From 8cc072a8a3bffcb8e9292cd39d1062493a1a0282 Mon Sep 17 00:00:00 2001
From: 朱桂飞 <18597012158>
Date: 星期二, 19 十二月 2023 13:03:09 +0800
Subject: [PATCH] 添加实时监控页面
---
package-lock.json | 5
pages/login/login.vue | 2
static/logo.png | 0
pages.json | 9
static/splash.png | 0
static/ezuikit.js | 35929 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
manifest.json | 42
pages/tabBar/general.vue | 2
package.json | 3
pages/me/control.vue | 102
pages/me/video.vue | 56
pages/tabBar/monitor.vue | 2
pages/tabBar/me.vue | 27
13 files changed, 36,141 insertions(+), 38 deletions(-)
diff --git a/manifest.json b/manifest.json
index 6a0ee6d..721eb2e 100644
--- a/manifest.json
+++ b/manifest.json
@@ -43,7 +43,47 @@
/* ios鎵撳寘閰嶇疆 */
"ios" : {},
/* SDK閰嶇疆 */
- "sdkConfigs" : {}
+ "sdkConfigs" : {},
+ "icons" : {
+ "android" : {
+ "hdpi" : "unpackage/res/icons/72x72.png",
+ "xhdpi" : "unpackage/res/icons/96x96.png",
+ "xxhdpi" : "unpackage/res/icons/144x144.png",
+ "xxxhdpi" : "unpackage/res/icons/192x192.png"
+ },
+ "ios" : {
+ "appstore" : "unpackage/res/icons/1024x1024.png",
+ "ipad" : {
+ "app" : "unpackage/res/icons/76x76.png",
+ "app@2x" : "unpackage/res/icons/152x152.png",
+ "notification" : "unpackage/res/icons/20x20.png",
+ "notification@2x" : "unpackage/res/icons/40x40.png",
+ "proapp@2x" : "unpackage/res/icons/167x167.png",
+ "settings" : "unpackage/res/icons/29x29.png",
+ "settings@2x" : "unpackage/res/icons/58x58.png",
+ "spotlight" : "unpackage/res/icons/40x40.png",
+ "spotlight@2x" : "unpackage/res/icons/80x80.png"
+ },
+ "iphone" : {
+ "app@2x" : "unpackage/res/icons/120x120.png",
+ "app@3x" : "unpackage/res/icons/180x180.png",
+ "notification@2x" : "unpackage/res/icons/40x40.png",
+ "notification@3x" : "unpackage/res/icons/60x60.png",
+ "settings@2x" : "unpackage/res/icons/58x58.png",
+ "settings@3x" : "unpackage/res/icons/87x87.png",
+ "spotlight@2x" : "unpackage/res/icons/80x80.png",
+ "spotlight@3x" : "unpackage/res/icons/120x120.png"
+ }
+ }
+ },
+ "splashscreen" : {
+ "androidStyle" : "default",
+ "android" : {
+ "hdpi" : "static/splash.png",
+ "xhdpi" : "static/splash.png",
+ "xxhdpi" : "static/splash.png"
+ }
+ }
}
},
/* 蹇簲鐢ㄧ壒鏈夌浉鍏� */
diff --git a/package-lock.json b/package-lock.json
index 0d961fc..a49bee1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4,6 +4,11 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+ "ezuikit-js": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/ezuikit-js/-/ezuikit-js-0.7.2.tgz",
+ "integrity": "sha512-BECy42q371eT4TekLon7YVmiU0u6UwbqEOjqzvbSKd0fVDwFqEaSST72EaiqWhgdfqS+xUg31pMgt1FY6GweRA=="
+ },
"lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
diff --git a/package.json b/package.json
index 216af2d..4f0f045 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
"author": "",
"license": "ISC",
"dependencies": {
- "lodash.get": "^4.4.2"
+ "lodash.get": "^4.4.2",
+ "ezuikit-js": "^0.7.2"
}
}
diff --git a/pages.json b/pages.json
index 33c277a..af418af 100644
--- a/pages.json
+++ b/pages.json
@@ -104,6 +104,15 @@
}
}
+ }, {
+ "path": "pages/me/video",
+ "style": {
+ "navigationStyle": "custom",
+ "app-plus": {
+ "titleNView": false
+ }
+ }
+
}
],
"globalStyle": {
diff --git a/pages/login/login.vue b/pages/login/login.vue
index af74294..438a26d 100644
--- a/pages/login/login.vue
+++ b/pages/login/login.vue
@@ -2,7 +2,7 @@
<template>
<view class="contaier">
<view class="top-bg">
- <view class="text-white text-bold text-xxxl">鏅鸿兘涓崏鑽共鐕ュ皬绋嬪簭绯荤粺</view>
+ <view class="text-white text-bold text-xxxl">鏅鸿兘涓崏鑽共鐕ヨ澶囬厤濂楃郴缁�</view>
<view class="margin-top-xs text-white">娆㈣繋浣跨敤锛岃鍏堢櫥褰�</view>
</view>
<u-form labelPosition="left" :model="model" ref="form">
diff --git a/pages/me/control.vue b/pages/me/control.vue
index 3e0a559..4abf342 100644
--- a/pages/me/control.vue
+++ b/pages/me/control.vue
@@ -40,11 +40,18 @@
return {
sendMsg: '',
recviceMsg: '',
- baseList: [{
+ baseList: [
+ /* {
+ id: 1010,
+ img: '',
+ title: '缁翠慨妯″紡',
+ name: 'warning'
+ }, */
+ {
id: 1010,
img: '',
- title: '缁翠慨妯″紡',
- name: 'warning'
+ title: '骞茬嚗鍚姩',
+ name: 'play-circle'
},
{
id: 0,
@@ -59,18 +66,12 @@
title: '鍋滄杩愯',
name: 'pause-circle'
},
- {
- id: 1001,
- img: '',
- title: '椋庣鍗�',
- name: 'arrow-up'
- },
- {
- id: 1003,
- img: '',
- title: '婊氱瓛鍗�',
- name: 'arrow-upward'
- },
+ // {
+ // id: 1001,
+ // img: '',
+ // title: '椋庣鍗�',
+ // name: 'arrow-up'
+ // },
{
id: 1005,
img: '',
@@ -78,25 +79,74 @@
name: 'checkmark-circle'
},
{
- id: 1002,
+ id: 1003,
img: '',
- title: '椋庣闄�',
- name: 'arrow-down'
+ title: '婊氱瓛鍗�',
+ name: 'arrow-upward'
+ },
+ {
+ id: 1011,
+ img: '',
+ title: '鍓嶉棬寮�鍏�',
+ name: 'plus-circle'
},
-
+
+ // {
+ // id: 1002,
+ // img: '',
+ // title: '椋庣闄�',
+ // name: 'arrow-down'
+ // },
+ {
+ id: 1006,
+ img: '',
+ title: '婊氱瓛鍙嶈浆',
+ name: 'close-circle'
+ },
+
{
id: 1004,
img: '',
title: '婊氱瓛闄�',
name: 'arrow-downward'
+ },
+ {
+ id: 1012,
+ img: '',
+ title: '鍚庨棬寮�鍏�',
+ name: 'minus-circle'
+ },
+ {
+ id: 1013,
+ img: '',
+ title: '鐑鍚姩',
+ name: 'coupon'
},
-
+
{
- id: 1006,
+ id: 1014,
img: '',
- title: '婊氱瓛鍙嶈浆',
- name: 'close-circle'
- },
+ title: '寮�闂ㄨ瀵�',
+ name: 'eye'
+ },
+ {
+ id: 1015,
+ img: '',
+ title: '鍑烘枡',
+ name: 'shopping-cart'
+ },{
+ id: 1016,
+ img: '',
+ title: '娓呴櫎',
+ name: 'trash'
+ },{
+ id: 1017,
+ img: '',
+ title: '鎵嬪姩/鑷姩',
+ name: 'fingerprint'
+ }
+
+
]
}
},
@@ -147,7 +197,7 @@
parmas.tenantId = 1003
parmas.machineId = 'GM001'
- this.sendMsg = '鍙戦�侊細' + this.formatData() + JSON.stringify(parmas)
+ this.sendMsg = '鍙戦�侊細' + this.formatData() + JSON.stringify(parmas)
this.recviceMsg = ''
console.info(parmas)
this.$api.sendCommand(parmas).then((res) => {
@@ -159,7 +209,7 @@
}
}).finally(() => {
-
+
})
},
formatData() {
diff --git a/pages/me/video.vue b/pages/me/video.vue
new file mode 100644
index 0000000..4e01719
--- /dev/null
+++ b/pages/me/video.vue
@@ -0,0 +1,56 @@
+<template>
+ <view>
+ <view id="video-container1" class="item-player">
+
+ </view>
+ </view>
+</template>
+
+<script>
+ import EZUIKit from "ezuikit-js";
+ export default {
+ data() {
+ return {
+
+ }
+ },
+ mounted() {
+ this.initPlayer1()
+
+ },
+ methods: {
+ initPlayer1() {
+ var width = document.documentElement.clientWidth;
+ var height = document.documentElement.clientWidth * 9 / 16;
+ const player1 = new EZUIKit.EZUIKitPlayer({
+ id: "video-container1", // 瑙嗛瀹瑰櫒ID
+ accessToken: 'at.3aw83ov4az77j8s87flvj2a36lctx64d-7awt1ntwzz-024wi8h-bpwhdobad',
+ url: 'ezopen://open.ys7.com/C24284281/1.hd.live',
+ template: 'mobileLive',
+ plugin: ["talk"], // 鍔犺浇鎻掍欢锛宼alk-瀵硅
+ width: width,
+ height: height,
+ handleSuccess: (res => {
+ console.info(res);
+ console.info("鍒濆鍖栨垚鍔�");
+ }),
+ handleError: (res => {
+ console.info(res);
+ if (res.retcode == "10002") {
+ console.info("鍒濆鍖栧け璐ワ紝token杩囨湡");
+ }
+ })
+ });
+ setTimeout(() => {
+ console.info("寮�濮嬭嚜鍔ㄦ挱鏀�1鍙�")
+ player1.play();
+ }, 1000);
+ }
+
+ }
+ }
+</script>
+
+<style>
+
+</style>
\ No newline at end of file
diff --git a/pages/tabBar/general.vue b/pages/tabBar/general.vue
index 6d46b9a..7600ad3 100644
--- a/pages/tabBar/general.vue
+++ b/pages/tabBar/general.vue
@@ -12,7 +12,7 @@
-->
<cu-custom bgColor="bg-gradual-blue" :isBack="false">
- <block slot="content">鏅鸿兘涓崏鑽共鐕ュ皬绋嬪簭绯荤粺</block>
+ <block slot="content">鏅鸿兘涓崏鑽共鐕ヨ澶囬厤濂楃郴缁�</block>
</cu-custom>
<u-toast ref="uToast"></u-toast>
<!-- <view class="card-box dynamic shadow cu-list menu">
diff --git a/pages/tabBar/me.vue b/pages/tabBar/me.vue
index 4c53316..239af44 100644
--- a/pages/tabBar/me.vue
+++ b/pages/tabBar/me.vue
@@ -119,10 +119,17 @@
</button>
</view>
<view class="cu-item">
- <button class='content cu-btn' @click="itemClick">
- <image src='../../static/me/icon/diannao.png' class='png' mode='aspectFit'></image>
- <text class='text-lg margin-sm'>杩滅▼鎺у埗</text>
+ <button class='content cu-btn' @click="itemClick('video')">
+ <image src='../../static/me/icon/jiankong.png' class='png' mode='aspectFit'></image>
+ <text class='text-lg margin-sm'>瀹炴椂鐩戞帶</text>
</button>
+ </view>
+
+ <view class="cu-item">
+ <button class='content cu-btn' @click="itemClick('control')">
+ <image src='../../static/me/icon/diannao.png' class='png' mode='aspectFit'></image>
+ <text class='text-lg margin-sm'>杩滅▼鎺у埗</text>
+ </button>
</view>
@@ -206,10 +213,16 @@
mounted() {
},
methods: {
- itemClick(){
- uni.navigateTo({
- url:"/pages/me/control"
- })
+ itemClick(mode){
+ if(mode == 'control'){
+ uni.navigateTo({
+ url:"/pages/me/control"
+ })
+ }else if(mode == 'video'){
+ uni.navigateTo({
+ url:"/pages/me/video"
+ })
+ }
},
exit() {
this.show = true
diff --git a/pages/tabBar/monitor.vue b/pages/tabBar/monitor.vue
index fa6b4fd..fbc86f7 100644
--- a/pages/tabBar/monitor.vue
+++ b/pages/tabBar/monitor.vue
@@ -404,7 +404,7 @@
model: {},
queryParam: {
machineid: "GM001",
- tenantid: 1000
+ tenantid: 1003
},
bannerList: [{
imageUrl: '../../static/image/zcy_gzj1.png'
diff --git a/static/ezuikit.js b/static/ezuikit.js
new file mode 100644
index 0000000..3e2b871
--- /dev/null
+++ b/static/ezuikit.js
@@ -0,0 +1,35929 @@
+'use strict';
+
+function _typeof(obj) {
+ "@babel/helpers - typeof";
+
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
+ return typeof obj;
+ } : function (obj) {
+ return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
+ }, _typeof(obj);
+}
+
+function _classCallCheck$1(instance, Constructor) {
+ if (!(instance instanceof Constructor)) {
+ throw new TypeError("Cannot call a class as a 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);
+ }
+}
+
+function _createClass$1(Constructor, protoProps, staticProps) {
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
+ if (staticProps) _defineProperties(Constructor, staticProps);
+ Object.defineProperty(Constructor, "prototype", {
+ writable: false
+ });
+ return Constructor;
+}
+
+function _defineProperty(obj, key, value) {
+ if (key in obj) {
+ Object.defineProperty(obj, key, {
+ value: value,
+ enumerable: true,
+ configurable: true,
+ writable: true
+ });
+ } else {
+ obj[key] = value;
+ }
+
+ return obj;
+}
+
+var Core = /*#__PURE__*/function () {
+ function Core(x, y) {
+ _classCallCheck$1(this, Core);
+
+ this.coreX = x;
+ this.coreY = y;
+ }
+
+ _createClass$1(Core, [{
+ key: "toString",
+ value: function toString() {
+ return "".concat(this.coreX, "-").concat(this.coreY);
+ }
+ }]);
+
+ return Core;
+}();
+
+// eslint-disable-next-line no-extend-native
+Date.prototype.Format = function (fmt) {
+ var o = {
+ "M+": this.getMonth() + 1,
+ "d+": this.getDate(),
+ "h+": this.getHours(),
+ "m+": this.getMinutes(),
+ "s+": this.getSeconds(),
+ "q+": Math.floor((this.getMonth() + 3) / 3),
+ "S": this.getMilliseconds()
+ };
+
+ if (/(y+)/.test(fmt)) {
+ fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
+ }
+
+ for (var k in o) {
+ if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
+ }
+
+ return fmt;
+}; // 鍔犺浇js
+
+
+var addJs = function addJs(filepath, callback, isReadyFun) {
+ var headerScript = document.getElementsByTagName('head')[0].getElementsByTagName("script");
+ var isReady = false;
+
+ if (isReadyFun) {
+ isReady = isReadyFun();
+ } else {
+ for (var i = 0; i < headerScript.length; i++) {
+ if (headerScript[i].getAttribute("src") == filepath) {
+ isReady = true;
+ callback();
+ }
+ }
+ }
+
+ if (!isReady) {
+ var oJs = document.createElement("script");
+ oJs.setAttribute("src", filepath);
+ oJs.setAttribute("crossorigin", true);
+ oJs.onload = callback;
+ document.getElementsByTagName("head")[0].appendChild(oJs);
+ } else {
+ callback();
+ }
+};
+var addCss = function addCss(filepath, callback) {
+ var headerLink = document.getElementsByTagName('head')[0].getElementsByTagName("link");
+ var isReady = false;
+
+ for (var i = 0; i < headerLink.length; i++) {
+ if (headerLink[i].getAttribute("href") == filepath) {
+ isReady = true;
+ }
+ }
+
+ if (!isReady) {
+ var oJs = document.createElement('link');
+ oJs.rel = 'stylesheet';
+ oJs.type = 'text/css';
+ oJs.href = filepath;
+ oJs.onload = callback;
+ document.getElementsByTagName("head")[0].appendChild(oJs);
+ }
+};
+var isPromise = function isPromise(obj) {
+ return !!obj && (_typeof(obj) === 'object' || typeof obj === 'function') && typeof obj.then === 'function';
+};
+var getQueryString = function getQueryString(name, url) {
+ var r = new RegExp("(\\?|#|&)" + name + "=(.*?)(#|&|$)");
+ var m = (url || window.location.href).match(r);
+ return decodeURIComponent(m ? m[2] : '');
+};
+var insertAfter$1 = function insertAfter(newElement, targetElement) {
+ var parent = targetElement.parentNode;
+
+ if (parent.lastChild == targetElement) {
+ parent.appendChild(newElement);
+ } else {
+ parent.insertBefore(newElement, targetElement.nextSibling);
+ }
+};
+var requestFullScreen = function requestFullScreen(element) {
+ console.log("requestFullScreen", document.getElementById(element));
+ var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullScreen;
+
+ if (requestMethod) {
+ requestMethod.call(element);
+ } else if (typeof window.ActiveXObject !== "undefined") {
+ var wscript = new window.ActiveXObject("WScript.Shell");
+
+ if (wscript !== null) {
+ wscript.SendKeys("{F11}");
+ }
+ }
+};
+var requestMobileFullScreen = function requestMobileFullScreen(element) {
+ var width = document.documentElement.clientWidth;
+ var height = document.documentElement.clientHeight;
+ var wrapper = element;
+ var style = "";
+ style += "width:" + height + "px;"; // 娉ㄦ剰鏃嬭浆鍚庣殑瀹介珮鍒囨崲
+
+ style += "height:" + width + "px;";
+ style += "-webkit-transform: rotate(90.001deg); transform: rotate(90.001deg);"; // 娉ㄦ剰鏃嬭浆涓偣鐨勫鐞�
+
+ style += "-webkit-transform-origin: " + width / 2 + "px " + width / 2 + "px;";
+ style += "transform-origin: " + width / 2 + "px " + width / 2 + "px;";
+ style += 'position: fixed;top: 0;left: 0;z-index:10';
+ wrapper.style.cssText = style;
+};
+var requestFullScreenPromise = function requestFullScreenPromise(element) {
+ requestFullScreen(element);
+ var promise = new Promise(function (resolve, reject) {
+ var timeInterval = setInterval(function () {
+ var isFullScreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
+
+ if (isFullScreen) {
+ clearInterval(timeInterval);
+ return resolve(true);
+ }
+ }, 100);
+ var timeOut = setTimeout(function () {
+ var isFullScreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
+
+ if (!isFullScreen) {
+ reject(false);
+ }
+
+ clearTimeout(timeOut);
+ }, 2000);
+ });
+ return promise;
+};
+var cancelMobileFullScreen = function cancelMobileFullScreen(element, width, height) {
+ var style = "";
+ style += "width:" + width + "px;";
+ style += "height:" + height + "px;";
+ style += "-webkit-transform: none; transform: none;";
+ style += "-webkit-transform-origin: 0 0;";
+ style += "transform-origin: 0 0;";
+ element.style.cssText = style;
+};
+var cancelFullScreen = function cancelFullScreen() {
+ if (document.exitFullscreen) {
+ document.exitFullscreen();
+ } else if (document.webkitCancelFullScreen) {
+ document.webkitCancelFullScreen();
+ } else if (document.mozCancelFullScreen) {
+ document.mozCancelFullScreen();
+ }
+};
+var cancelFullScreenPromise = function cancelFullScreenPromise(element) {
+ cancelFullScreen();
+ var promise = new Promise(function (resolve, reject) {
+ var timeInterval = setInterval(function () {
+ var isFullScreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
+
+ if (!isFullScreen) {
+ clearInterval(timeInterval);
+ return resolve(true);
+ }
+ }, 50);
+ var timeOut = setTimeout(function () {
+ var isFullScreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
+
+ if (isFullScreen) {
+ reject(false);
+ }
+
+ clearTimeout(timeOut);
+ }, 2000);
+ });
+ return promise;
+};
+var matchEzopenUrl = function matchEzopenUrl(ezopenUrl) {
+ var deviceSerial = ezopenUrl.split("/")[3];
+ var channelNo = ezopenUrl.split("/")[4].split(".")[0];
+ var validCode = ezopenUrl.split("/")[2].split("@").length === 2 ? ezopenUrl.split("/")[2].split("@")[0] : "";
+ var hd = ezopenUrl.indexOf('.hd') !== -1;
+ var type = ezopenUrl.split("/")[4].split(".")[ezopenUrl.split("/")[4].split(".").length - 1].split("?")[0];
+
+ if (type === 'rec' && ezopenUrl.indexOf(".cloud.rec") !== -1) {
+ type = 'cloud.rec';
+ }
+
+ return {
+ deviceSerial: deviceSerial,
+ channelNo: channelNo,
+ validCode: validCode,
+ hd: hd,
+ type: type
+ };
+};
+
+function isJSON(str) {
+ if (typeof str === 'string') {
+ try {
+ var obj = JSON.parse(str);
+
+ if (_typeof(obj) === 'object' && obj) {
+ return true;
+ }
+
+ return false;
+ } catch (e) {
+ return false;
+ }
+ }
+
+ console.log('It is not a string!');
+}
+
+var request = function request(url, method, params, header, success, error) {
+ var _url = url;
+ var http_request = new XMLHttpRequest();
+
+ http_request.onreadystatechange = function () {
+ if (http_request.readyState == 4) {
+ if (http_request.status == 200) {
+ if (isJSON(http_request.responseText)) {
+ var _data = JSON.parse(http_request.responseText);
+
+ success(_data);
+ } else {
+ success(http_request.responseText);
+ }
+ }
+ }
+ };
+
+ http_request.open(method, _url, true); // http_request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
+
+ var data = new FormData();
+
+ for (var i in params) {
+ data.append(i, params[i]);
+ }
+
+ http_request.send(data);
+};
+
+var HLS = /*#__PURE__*/function () {
+ function HLS(videoId, url) {
+ var _this = this;
+
+ _classCallCheck$1(this, HLS);
+
+ addJs("https://open.ys7.com/assets/ezuikit_v3.4/js/hls.js", function () {
+ console.log("鍔犺浇hls.min.js鎴愬姛", window.Hls);
+ console.log("isSupportHls", window.Hls.isSupported());
+
+ if (window.Hls.isSupported()) {
+ _this.initHLS(videoId, url);
+ }
+ }, function () {
+ return !!window.Hls;
+ });
+ }
+
+ _createClass$1(HLS, [{
+ key: "toString",
+ value: function toString() {
+ return "hls ".concat(this.coreX, "-").concat(this.coreY);
+ }
+ }, {
+ key: "initHLS",
+ value: function initHLS(videoId, hlsUrl) {
+ var video = document.getElementById(videoId);
+ var hls = new window.Hls({
+ defaultAudioCodec: 'mp4a.40.2'
+ }); // 钀ょ煶璁惧榛樿浣跨敤 AAC LC 闊抽缂栫爜
+
+ hls.loadSource(hlsUrl);
+ hls.attachMedia(video);
+ hls.on(window.Hls.Events.MANIFEST_PARSED, function () {
+ video.play();
+ });
+ hls.on(window.Hls.Events.ERROR, function (event, data) {
+ if (data.fatal) {
+ switch (data.type) {
+ case window.Hls.ErrorTypes.NETWORK_ERROR:
+ // try to recover network error
+ console.log("fatal network error encountered, try to recover");
+ hls.startLoad();
+ break;
+
+ case window.Hls.ErrorTypes.MEDIA_ERROR:
+ console.log("fatal media error encountered, try to recover");
+ hls.recoverMediaError();
+ break;
+
+ default:
+ // cannot recover
+ hls.destroy();
+ break;
+ }
+ }
+ });
+ this.hls = hls;
+ this.video = video;
+ this.hlsUrl = hlsUrl;
+ }
+ }, {
+ key: "play",
+ value: function play() {
+ console.log("鎵цhls鎾斁", this.video);
+ this.hls.startLoad(); // this.video.src = this.hlsUrl;
+
+ this.video.play();
+ }
+ }, {
+ key: "stop",
+ value: function stop() {
+ // 閫氳繃鏆傚仠鍋滄鎾斁
+ // this.video.pause();
+ // this.video.src = "";
+ this.video.pause(); // 鍋滄鍙栨祦
+
+ this.hls.stopLoad(); // this.hls.destroy();
+ }
+ }]);
+
+ return HLS;
+}();
+
+var FLV = /*#__PURE__*/function () {
+ function FLV(videoId, url) {
+ var _this = this;
+
+ _classCallCheck$1(this, FLV);
+
+ addJs("https://open.ys7.com/sdk/js/2.0/js/flv.min.js", function () {
+ console.log("鍔犺浇flv.min.js鎴愬姛", window.flvjs);
+ console.log("isSupportFlv", window.flvjs.isSupported());
+
+ if (window.flvjs.isSupported()) {
+ _this.initFLV(videoId, url);
+ }
+ });
+ }
+
+ _createClass$1(FLV, [{
+ key: "toString",
+ value: function toString() {
+ return "Flv ".concat(this.coreX, "-").concat(this.coreY);
+ }
+ }, {
+ key: "initFLV",
+ value: function initFLV(videoId, flvUrl) {
+ var video = document.getElementById(videoId);
+ var hasControls = video.getAttribute('controls');
+
+ if (!hasControls) {
+ video.setAttribute('controls', true);
+ }
+
+ var flvPlayer = window.flvjs.createPlayer({
+ type: 'flv',
+ url: flvUrl,
+ isLive: true
+ }, {
+ enableStashBuffer: true,
+ stashInitialSize: 128,
+ enableWorker: true
+ });
+ flvPlayer.attachMediaElement(video);
+ flvPlayer.load();
+ flvPlayer.play();
+ this.flvUrl = flvUrl;
+ this.flv = flvPlayer;
+ this.video = video;
+ }
+ }, {
+ key: "play",
+ value: function play() {
+ console.log("鎵цflv鎾斁", this.video);
+ this.video.play();
+ }
+ }, {
+ key: "stop",
+ value: function stop() {
+ // 閫氳繃鏆傚仠鍋滄鎾斁
+ // this.video.pause();
+ // this.video.src = "";
+ this.video.pause(); // 鍋滄鍙栨祦
+
+ this.flv.unload(); // this.hls.destroy();
+ }
+ }]);
+
+ return FLV;
+}();
+
+var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
+
+function createCommonjsModule(fn, module) {
+ return module = { exports: {} }, fn(module, module.exports), module.exports;
+}
+
+var lodash = createCommonjsModule(function (module, exports) {
+(function(){/** Used as a safe reference for `undefined` in pre-ES5 environments. */var undefined$1;/** Used as the semantic version number. */var VERSION='4.17.21';/** Used as the size to enable large array optimizations. */var LARGE_ARRAY_SIZE=200;/** Error message constants. */var CORE_ERROR_TEXT='Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',FUNC_ERROR_TEXT='Expected a function',INVALID_TEMPL_VAR_ERROR_TEXT='Invalid `variable` option passed into `_.template`';/** Used to stand-in for `undefined` hash values. */var HASH_UNDEFINED='__lodash_hash_undefined__';/** Used as the maximum memoize cache size. */var MAX_MEMOIZE_SIZE=500;/** Used as the internal argument placeholder. */var PLACEHOLDER='__lodash_placeholder__';/** Used to compose bitmasks for cloning. */var CLONE_DEEP_FLAG=1,CLONE_FLAT_FLAG=2,CLONE_SYMBOLS_FLAG=4;/** Used to compose bitmasks for value comparisons. */var COMPARE_PARTIAL_FLAG=1,COMPARE_UNORDERED_FLAG=2;/** Used to compose bitmasks for function metadata. */var WRAP_BIND_FLAG=1,WRAP_BIND_KEY_FLAG=2,WRAP_CURRY_BOUND_FLAG=4,WRAP_CURRY_FLAG=8,WRAP_CURRY_RIGHT_FLAG=16,WRAP_PARTIAL_FLAG=32,WRAP_PARTIAL_RIGHT_FLAG=64,WRAP_ARY_FLAG=128,WRAP_REARG_FLAG=256,WRAP_FLIP_FLAG=512;/** Used as default options for `_.truncate`. */var DEFAULT_TRUNC_LENGTH=30,DEFAULT_TRUNC_OMISSION='...';/** Used to detect hot functions by number of calls within a span of milliseconds. */var HOT_COUNT=800,HOT_SPAN=16;/** Used to indicate the type of lazy iteratees. */var LAZY_FILTER_FLAG=1,LAZY_MAP_FLAG=2,LAZY_WHILE_FLAG=3;/** Used as references for various `Number` constants. */var INFINITY=1/0,MAX_SAFE_INTEGER=9007199254740991,MAX_INTEGER=1.7976931348623157e+308,NAN=0/0;/** Used as references for the maximum length and index of an array. */var MAX_ARRAY_LENGTH=4294967295,MAX_ARRAY_INDEX=MAX_ARRAY_LENGTH-1,HALF_MAX_ARRAY_LENGTH=MAX_ARRAY_LENGTH>>>1;/** Used to associate wrap methods with their bit flags. */var wrapFlags=[['ary',WRAP_ARY_FLAG],['bind',WRAP_BIND_FLAG],['bindKey',WRAP_BIND_KEY_FLAG],['curry',WRAP_CURRY_FLAG],['curryRight',WRAP_CURRY_RIGHT_FLAG],['flip',WRAP_FLIP_FLAG],['partial',WRAP_PARTIAL_FLAG],['partialRight',WRAP_PARTIAL_RIGHT_FLAG],['rearg',WRAP_REARG_FLAG]];/** `Object#toString` result references. */var argsTag='[object Arguments]',arrayTag='[object Array]',asyncTag='[object AsyncFunction]',boolTag='[object Boolean]',dateTag='[object Date]',domExcTag='[object DOMException]',errorTag='[object Error]',funcTag='[object Function]',genTag='[object GeneratorFunction]',mapTag='[object Map]',numberTag='[object Number]',nullTag='[object Null]',objectTag='[object Object]',promiseTag='[object Promise]',proxyTag='[object Proxy]',regexpTag='[object RegExp]',setTag='[object Set]',stringTag='[object String]',symbolTag='[object Symbol]',undefinedTag='[object Undefined]',weakMapTag='[object WeakMap]',weakSetTag='[object WeakSet]';var arrayBufferTag='[object ArrayBuffer]',dataViewTag='[object DataView]',float32Tag='[object Float32Array]',float64Tag='[object Float64Array]',int8Tag='[object Int8Array]',int16Tag='[object Int16Array]',int32Tag='[object Int32Array]',uint8Tag='[object Uint8Array]',uint8ClampedTag='[object Uint8ClampedArray]',uint16Tag='[object Uint16Array]',uint32Tag='[object Uint32Array]';/** Used to match empty string literals in compiled template source. */var reEmptyStringLeading=/\b__p \+= '';/g,reEmptyStringMiddle=/\b(__p \+=) '' \+/g,reEmptyStringTrailing=/(__e\(.*?\)|\b__t\)) \+\n'';/g;/** Used to match HTML entities and HTML characters. */var reEscapedHtml=/&(?:amp|lt|gt|quot|#39);/g,reUnescapedHtml=/[&<>"']/g,reHasEscapedHtml=RegExp(reEscapedHtml.source),reHasUnescapedHtml=RegExp(reUnescapedHtml.source);/** Used to match template delimiters. */var reEscape=/<%-([\s\S]+?)%>/g,reEvaluate=/<%([\s\S]+?)%>/g,reInterpolate=/<%=([\s\S]+?)%>/g;/** Used to match property names within property paths. */var reIsDeepProp=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,reIsPlainProp=/^\w*$/,rePropName=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;/**
+ * Used to match `RegExp`
+ * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
+ */var reRegExpChar=/[\\^$.*+?()[\]{}|]/g,reHasRegExpChar=RegExp(reRegExpChar.source);/** Used to match leading whitespace. */var reTrimStart=/^\s+/;/** Used to match a single whitespace character. */var reWhitespace=/\s/;/** Used to match wrap detail comments. */var reWrapComment=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,reWrapDetails=/\{\n\/\* \[wrapped with (.+)\] \*/,reSplitDetails=/,? & /;/** Used to match words composed of alphanumeric characters. */var reAsciiWord=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;/**
+ * Used to validate the `validate` option in `_.template` variable.
+ *
+ * Forbids characters which could potentially change the meaning of the function argument definition:
+ * - "()," (modification of function parameters)
+ * - "=" (default value)
+ * - "[]{}" (destructuring of function parameters)
+ * - "/" (beginning of a comment)
+ * - whitespace
+ */var reForbiddenIdentifierChars=/[()=,{}\[\]\/\s]/;/** Used to match backslashes in property paths. */var reEscapeChar=/\\(\\)?/g;/**
+ * Used to match
+ * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
+ */var reEsTemplate=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;/** Used to match `RegExp` flags from their coerced string values. */var reFlags=/\w*$/;/** Used to detect bad signed hexadecimal string values. */var reIsBadHex=/^[-+]0x[0-9a-f]+$/i;/** Used to detect binary string values. */var reIsBinary=/^0b[01]+$/i;/** Used to detect host constructors (Safari). */var reIsHostCtor=/^\[object .+?Constructor\]$/;/** Used to detect octal string values. */var reIsOctal=/^0o[0-7]+$/i;/** Used to detect unsigned integer values. */var reIsUint=/^(?:0|[1-9]\d*)$/;/** Used to match Latin Unicode letters (excluding mathematical operators). */var reLatin=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;/** Used to ensure capturing order of template delimiters. */var reNoMatch=/($^)/;/** Used to match unescaped characters in compiled string literals. */var reUnescapedString=/['\n\r\u2028\u2029\\]/g;/** Used to compose unicode character classes. */var rsAstralRange='\\ud800-\\udfff',rsComboMarksRange='\\u0300-\\u036f',reComboHalfMarksRange='\\ufe20-\\ufe2f',rsComboSymbolsRange='\\u20d0-\\u20ff',rsComboRange=rsComboMarksRange+reComboHalfMarksRange+rsComboSymbolsRange,rsDingbatRange='\\u2700-\\u27bf',rsLowerRange='a-z\\xdf-\\xf6\\xf8-\\xff',rsMathOpRange='\\xac\\xb1\\xd7\\xf7',rsNonCharRange='\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',rsPunctuationRange='\\u2000-\\u206f',rsSpaceRange=' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',rsUpperRange='A-Z\\xc0-\\xd6\\xd8-\\xde',rsVarRange='\\ufe0e\\ufe0f',rsBreakRange=rsMathOpRange+rsNonCharRange+rsPunctuationRange+rsSpaceRange;/** Used to compose unicode capture groups. */var rsApos="['\u2019]",rsAstral='['+rsAstralRange+']',rsBreak='['+rsBreakRange+']',rsCombo='['+rsComboRange+']',rsDigits='\\d+',rsDingbat='['+rsDingbatRange+']',rsLower='['+rsLowerRange+']',rsMisc='[^'+rsAstralRange+rsBreakRange+rsDigits+rsDingbatRange+rsLowerRange+rsUpperRange+']',rsFitz='\\ud83c[\\udffb-\\udfff]',rsModifier='(?:'+rsCombo+'|'+rsFitz+')',rsNonAstral='[^'+rsAstralRange+']',rsRegional='(?:\\ud83c[\\udde6-\\uddff]){2}',rsSurrPair='[\\ud800-\\udbff][\\udc00-\\udfff]',rsUpper='['+rsUpperRange+']',rsZWJ='\\u200d';/** Used to compose unicode regexes. */var rsMiscLower='(?:'+rsLower+'|'+rsMisc+')',rsMiscUpper='(?:'+rsUpper+'|'+rsMisc+')',rsOptContrLower='(?:'+rsApos+'(?:d|ll|m|re|s|t|ve))?',rsOptContrUpper='(?:'+rsApos+'(?:D|LL|M|RE|S|T|VE))?',reOptMod=rsModifier+'?',rsOptVar='['+rsVarRange+']?',rsOptJoin='(?:'+rsZWJ+'(?:'+[rsNonAstral,rsRegional,rsSurrPair].join('|')+')'+rsOptVar+reOptMod+')*',rsOrdLower='\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])',rsOrdUpper='\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])',rsSeq=rsOptVar+reOptMod+rsOptJoin,rsEmoji='(?:'+[rsDingbat,rsRegional,rsSurrPair].join('|')+')'+rsSeq,rsSymbol='(?:'+[rsNonAstral+rsCombo+'?',rsCombo,rsRegional,rsSurrPair,rsAstral].join('|')+')';/** Used to match apostrophes. */var reApos=RegExp(rsApos,'g');/**
+ * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
+ * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
+ */var reComboMark=RegExp(rsCombo,'g');/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */var reUnicode=RegExp(rsFitz+'(?='+rsFitz+')|'+rsSymbol+rsSeq,'g');/** Used to match complex or compound words. */var reUnicodeWord=RegExp([rsUpper+'?'+rsLower+'+'+rsOptContrLower+'(?='+[rsBreak,rsUpper,'$'].join('|')+')',rsMiscUpper+'+'+rsOptContrUpper+'(?='+[rsBreak,rsUpper+rsMiscLower,'$'].join('|')+')',rsUpper+'?'+rsMiscLower+'+'+rsOptContrLower,rsUpper+'+'+rsOptContrUpper,rsOrdUpper,rsOrdLower,rsDigits,rsEmoji].join('|'),'g');/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */var reHasUnicode=RegExp('['+rsZWJ+rsAstralRange+rsComboRange+rsVarRange+']');/** Used to detect strings that need a more robust regexp to match words. */var reHasUnicodeWord=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;/** Used to assign default `context` object properties. */var contextProps=['Array','Buffer','DataView','Date','Error','Float32Array','Float64Array','Function','Int8Array','Int16Array','Int32Array','Map','Math','Object','Promise','RegExp','Set','String','Symbol','TypeError','Uint8Array','Uint8ClampedArray','Uint16Array','Uint32Array','WeakMap','_','clearTimeout','isFinite','parseInt','setTimeout'];/** Used to make template sourceURLs easier to identify. */var templateCounter=-1;/** Used to identify `toStringTag` values of typed arrays. */var typedArrayTags={};typedArrayTags[float32Tag]=typedArrayTags[float64Tag]=typedArrayTags[int8Tag]=typedArrayTags[int16Tag]=typedArrayTags[int32Tag]=typedArrayTags[uint8Tag]=typedArrayTags[uint8ClampedTag]=typedArrayTags[uint16Tag]=typedArrayTags[uint32Tag]=true;typedArrayTags[argsTag]=typedArrayTags[arrayTag]=typedArrayTags[arrayBufferTag]=typedArrayTags[boolTag]=typedArrayTags[dataViewTag]=typedArrayTags[dateTag]=typedArrayTags[errorTag]=typedArrayTags[funcTag]=typedArrayTags[mapTag]=typedArrayTags[numberTag]=typedArrayTags[objectTag]=typedArrayTags[regexpTag]=typedArrayTags[setTag]=typedArrayTags[stringTag]=typedArrayTags[weakMapTag]=false;/** Used to identify `toStringTag` values supported by `_.clone`. */var cloneableTags={};cloneableTags[argsTag]=cloneableTags[arrayTag]=cloneableTags[arrayBufferTag]=cloneableTags[dataViewTag]=cloneableTags[boolTag]=cloneableTags[dateTag]=cloneableTags[float32Tag]=cloneableTags[float64Tag]=cloneableTags[int8Tag]=cloneableTags[int16Tag]=cloneableTags[int32Tag]=cloneableTags[mapTag]=cloneableTags[numberTag]=cloneableTags[objectTag]=cloneableTags[regexpTag]=cloneableTags[setTag]=cloneableTags[stringTag]=cloneableTags[symbolTag]=cloneableTags[uint8Tag]=cloneableTags[uint8ClampedTag]=cloneableTags[uint16Tag]=cloneableTags[uint32Tag]=true;cloneableTags[errorTag]=cloneableTags[funcTag]=cloneableTags[weakMapTag]=false;/** Used to map Latin Unicode letters to basic Latin letters. */var deburredLetters={// Latin-1 Supplement block.
+'\xc0':'A','\xc1':'A','\xc2':'A','\xc3':'A','\xc4':'A','\xc5':'A','\xe0':'a','\xe1':'a','\xe2':'a','\xe3':'a','\xe4':'a','\xe5':'a','\xc7':'C','\xe7':'c','\xd0':'D','\xf0':'d','\xc8':'E','\xc9':'E','\xca':'E','\xcb':'E','\xe8':'e','\xe9':'e','\xea':'e','\xeb':'e','\xcc':'I','\xcd':'I','\xce':'I','\xcf':'I','\xec':'i','\xed':'i','\xee':'i','\xef':'i','\xd1':'N','\xf1':'n','\xd2':'O','\xd3':'O','\xd4':'O','\xd5':'O','\xd6':'O','\xd8':'O','\xf2':'o','\xf3':'o','\xf4':'o','\xf5':'o','\xf6':'o','\xf8':'o','\xd9':'U','\xda':'U','\xdb':'U','\xdc':'U','\xf9':'u','\xfa':'u','\xfb':'u','\xfc':'u','\xdd':'Y','\xfd':'y','\xff':'y','\xc6':'Ae','\xe6':'ae','\xde':'Th','\xfe':'th','\xdf':'ss',// Latin Extended-A block.
+'\u0100':'A','\u0102':'A','\u0104':'A','\u0101':'a','\u0103':'a','\u0105':'a','\u0106':'C','\u0108':'C','\u010a':'C','\u010c':'C','\u0107':'c','\u0109':'c','\u010b':'c','\u010d':'c','\u010e':'D','\u0110':'D','\u010f':'d','\u0111':'d','\u0112':'E','\u0114':'E','\u0116':'E','\u0118':'E','\u011a':'E','\u0113':'e','\u0115':'e','\u0117':'e','\u0119':'e','\u011b':'e','\u011c':'G','\u011e':'G','\u0120':'G','\u0122':'G','\u011d':'g','\u011f':'g','\u0121':'g','\u0123':'g','\u0124':'H','\u0126':'H','\u0125':'h','\u0127':'h','\u0128':'I','\u012a':'I','\u012c':'I','\u012e':'I','\u0130':'I','\u0129':'i','\u012b':'i','\u012d':'i','\u012f':'i','\u0131':'i','\u0134':'J','\u0135':'j','\u0136':'K','\u0137':'k','\u0138':'k','\u0139':'L','\u013b':'L','\u013d':'L','\u013f':'L','\u0141':'L','\u013a':'l','\u013c':'l','\u013e':'l','\u0140':'l','\u0142':'l','\u0143':'N','\u0145':'N','\u0147':'N','\u014a':'N','\u0144':'n','\u0146':'n','\u0148':'n','\u014b':'n','\u014c':'O','\u014e':'O','\u0150':'O','\u014d':'o','\u014f':'o','\u0151':'o','\u0154':'R','\u0156':'R','\u0158':'R','\u0155':'r','\u0157':'r','\u0159':'r','\u015a':'S','\u015c':'S','\u015e':'S','\u0160':'S','\u015b':'s','\u015d':'s','\u015f':'s','\u0161':'s','\u0162':'T','\u0164':'T','\u0166':'T','\u0163':'t','\u0165':'t','\u0167':'t','\u0168':'U','\u016a':'U','\u016c':'U','\u016e':'U','\u0170':'U','\u0172':'U','\u0169':'u','\u016b':'u','\u016d':'u','\u016f':'u','\u0171':'u','\u0173':'u','\u0174':'W','\u0175':'w','\u0176':'Y','\u0177':'y','\u0178':'Y','\u0179':'Z','\u017b':'Z','\u017d':'Z','\u017a':'z','\u017c':'z','\u017e':'z','\u0132':'IJ','\u0133':'ij','\u0152':'Oe','\u0153':'oe','\u0149':"'n",'\u017f':'s'};/** Used to map characters to HTML entities. */var htmlEscapes={'&':'&','<':'<','>':'>','"':'"',"'":'''};/** Used to map HTML entities to characters. */var htmlUnescapes={'&':'&','<':'<','>':'>','"':'"',''':"'"};/** Used to escape characters for inclusion in compiled string literals. */var stringEscapes={'\\':'\\',"'":"'",'\n':'n','\r':'r','\u2028':'u2028','\u2029':'u2029'};/** Built-in method references without a dependency on `root`. */var freeParseFloat=parseFloat,freeParseInt=parseInt;/** Detect free variable `global` from Node.js. */var freeGlobal=typeof commonjsGlobal=='object'&&commonjsGlobal&&commonjsGlobal.Object===Object&&commonjsGlobal;/** Detect free variable `self`. */var freeSelf=typeof self=='object'&&self&&self.Object===Object&&self;/** Used as a reference to the global object. */var root=freeGlobal||freeSelf||Function('return this')();/** Detect free variable `exports`. */var freeExports=exports&&!exports.nodeType&&exports;/** Detect free variable `module`. */var freeModule=freeExports&&'object'=='object'&&module&&!module.nodeType&&module;/** Detect the popular CommonJS extension `module.exports`. */var moduleExports=freeModule&&freeModule.exports===freeExports;/** Detect free variable `process` from Node.js. */var freeProcess=moduleExports&&freeGlobal.process;/** Used to access faster Node.js helpers. */var nodeUtil=function(){try{// Use `util.types` for Node.js 10+.
+var types=freeModule&&freeModule.require&&freeModule.require('util').types;if(types){return types;}// Legacy `process.binding('util')` for Node.js < 10.
+return freeProcess&&freeProcess.binding&&freeProcess.binding('util');}catch(e){}}();/* Node.js helper references. */var nodeIsArrayBuffer=nodeUtil&&nodeUtil.isArrayBuffer,nodeIsDate=nodeUtil&&nodeUtil.isDate,nodeIsMap=nodeUtil&&nodeUtil.isMap,nodeIsRegExp=nodeUtil&&nodeUtil.isRegExp,nodeIsSet=nodeUtil&&nodeUtil.isSet,nodeIsTypedArray=nodeUtil&&nodeUtil.isTypedArray;/*--------------------------------------------------------------------------*/ /**
+ * A faster alternative to `Function#apply`, this function invokes `func`
+ * with the `this` binding of `thisArg` and the arguments of `args`.
+ *
+ * @private
+ * @param {Function} func The function to invoke.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {Array} args The arguments to invoke `func` with.
+ * @returns {*} Returns the result of `func`.
+ */function apply(func,thisArg,args){switch(args.length){case 0:return func.call(thisArg);case 1:return func.call(thisArg,args[0]);case 2:return func.call(thisArg,args[0],args[1]);case 3:return func.call(thisArg,args[0],args[1],args[2]);}return func.apply(thisArg,args);}/**
+ * A specialized version of `baseAggregator` for arrays.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} setter The function to set `accumulator` values.
+ * @param {Function} iteratee The iteratee to transform keys.
+ * @param {Object} accumulator The initial aggregated object.
+ * @returns {Function} Returns `accumulator`.
+ */function arrayAggregator(array,setter,iteratee,accumulator){var index=-1,length=array==null?0:array.length;while(++index<length){var value=array[index];setter(accumulator,value,iteratee(value),array);}return accumulator;}/**
+ * A specialized version of `_.forEach` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns `array`.
+ */function arrayEach(array,iteratee){var index=-1,length=array==null?0:array.length;while(++index<length){if(iteratee(array[index],index,array)===false){break;}}return array;}/**
+ * A specialized version of `_.forEachRight` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns `array`.
+ */function arrayEachRight(array,iteratee){var length=array==null?0:array.length;while(length--){if(iteratee(array[length],length,array)===false){break;}}return array;}/**
+ * A specialized version of `_.every` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {boolean} Returns `true` if all elements pass the predicate check,
+ * else `false`.
+ */function arrayEvery(array,predicate){var index=-1,length=array==null?0:array.length;while(++index<length){if(!predicate(array[index],index,array)){return false;}}return true;}/**
+ * A specialized version of `_.filter` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {Array} Returns the new filtered array.
+ */function arrayFilter(array,predicate){var index=-1,length=array==null?0:array.length,resIndex=0,result=[];while(++index<length){var value=array[index];if(predicate(value,index,array)){result[resIndex++]=value;}}return result;}/**
+ * A specialized version of `_.includes` for arrays without support for
+ * specifying an index to search from.
+ *
+ * @private
+ * @param {Array} [array] The array to inspect.
+ * @param {*} target The value to search for.
+ * @returns {boolean} Returns `true` if `target` is found, else `false`.
+ */function arrayIncludes(array,value){var length=array==null?0:array.length;return !!length&&baseIndexOf(array,value,0)>-1;}/**
+ * This function is like `arrayIncludes` except that it accepts a comparator.
+ *
+ * @private
+ * @param {Array} [array] The array to inspect.
+ * @param {*} target The value to search for.
+ * @param {Function} comparator The comparator invoked per element.
+ * @returns {boolean} Returns `true` if `target` is found, else `false`.
+ */function arrayIncludesWith(array,value,comparator){var index=-1,length=array==null?0:array.length;while(++index<length){if(comparator(value,array[index])){return true;}}return false;}/**
+ * A specialized version of `_.map` for arrays without support for iteratee
+ * shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the new mapped array.
+ */function arrayMap(array,iteratee){var index=-1,length=array==null?0:array.length,result=Array(length);while(++index<length){result[index]=iteratee(array[index],index,array);}return result;}/**
+ * Appends the elements of `values` to `array`.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to append.
+ * @returns {Array} Returns `array`.
+ */function arrayPush(array,values){var index=-1,length=values.length,offset=array.length;while(++index<length){array[offset+index]=values[index];}return array;}/**
+ * A specialized version of `_.reduce` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {*} [accumulator] The initial value.
+ * @param {boolean} [initAccum] Specify using the first element of `array` as
+ * the initial value.
+ * @returns {*} Returns the accumulated value.
+ */function arrayReduce(array,iteratee,accumulator,initAccum){var index=-1,length=array==null?0:array.length;if(initAccum&&length){accumulator=array[++index];}while(++index<length){accumulator=iteratee(accumulator,array[index],index,array);}return accumulator;}/**
+ * A specialized version of `_.reduceRight` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {*} [accumulator] The initial value.
+ * @param {boolean} [initAccum] Specify using the last element of `array` as
+ * the initial value.
+ * @returns {*} Returns the accumulated value.
+ */function arrayReduceRight(array,iteratee,accumulator,initAccum){var length=array==null?0:array.length;if(initAccum&&length){accumulator=array[--length];}while(length--){accumulator=iteratee(accumulator,array[length],length,array);}return accumulator;}/**
+ * A specialized version of `_.some` for arrays without support for iteratee
+ * shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {boolean} Returns `true` if any element passes the predicate check,
+ * else `false`.
+ */function arraySome(array,predicate){var index=-1,length=array==null?0:array.length;while(++index<length){if(predicate(array[index],index,array)){return true;}}return false;}/**
+ * Gets the size of an ASCII `string`.
+ *
+ * @private
+ * @param {string} string The string inspect.
+ * @returns {number} Returns the string size.
+ */var asciiSize=baseProperty('length');/**
+ * Converts an ASCII `string` to an array.
+ *
+ * @private
+ * @param {string} string The string to convert.
+ * @returns {Array} Returns the converted array.
+ */function asciiToArray(string){return string.split('');}/**
+ * Splits an ASCII `string` into an array of its words.
+ *
+ * @private
+ * @param {string} The string to inspect.
+ * @returns {Array} Returns the words of `string`.
+ */function asciiWords(string){return string.match(reAsciiWord)||[];}/**
+ * The base implementation of methods like `_.findKey` and `_.findLastKey`,
+ * without support for iteratee shorthands, which iterates over `collection`
+ * using `eachFunc`.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to inspect.
+ * @param {Function} predicate The function invoked per iteration.
+ * @param {Function} eachFunc The function to iterate over `collection`.
+ * @returns {*} Returns the found element or its key, else `undefined`.
+ */function baseFindKey(collection,predicate,eachFunc){var result;eachFunc(collection,function(value,key,collection){if(predicate(value,key,collection)){result=key;return false;}});return result;}/**
+ * The base implementation of `_.findIndex` and `_.findLastIndex` without
+ * support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {Function} predicate The function invoked per iteration.
+ * @param {number} fromIndex The index to search from.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */function baseFindIndex(array,predicate,fromIndex,fromRight){var length=array.length,index=fromIndex+(fromRight?1:-1);while(fromRight?index--:++index<length){if(predicate(array[index],index,array)){return index;}}return -1;}/**
+ * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {*} value The value to search for.
+ * @param {number} fromIndex The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */function baseIndexOf(array,value,fromIndex){return value===value?strictIndexOf(array,value,fromIndex):baseFindIndex(array,baseIsNaN,fromIndex);}/**
+ * This function is like `baseIndexOf` except that it accepts a comparator.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {*} value The value to search for.
+ * @param {number} fromIndex The index to search from.
+ * @param {Function} comparator The comparator invoked per element.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */function baseIndexOfWith(array,value,fromIndex,comparator){var index=fromIndex-1,length=array.length;while(++index<length){if(comparator(array[index],value)){return index;}}return -1;}/**
+ * The base implementation of `_.isNaN` without support for number objects.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
+ */function baseIsNaN(value){return value!==value;}/**
+ * The base implementation of `_.mean` and `_.meanBy` without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {number} Returns the mean.
+ */function baseMean(array,iteratee){var length=array==null?0:array.length;return length?baseSum(array,iteratee)/length:NAN;}/**
+ * The base implementation of `_.property` without support for deep paths.
+ *
+ * @private
+ * @param {string} key The key of the property to get.
+ * @returns {Function} Returns the new accessor function.
+ */function baseProperty(key){return function(object){return object==null?undefined$1:object[key];};}/**
+ * The base implementation of `_.propertyOf` without support for deep paths.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Function} Returns the new accessor function.
+ */function basePropertyOf(object){return function(key){return object==null?undefined$1:object[key];};}/**
+ * The base implementation of `_.reduce` and `_.reduceRight`, without support
+ * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {*} accumulator The initial value.
+ * @param {boolean} initAccum Specify using the first or last element of
+ * `collection` as the initial value.
+ * @param {Function} eachFunc The function to iterate over `collection`.
+ * @returns {*} Returns the accumulated value.
+ */function baseReduce(collection,iteratee,accumulator,initAccum,eachFunc){eachFunc(collection,function(value,index,collection){accumulator=initAccum?(initAccum=false,value):iteratee(accumulator,value,index,collection);});return accumulator;}/**
+ * The base implementation of `_.sortBy` which uses `comparer` to define the
+ * sort order of `array` and replaces criteria objects with their corresponding
+ * values.
+ *
+ * @private
+ * @param {Array} array The array to sort.
+ * @param {Function} comparer The function to define sort order.
+ * @returns {Array} Returns `array`.
+ */function baseSortBy(array,comparer){var length=array.length;array.sort(comparer);while(length--){array[length]=array[length].value;}return array;}/**
+ * The base implementation of `_.sum` and `_.sumBy` without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {number} Returns the sum.
+ */function baseSum(array,iteratee){var result,index=-1,length=array.length;while(++index<length){var current=iteratee(array[index]);if(current!==undefined$1){result=result===undefined$1?current:result+current;}}return result;}/**
+ * The base implementation of `_.times` without support for iteratee shorthands
+ * or max array length checks.
+ *
+ * @private
+ * @param {number} n The number of times to invoke `iteratee`.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the array of results.
+ */function baseTimes(n,iteratee){var index=-1,result=Array(n);while(++index<n){result[index]=iteratee(index);}return result;}/**
+ * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
+ * of key-value pairs for `object` corresponding to the property names of `props`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array} props The property names to get values for.
+ * @returns {Object} Returns the key-value pairs.
+ */function baseToPairs(object,props){return arrayMap(props,function(key){return [key,object[key]];});}/**
+ * The base implementation of `_.trim`.
+ *
+ * @private
+ * @param {string} string The string to trim.
+ * @returns {string} Returns the trimmed string.
+ */function baseTrim(string){return string?string.slice(0,trimmedEndIndex(string)+1).replace(reTrimStart,''):string;}/**
+ * The base implementation of `_.unary` without support for storing metadata.
+ *
+ * @private
+ * @param {Function} func The function to cap arguments for.
+ * @returns {Function} Returns the new capped function.
+ */function baseUnary(func){return function(value){return func(value);};}/**
+ * The base implementation of `_.values` and `_.valuesIn` which creates an
+ * array of `object` property values corresponding to the property names
+ * of `props`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array} props The property names to get values for.
+ * @returns {Object} Returns the array of property values.
+ */function baseValues(object,props){return arrayMap(props,function(key){return object[key];});}/**
+ * Checks if a `cache` value for `key` exists.
+ *
+ * @private
+ * @param {Object} cache The cache to query.
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */function cacheHas(cache,key){return cache.has(key);}/**
+ * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
+ * that is not found in the character symbols.
+ *
+ * @private
+ * @param {Array} strSymbols The string symbols to inspect.
+ * @param {Array} chrSymbols The character symbols to find.
+ * @returns {number} Returns the index of the first unmatched string symbol.
+ */function charsStartIndex(strSymbols,chrSymbols){var index=-1,length=strSymbols.length;while(++index<length&&baseIndexOf(chrSymbols,strSymbols[index],0)>-1){}return index;}/**
+ * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
+ * that is not found in the character symbols.
+ *
+ * @private
+ * @param {Array} strSymbols The string symbols to inspect.
+ * @param {Array} chrSymbols The character symbols to find.
+ * @returns {number} Returns the index of the last unmatched string symbol.
+ */function charsEndIndex(strSymbols,chrSymbols){var index=strSymbols.length;while(index--&&baseIndexOf(chrSymbols,strSymbols[index],0)>-1){}return index;}/**
+ * Gets the number of `placeholder` occurrences in `array`.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {*} placeholder The placeholder to search for.
+ * @returns {number} Returns the placeholder count.
+ */function countHolders(array,placeholder){var length=array.length,result=0;while(length--){if(array[length]===placeholder){++result;}}return result;}/**
+ * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
+ * letters to basic Latin letters.
+ *
+ * @private
+ * @param {string} letter The matched letter to deburr.
+ * @returns {string} Returns the deburred letter.
+ */var deburrLetter=basePropertyOf(deburredLetters);/**
+ * Used by `_.escape` to convert characters to HTML entities.
+ *
+ * @private
+ * @param {string} chr The matched character to escape.
+ * @returns {string} Returns the escaped character.
+ */var escapeHtmlChar=basePropertyOf(htmlEscapes);/**
+ * Used by `_.template` to escape characters for inclusion in compiled string literals.
+ *
+ * @private
+ * @param {string} chr The matched character to escape.
+ * @returns {string} Returns the escaped character.
+ */function escapeStringChar(chr){return '\\'+stringEscapes[chr];}/**
+ * Gets the value at `key` of `object`.
+ *
+ * @private
+ * @param {Object} [object] The object to query.
+ * @param {string} key The key of the property to get.
+ * @returns {*} Returns the property value.
+ */function getValue(object,key){return object==null?undefined$1:object[key];}/**
+ * Checks if `string` contains Unicode symbols.
+ *
+ * @private
+ * @param {string} string The string to inspect.
+ * @returns {boolean} Returns `true` if a symbol is found, else `false`.
+ */function hasUnicode(string){return reHasUnicode.test(string);}/**
+ * Checks if `string` contains a word composed of Unicode symbols.
+ *
+ * @private
+ * @param {string} string The string to inspect.
+ * @returns {boolean} Returns `true` if a word is found, else `false`.
+ */function hasUnicodeWord(string){return reHasUnicodeWord.test(string);}/**
+ * Converts `iterator` to an array.
+ *
+ * @private
+ * @param {Object} iterator The iterator to convert.
+ * @returns {Array} Returns the converted array.
+ */function iteratorToArray(iterator){var data,result=[];while(!(data=iterator.next()).done){result.push(data.value);}return result;}/**
+ * Converts `map` to its key-value pairs.
+ *
+ * @private
+ * @param {Object} map The map to convert.
+ * @returns {Array} Returns the key-value pairs.
+ */function mapToArray(map){var index=-1,result=Array(map.size);map.forEach(function(value,key){result[++index]=[key,value];});return result;}/**
+ * Creates a unary function that invokes `func` with its argument transformed.
+ *
+ * @private
+ * @param {Function} func The function to wrap.
+ * @param {Function} transform The argument transform.
+ * @returns {Function} Returns the new function.
+ */function overArg(func,transform){return function(arg){return func(transform(arg));};}/**
+ * Replaces all `placeholder` elements in `array` with an internal placeholder
+ * and returns an array of their indexes.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {*} placeholder The placeholder to replace.
+ * @returns {Array} Returns the new array of placeholder indexes.
+ */function replaceHolders(array,placeholder){var index=-1,length=array.length,resIndex=0,result=[];while(++index<length){var value=array[index];if(value===placeholder||value===PLACEHOLDER){array[index]=PLACEHOLDER;result[resIndex++]=index;}}return result;}/**
+ * Converts `set` to an array of its values.
+ *
+ * @private
+ * @param {Object} set The set to convert.
+ * @returns {Array} Returns the values.
+ */function setToArray(set){var index=-1,result=Array(set.size);set.forEach(function(value){result[++index]=value;});return result;}/**
+ * Converts `set` to its value-value pairs.
+ *
+ * @private
+ * @param {Object} set The set to convert.
+ * @returns {Array} Returns the value-value pairs.
+ */function setToPairs(set){var index=-1,result=Array(set.size);set.forEach(function(value){result[++index]=[value,value];});return result;}/**
+ * A specialized version of `_.indexOf` which performs strict equality
+ * comparisons of values, i.e. `===`.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {*} value The value to search for.
+ * @param {number} fromIndex The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */function strictIndexOf(array,value,fromIndex){var index=fromIndex-1,length=array.length;while(++index<length){if(array[index]===value){return index;}}return -1;}/**
+ * A specialized version of `_.lastIndexOf` which performs strict equality
+ * comparisons of values, i.e. `===`.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {*} value The value to search for.
+ * @param {number} fromIndex The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */function strictLastIndexOf(array,value,fromIndex){var index=fromIndex+1;while(index--){if(array[index]===value){return index;}}return index;}/**
+ * Gets the number of symbols in `string`.
+ *
+ * @private
+ * @param {string} string The string to inspect.
+ * @returns {number} Returns the string size.
+ */function stringSize(string){return hasUnicode(string)?unicodeSize(string):asciiSize(string);}/**
+ * Converts `string` to an array.
+ *
+ * @private
+ * @param {string} string The string to convert.
+ * @returns {Array} Returns the converted array.
+ */function stringToArray(string){return hasUnicode(string)?unicodeToArray(string):asciiToArray(string);}/**
+ * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
+ * character of `string`.
+ *
+ * @private
+ * @param {string} string The string to inspect.
+ * @returns {number} Returns the index of the last non-whitespace character.
+ */function trimmedEndIndex(string){var index=string.length;while(index--&&reWhitespace.test(string.charAt(index))){}return index;}/**
+ * Used by `_.unescape` to convert HTML entities to characters.
+ *
+ * @private
+ * @param {string} chr The matched character to unescape.
+ * @returns {string} Returns the unescaped character.
+ */var unescapeHtmlChar=basePropertyOf(htmlUnescapes);/**
+ * Gets the size of a Unicode `string`.
+ *
+ * @private
+ * @param {string} string The string inspect.
+ * @returns {number} Returns the string size.
+ */function unicodeSize(string){var result=reUnicode.lastIndex=0;while(reUnicode.test(string)){++result;}return result;}/**
+ * Converts a Unicode `string` to an array.
+ *
+ * @private
+ * @param {string} string The string to convert.
+ * @returns {Array} Returns the converted array.
+ */function unicodeToArray(string){return string.match(reUnicode)||[];}/**
+ * Splits a Unicode `string` into an array of its words.
+ *
+ * @private
+ * @param {string} The string to inspect.
+ * @returns {Array} Returns the words of `string`.
+ */function unicodeWords(string){return string.match(reUnicodeWord)||[];}/*--------------------------------------------------------------------------*/ /**
+ * Create a new pristine `lodash` function using the `context` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.1.0
+ * @category Util
+ * @param {Object} [context=root] The context object.
+ * @returns {Function} Returns a new `lodash` function.
+ * @example
+ *
+ * _.mixin({ 'foo': _.constant('foo') });
+ *
+ * var lodash = _.runInContext();
+ * lodash.mixin({ 'bar': lodash.constant('bar') });
+ *
+ * _.isFunction(_.foo);
+ * // => true
+ * _.isFunction(_.bar);
+ * // => false
+ *
+ * lodash.isFunction(lodash.foo);
+ * // => false
+ * lodash.isFunction(lodash.bar);
+ * // => true
+ *
+ * // Create a suped-up `defer` in Node.js.
+ * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
+ */var runInContext=function runInContext(context){context=context==null?root:_.defaults(root.Object(),context,_.pick(root,contextProps));/** Built-in constructor references. */var Array=context.Array,Date=context.Date,Error=context.Error,Function=context.Function,Math=context.Math,Object=context.Object,RegExp=context.RegExp,String=context.String,TypeError=context.TypeError;/** Used for built-in method references. */var arrayProto=Array.prototype,funcProto=Function.prototype,objectProto=Object.prototype;/** Used to detect overreaching core-js shims. */var coreJsData=context['__core-js_shared__'];/** Used to resolve the decompiled source of functions. */var funcToString=funcProto.toString;/** Used to check objects for own properties. */var hasOwnProperty=objectProto.hasOwnProperty;/** Used to generate unique IDs. */var idCounter=0;/** Used to detect methods masquerading as native. */var maskSrcKey=function(){var uid=/[^.]+$/.exec(coreJsData&&coreJsData.keys&&coreJsData.keys.IE_PROTO||'');return uid?'Symbol(src)_1.'+uid:'';}();/**
+ * Used to resolve the
+ * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
+ * of values.
+ */var nativeObjectToString=objectProto.toString;/** Used to infer the `Object` constructor. */var objectCtorString=funcToString.call(Object);/** Used to restore the original `_` reference in `_.noConflict`. */var oldDash=root._;/** Used to detect if a method is native. */var reIsNative=RegExp('^'+funcToString.call(hasOwnProperty).replace(reRegExpChar,'\\$&').replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,'$1.*?')+'$');/** Built-in value references. */var Buffer=moduleExports?context.Buffer:undefined$1,Symbol=context.Symbol,Uint8Array=context.Uint8Array,allocUnsafe=Buffer?Buffer.allocUnsafe:undefined$1,getPrototype=overArg(Object.getPrototypeOf,Object),objectCreate=Object.create,propertyIsEnumerable=objectProto.propertyIsEnumerable,splice=arrayProto.splice,spreadableSymbol=Symbol?Symbol.isConcatSpreadable:undefined$1,symIterator=Symbol?Symbol.iterator:undefined$1,symToStringTag=Symbol?Symbol.toStringTag:undefined$1;var defineProperty=function(){try{var func=getNative(Object,'defineProperty');func({},'',{});return func;}catch(e){}}();/** Mocked built-ins. */var ctxClearTimeout=context.clearTimeout!==root.clearTimeout&&context.clearTimeout,ctxNow=Date&&Date.now!==root.Date.now&&Date.now,ctxSetTimeout=context.setTimeout!==root.setTimeout&&context.setTimeout;/* Built-in method references for those with the same name as other `lodash` methods. */var nativeCeil=Math.ceil,nativeFloor=Math.floor,nativeGetSymbols=Object.getOwnPropertySymbols,nativeIsBuffer=Buffer?Buffer.isBuffer:undefined$1,nativeIsFinite=context.isFinite,nativeJoin=arrayProto.join,nativeKeys=overArg(Object.keys,Object),nativeMax=Math.max,nativeMin=Math.min,nativeNow=Date.now,nativeParseInt=context.parseInt,nativeRandom=Math.random,nativeReverse=arrayProto.reverse;/* Built-in method references that are verified to be native. */var DataView=getNative(context,'DataView'),Map=getNative(context,'Map'),Promise=getNative(context,'Promise'),Set=getNative(context,'Set'),WeakMap=getNative(context,'WeakMap'),nativeCreate=getNative(Object,'create');/** Used to store function metadata. */var metaMap=WeakMap&&new WeakMap();/** Used to lookup unminified function names. */var realNames={};/** Used to detect maps, sets, and weakmaps. */var dataViewCtorString=toSource(DataView),mapCtorString=toSource(Map),promiseCtorString=toSource(Promise),setCtorString=toSource(Set),weakMapCtorString=toSource(WeakMap);/** Used to convert symbols to primitives and strings. */var symbolProto=Symbol?Symbol.prototype:undefined$1,symbolValueOf=symbolProto?symbolProto.valueOf:undefined$1,symbolToString=symbolProto?symbolProto.toString:undefined$1;/*------------------------------------------------------------------------*/ /**
+ * Creates a `lodash` object which wraps `value` to enable implicit method
+ * chain sequences. Methods that operate on and return arrays, collections,
+ * and functions can be chained together. Methods that retrieve a single value
+ * or may return a primitive value will automatically end the chain sequence
+ * and return the unwrapped value. Otherwise, the value must be unwrapped
+ * with `_#value`.
+ *
+ * Explicit chain sequences, which must be unwrapped with `_#value`, may be
+ * enabled using `_.chain`.
+ *
+ * The execution of chained methods is lazy, that is, it's deferred until
+ * `_#value` is implicitly or explicitly called.
+ *
+ * Lazy evaluation allows several methods to support shortcut fusion.
+ * Shortcut fusion is an optimization to merge iteratee calls; this avoids
+ * the creation of intermediate arrays and can greatly reduce the number of
+ * iteratee executions. Sections of a chain sequence qualify for shortcut
+ * fusion if the section is applied to an array and iteratees accept only
+ * one argument. The heuristic for whether a section qualifies for shortcut
+ * fusion is subject to change.
+ *
+ * Chaining is supported in custom builds as long as the `_#value` method is
+ * directly or indirectly included in the build.
+ *
+ * In addition to lodash methods, wrappers have `Array` and `String` methods.
+ *
+ * The wrapper `Array` methods are:
+ * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
+ *
+ * The wrapper `String` methods are:
+ * `replace` and `split`
+ *
+ * The wrapper methods that support shortcut fusion are:
+ * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
+ * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
+ * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
+ *
+ * The chainable wrapper methods are:
+ * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
+ * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
+ * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
+ * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
+ * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
+ * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
+ * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
+ * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
+ * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
+ * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
+ * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
+ * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
+ * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
+ * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
+ * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
+ * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
+ * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
+ * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
+ * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
+ * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
+ * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
+ * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
+ * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
+ * `zipObject`, `zipObjectDeep`, and `zipWith`
+ *
+ * The wrapper methods that are **not** chainable by default are:
+ * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
+ * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
+ * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
+ * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
+ * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
+ * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
+ * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
+ * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
+ * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
+ * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
+ * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
+ * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
+ * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
+ * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
+ * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
+ * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
+ * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
+ * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
+ * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
+ * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
+ * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
+ * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
+ * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
+ * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
+ * `upperFirst`, `value`, and `words`
+ *
+ * @name _
+ * @constructor
+ * @category Seq
+ * @param {*} value The value to wrap in a `lodash` instance.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * var wrapped = _([1, 2, 3]);
+ *
+ * // Returns an unwrapped value.
+ * wrapped.reduce(_.add);
+ * // => 6
+ *
+ * // Returns a wrapped value.
+ * var squares = wrapped.map(square);
+ *
+ * _.isArray(squares);
+ * // => false
+ *
+ * _.isArray(squares.value());
+ * // => true
+ */function lodash(value){if(isObjectLike(value)&&!isArray(value)&&!(value instanceof LazyWrapper)){if(value instanceof LodashWrapper){return value;}if(hasOwnProperty.call(value,'__wrapped__')){return wrapperClone(value);}}return new LodashWrapper(value);}/**
+ * The base implementation of `_.create` without support for assigning
+ * properties to the created object.
+ *
+ * @private
+ * @param {Object} proto The object to inherit from.
+ * @returns {Object} Returns the new object.
+ */var baseCreate=function(){function object(){}return function(proto){if(!isObject(proto)){return {};}if(objectCreate){return objectCreate(proto);}object.prototype=proto;var result=new object();object.prototype=undefined$1;return result;};}();/**
+ * The function whose prototype chain sequence wrappers inherit from.
+ *
+ * @private
+ */function baseLodash(){// No operation performed.
+}/**
+ * The base constructor for creating `lodash` wrapper objects.
+ *
+ * @private
+ * @param {*} value The value to wrap.
+ * @param {boolean} [chainAll] Enable explicit method chain sequences.
+ */function LodashWrapper(value,chainAll){this.__wrapped__=value;this.__actions__=[];this.__chain__=!!chainAll;this.__index__=0;this.__values__=undefined$1;}/**
+ * By default, the template delimiters used by lodash are like those in
+ * embedded Ruby (ERB) as well as ES2015 template strings. Change the
+ * following template settings to use alternative delimiters.
+ *
+ * @static
+ * @memberOf _
+ * @type {Object}
+ */lodash.templateSettings={/**
+ * Used to detect `data` property values to be HTML-escaped.
+ *
+ * @memberOf _.templateSettings
+ * @type {RegExp}
+ */'escape':reEscape,/**
+ * Used to detect code to be evaluated.
+ *
+ * @memberOf _.templateSettings
+ * @type {RegExp}
+ */'evaluate':reEvaluate,/**
+ * Used to detect `data` property values to inject.
+ *
+ * @memberOf _.templateSettings
+ * @type {RegExp}
+ */'interpolate':reInterpolate,/**
+ * Used to reference the data object in the template text.
+ *
+ * @memberOf _.templateSettings
+ * @type {string}
+ */'variable':'',/**
+ * Used to import variables into the compiled template.
+ *
+ * @memberOf _.templateSettings
+ * @type {Object}
+ */'imports':{/**
+ * A reference to the `lodash` function.
+ *
+ * @memberOf _.templateSettings.imports
+ * @type {Function}
+ */'_':lodash}};// Ensure wrappers are instances of `baseLodash`.
+lodash.prototype=baseLodash.prototype;lodash.prototype.constructor=lodash;LodashWrapper.prototype=baseCreate(baseLodash.prototype);LodashWrapper.prototype.constructor=LodashWrapper;/*------------------------------------------------------------------------*/ /**
+ * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
+ *
+ * @private
+ * @constructor
+ * @param {*} value The value to wrap.
+ */function LazyWrapper(value){this.__wrapped__=value;this.__actions__=[];this.__dir__=1;this.__filtered__=false;this.__iteratees__=[];this.__takeCount__=MAX_ARRAY_LENGTH;this.__views__=[];}/**
+ * Creates a clone of the lazy wrapper object.
+ *
+ * @private
+ * @name clone
+ * @memberOf LazyWrapper
+ * @returns {Object} Returns the cloned `LazyWrapper` object.
+ */function lazyClone(){var result=new LazyWrapper(this.__wrapped__);result.__actions__=copyArray(this.__actions__);result.__dir__=this.__dir__;result.__filtered__=this.__filtered__;result.__iteratees__=copyArray(this.__iteratees__);result.__takeCount__=this.__takeCount__;result.__views__=copyArray(this.__views__);return result;}/**
+ * Reverses the direction of lazy iteration.
+ *
+ * @private
+ * @name reverse
+ * @memberOf LazyWrapper
+ * @returns {Object} Returns the new reversed `LazyWrapper` object.
+ */function lazyReverse(){if(this.__filtered__){var result=new LazyWrapper(this);result.__dir__=-1;result.__filtered__=true;}else {result=this.clone();result.__dir__*=-1;}return result;}/**
+ * Extracts the unwrapped value from its lazy wrapper.
+ *
+ * @private
+ * @name value
+ * @memberOf LazyWrapper
+ * @returns {*} Returns the unwrapped value.
+ */function lazyValue(){var array=this.__wrapped__.value(),dir=this.__dir__,isArr=isArray(array),isRight=dir<0,arrLength=isArr?array.length:0,view=getView(0,arrLength,this.__views__),start=view.start,end=view.end,length=end-start,index=isRight?end:start-1,iteratees=this.__iteratees__,iterLength=iteratees.length,resIndex=0,takeCount=nativeMin(length,this.__takeCount__);if(!isArr||!isRight&&arrLength==length&&takeCount==length){return baseWrapperValue(array,this.__actions__);}var result=[];outer:while(length--&&resIndex<takeCount){index+=dir;var iterIndex=-1,value=array[index];while(++iterIndex<iterLength){var data=iteratees[iterIndex],iteratee=data.iteratee,type=data.type,computed=iteratee(value);if(type==LAZY_MAP_FLAG){value=computed;}else if(!computed){if(type==LAZY_FILTER_FLAG){continue outer;}else {break outer;}}}result[resIndex++]=value;}return result;}// Ensure `LazyWrapper` is an instance of `baseLodash`.
+LazyWrapper.prototype=baseCreate(baseLodash.prototype);LazyWrapper.prototype.constructor=LazyWrapper;/*------------------------------------------------------------------------*/ /**
+ * Creates a hash object.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [entries] The key-value pairs to cache.
+ */function Hash(entries){var index=-1,length=entries==null?0:entries.length;this.clear();while(++index<length){var entry=entries[index];this.set(entry[0],entry[1]);}}/**
+ * Removes all key-value entries from the hash.
+ *
+ * @private
+ * @name clear
+ * @memberOf Hash
+ */function hashClear(){this.__data__=nativeCreate?nativeCreate(null):{};this.size=0;}/**
+ * Removes `key` and its value from the hash.
+ *
+ * @private
+ * @name delete
+ * @memberOf Hash
+ * @param {Object} hash The hash to modify.
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */function hashDelete(key){var result=this.has(key)&&delete this.__data__[key];this.size-=result?1:0;return result;}/**
+ * Gets the hash value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf Hash
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */function hashGet(key){var data=this.__data__;if(nativeCreate){var result=data[key];return result===HASH_UNDEFINED?undefined$1:result;}return hasOwnProperty.call(data,key)?data[key]:undefined$1;}/**
+ * Checks if a hash value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf Hash
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */function hashHas(key){var data=this.__data__;return nativeCreate?data[key]!==undefined$1:hasOwnProperty.call(data,key);}/**
+ * Sets the hash `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf Hash
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the hash instance.
+ */function hashSet(key,value){var data=this.__data__;this.size+=this.has(key)?0:1;data[key]=nativeCreate&&value===undefined$1?HASH_UNDEFINED:value;return this;}// Add methods to `Hash`.
+Hash.prototype.clear=hashClear;Hash.prototype['delete']=hashDelete;Hash.prototype.get=hashGet;Hash.prototype.has=hashHas;Hash.prototype.set=hashSet;/*------------------------------------------------------------------------*/ /**
+ * Creates an list cache object.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [entries] The key-value pairs to cache.
+ */function ListCache(entries){var index=-1,length=entries==null?0:entries.length;this.clear();while(++index<length){var entry=entries[index];this.set(entry[0],entry[1]);}}/**
+ * Removes all key-value entries from the list cache.
+ *
+ * @private
+ * @name clear
+ * @memberOf ListCache
+ */function listCacheClear(){this.__data__=[];this.size=0;}/**
+ * Removes `key` and its value from the list cache.
+ *
+ * @private
+ * @name delete
+ * @memberOf ListCache
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */function listCacheDelete(key){var data=this.__data__,index=assocIndexOf(data,key);if(index<0){return false;}var lastIndex=data.length-1;if(index==lastIndex){data.pop();}else {splice.call(data,index,1);}--this.size;return true;}/**
+ * Gets the list cache value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf ListCache
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */function listCacheGet(key){var data=this.__data__,index=assocIndexOf(data,key);return index<0?undefined$1:data[index][1];}/**
+ * Checks if a list cache value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf ListCache
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */function listCacheHas(key){return assocIndexOf(this.__data__,key)>-1;}/**
+ * Sets the list cache `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf ListCache
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the list cache instance.
+ */function listCacheSet(key,value){var data=this.__data__,index=assocIndexOf(data,key);if(index<0){++this.size;data.push([key,value]);}else {data[index][1]=value;}return this;}// Add methods to `ListCache`.
+ListCache.prototype.clear=listCacheClear;ListCache.prototype['delete']=listCacheDelete;ListCache.prototype.get=listCacheGet;ListCache.prototype.has=listCacheHas;ListCache.prototype.set=listCacheSet;/*------------------------------------------------------------------------*/ /**
+ * Creates a map cache object to store key-value pairs.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [entries] The key-value pairs to cache.
+ */function MapCache(entries){var index=-1,length=entries==null?0:entries.length;this.clear();while(++index<length){var entry=entries[index];this.set(entry[0],entry[1]);}}/**
+ * Removes all key-value entries from the map.
+ *
+ * @private
+ * @name clear
+ * @memberOf MapCache
+ */function mapCacheClear(){this.size=0;this.__data__={'hash':new Hash(),'map':new(Map||ListCache)(),'string':new Hash()};}/**
+ * Removes `key` and its value from the map.
+ *
+ * @private
+ * @name delete
+ * @memberOf MapCache
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */function mapCacheDelete(key){var result=getMapData(this,key)['delete'](key);this.size-=result?1:0;return result;}/**
+ * Gets the map value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf MapCache
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */function mapCacheGet(key){return getMapData(this,key).get(key);}/**
+ * Checks if a map value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf MapCache
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */function mapCacheHas(key){return getMapData(this,key).has(key);}/**
+ * Sets the map `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf MapCache
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the map cache instance.
+ */function mapCacheSet(key,value){var data=getMapData(this,key),size=data.size;data.set(key,value);this.size+=data.size==size?0:1;return this;}// Add methods to `MapCache`.
+MapCache.prototype.clear=mapCacheClear;MapCache.prototype['delete']=mapCacheDelete;MapCache.prototype.get=mapCacheGet;MapCache.prototype.has=mapCacheHas;MapCache.prototype.set=mapCacheSet;/*------------------------------------------------------------------------*/ /**
+ *
+ * Creates an array cache object to store unique values.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [values] The values to cache.
+ */function SetCache(values){var index=-1,length=values==null?0:values.length;this.__data__=new MapCache();while(++index<length){this.add(values[index]);}}/**
+ * Adds `value` to the array cache.
+ *
+ * @private
+ * @name add
+ * @memberOf SetCache
+ * @alias push
+ * @param {*} value The value to cache.
+ * @returns {Object} Returns the cache instance.
+ */function setCacheAdd(value){this.__data__.set(value,HASH_UNDEFINED);return this;}/**
+ * Checks if `value` is in the array cache.
+ *
+ * @private
+ * @name has
+ * @memberOf SetCache
+ * @param {*} value The value to search for.
+ * @returns {number} Returns `true` if `value` is found, else `false`.
+ */function setCacheHas(value){return this.__data__.has(value);}// Add methods to `SetCache`.
+SetCache.prototype.add=SetCache.prototype.push=setCacheAdd;SetCache.prototype.has=setCacheHas;/*------------------------------------------------------------------------*/ /**
+ * Creates a stack cache object to store key-value pairs.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [entries] The key-value pairs to cache.
+ */function Stack(entries){var data=this.__data__=new ListCache(entries);this.size=data.size;}/**
+ * Removes all key-value entries from the stack.
+ *
+ * @private
+ * @name clear
+ * @memberOf Stack
+ */function stackClear(){this.__data__=new ListCache();this.size=0;}/**
+ * Removes `key` and its value from the stack.
+ *
+ * @private
+ * @name delete
+ * @memberOf Stack
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */function stackDelete(key){var data=this.__data__,result=data['delete'](key);this.size=data.size;return result;}/**
+ * Gets the stack value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf Stack
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */function stackGet(key){return this.__data__.get(key);}/**
+ * Checks if a stack value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf Stack
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */function stackHas(key){return this.__data__.has(key);}/**
+ * Sets the stack `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf Stack
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the stack cache instance.
+ */function stackSet(key,value){var data=this.__data__;if(data instanceof ListCache){var pairs=data.__data__;if(!Map||pairs.length<LARGE_ARRAY_SIZE-1){pairs.push([key,value]);this.size=++data.size;return this;}data=this.__data__=new MapCache(pairs);}data.set(key,value);this.size=data.size;return this;}// Add methods to `Stack`.
+Stack.prototype.clear=stackClear;Stack.prototype['delete']=stackDelete;Stack.prototype.get=stackGet;Stack.prototype.has=stackHas;Stack.prototype.set=stackSet;/*------------------------------------------------------------------------*/ /**
+ * Creates an array of the enumerable property names of the array-like `value`.
+ *
+ * @private
+ * @param {*} value The value to query.
+ * @param {boolean} inherited Specify returning inherited property names.
+ * @returns {Array} Returns the array of property names.
+ */function arrayLikeKeys(value,inherited){var isArr=isArray(value),isArg=!isArr&&isArguments(value),isBuff=!isArr&&!isArg&&isBuffer(value),isType=!isArr&&!isArg&&!isBuff&&isTypedArray(value),skipIndexes=isArr||isArg||isBuff||isType,result=skipIndexes?baseTimes(value.length,String):[],length=result.length;for(var key in value){if((inherited||hasOwnProperty.call(value,key))&&!(skipIndexes&&(// Safari 9 has enumerable `arguments.length` in strict mode.
+key=='length'||// Node.js 0.10 has enumerable non-index properties on buffers.
+isBuff&&(key=='offset'||key=='parent')||// PhantomJS 2 has enumerable non-index properties on typed arrays.
+isType&&(key=='buffer'||key=='byteLength'||key=='byteOffset')||// Skip index properties.
+isIndex(key,length)))){result.push(key);}}return result;}/**
+ * A specialized version of `_.sample` for arrays.
+ *
+ * @private
+ * @param {Array} array The array to sample.
+ * @returns {*} Returns the random element.
+ */function arraySample(array){var length=array.length;return length?array[baseRandom(0,length-1)]:undefined$1;}/**
+ * A specialized version of `_.sampleSize` for arrays.
+ *
+ * @private
+ * @param {Array} array The array to sample.
+ * @param {number} n The number of elements to sample.
+ * @returns {Array} Returns the random elements.
+ */function arraySampleSize(array,n){return shuffleSelf(copyArray(array),baseClamp(n,0,array.length));}/**
+ * A specialized version of `_.shuffle` for arrays.
+ *
+ * @private
+ * @param {Array} array The array to shuffle.
+ * @returns {Array} Returns the new shuffled array.
+ */function arrayShuffle(array){return shuffleSelf(copyArray(array));}/**
+ * This function is like `assignValue` except that it doesn't assign
+ * `undefined` values.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {string} key The key of the property to assign.
+ * @param {*} value The value to assign.
+ */function assignMergeValue(object,key,value){if(value!==undefined$1&&!eq(object[key],value)||value===undefined$1&&!(key in object)){baseAssignValue(object,key,value);}}/**
+ * Assigns `value` to `key` of `object` if the existing value is not equivalent
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {string} key The key of the property to assign.
+ * @param {*} value The value to assign.
+ */function assignValue(object,key,value){var objValue=object[key];if(!(hasOwnProperty.call(object,key)&&eq(objValue,value))||value===undefined$1&&!(key in object)){baseAssignValue(object,key,value);}}/**
+ * Gets the index at which the `key` is found in `array` of key-value pairs.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {*} key The key to search for.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */function assocIndexOf(array,key){var length=array.length;while(length--){if(eq(array[length][0],key)){return length;}}return -1;}/**
+ * Aggregates elements of `collection` on `accumulator` with keys transformed
+ * by `iteratee` and values set by `setter`.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} setter The function to set `accumulator` values.
+ * @param {Function} iteratee The iteratee to transform keys.
+ * @param {Object} accumulator The initial aggregated object.
+ * @returns {Function} Returns `accumulator`.
+ */function baseAggregator(collection,setter,iteratee,accumulator){baseEach(collection,function(value,key,collection){setter(accumulator,value,iteratee(value),collection);});return accumulator;}/**
+ * The base implementation of `_.assign` without support for multiple sources
+ * or `customizer` functions.
+ *
+ * @private
+ * @param {Object} object The destination object.
+ * @param {Object} source The source object.
+ * @returns {Object} Returns `object`.
+ */function baseAssign(object,source){return object&©Object(source,keys(source),object);}/**
+ * The base implementation of `_.assignIn` without support for multiple sources
+ * or `customizer` functions.
+ *
+ * @private
+ * @param {Object} object The destination object.
+ * @param {Object} source The source object.
+ * @returns {Object} Returns `object`.
+ */function baseAssignIn(object,source){return object&©Object(source,keysIn(source),object);}/**
+ * The base implementation of `assignValue` and `assignMergeValue` without
+ * value checks.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {string} key The key of the property to assign.
+ * @param {*} value The value to assign.
+ */function baseAssignValue(object,key,value){if(key=='__proto__'&&defineProperty){defineProperty(object,key,{'configurable':true,'enumerable':true,'value':value,'writable':true});}else {object[key]=value;}}/**
+ * The base implementation of `_.at` without support for individual paths.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {string[]} paths The property paths to pick.
+ * @returns {Array} Returns the picked elements.
+ */function baseAt(object,paths){var index=-1,length=paths.length,result=Array(length),skip=object==null;while(++index<length){result[index]=skip?undefined$1:get(object,paths[index]);}return result;}/**
+ * The base implementation of `_.clamp` which doesn't coerce arguments.
+ *
+ * @private
+ * @param {number} number The number to clamp.
+ * @param {number} [lower] The lower bound.
+ * @param {number} upper The upper bound.
+ * @returns {number} Returns the clamped number.
+ */function baseClamp(number,lower,upper){if(number===number){if(upper!==undefined$1){number=number<=upper?number:upper;}if(lower!==undefined$1){number=number>=lower?number:lower;}}return number;}/**
+ * The base implementation of `_.clone` and `_.cloneDeep` which tracks
+ * traversed objects.
+ *
+ * @private
+ * @param {*} value The value to clone.
+ * @param {boolean} bitmask The bitmask flags.
+ * 1 - Deep clone
+ * 2 - Flatten inherited properties
+ * 4 - Clone symbols
+ * @param {Function} [customizer] The function to customize cloning.
+ * @param {string} [key] The key of `value`.
+ * @param {Object} [object] The parent object of `value`.
+ * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
+ * @returns {*} Returns the cloned value.
+ */function baseClone(value,bitmask,customizer,key,object,stack){var result,isDeep=bitmask&CLONE_DEEP_FLAG,isFlat=bitmask&CLONE_FLAT_FLAG,isFull=bitmask&CLONE_SYMBOLS_FLAG;if(customizer){result=object?customizer(value,key,object,stack):customizer(value);}if(result!==undefined$1){return result;}if(!isObject(value)){return value;}var isArr=isArray(value);if(isArr){result=initCloneArray(value);if(!isDeep){return copyArray(value,result);}}else {var tag=getTag(value),isFunc=tag==funcTag||tag==genTag;if(isBuffer(value)){return cloneBuffer(value,isDeep);}if(tag==objectTag||tag==argsTag||isFunc&&!object){result=isFlat||isFunc?{}:initCloneObject(value);if(!isDeep){return isFlat?copySymbolsIn(value,baseAssignIn(result,value)):copySymbols(value,baseAssign(result,value));}}else {if(!cloneableTags[tag]){return object?value:{};}result=initCloneByTag(value,tag,isDeep);}}// Check for circular references and return its corresponding clone.
+stack||(stack=new Stack());var stacked=stack.get(value);if(stacked){return stacked;}stack.set(value,result);if(isSet(value)){value.forEach(function(subValue){result.add(baseClone(subValue,bitmask,customizer,subValue,value,stack));});}else if(isMap(value)){value.forEach(function(subValue,key){result.set(key,baseClone(subValue,bitmask,customizer,key,value,stack));});}var keysFunc=isFull?isFlat?getAllKeysIn:getAllKeys:isFlat?keysIn:keys;var props=isArr?undefined$1:keysFunc(value);arrayEach(props||value,function(subValue,key){if(props){key=subValue;subValue=value[key];}// Recursively populate clone (susceptible to call stack limits).
+assignValue(result,key,baseClone(subValue,bitmask,customizer,key,value,stack));});return result;}/**
+ * The base implementation of `_.conforms` which doesn't clone `source`.
+ *
+ * @private
+ * @param {Object} source The object of property predicates to conform to.
+ * @returns {Function} Returns the new spec function.
+ */function baseConforms(source){var props=keys(source);return function(object){return baseConformsTo(object,source,props);};}/**
+ * The base implementation of `_.conformsTo` which accepts `props` to check.
+ *
+ * @private
+ * @param {Object} object The object to inspect.
+ * @param {Object} source The object of property predicates to conform to.
+ * @returns {boolean} Returns `true` if `object` conforms, else `false`.
+ */function baseConformsTo(object,source,props){var length=props.length;if(object==null){return !length;}object=Object(object);while(length--){var key=props[length],predicate=source[key],value=object[key];if(value===undefined$1&&!(key in object)||!predicate(value)){return false;}}return true;}/**
+ * The base implementation of `_.delay` and `_.defer` which accepts `args`
+ * to provide to `func`.
+ *
+ * @private
+ * @param {Function} func The function to delay.
+ * @param {number} wait The number of milliseconds to delay invocation.
+ * @param {Array} args The arguments to provide to `func`.
+ * @returns {number|Object} Returns the timer id or timeout object.
+ */function baseDelay(func,wait,args){if(typeof func!='function'){throw new TypeError(FUNC_ERROR_TEXT);}return setTimeout(function(){func.apply(undefined$1,args);},wait);}/**
+ * The base implementation of methods like `_.difference` without support
+ * for excluding multiple arrays or iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {Array} values The values to exclude.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of filtered values.
+ */function baseDifference(array,values,iteratee,comparator){var index=-1,includes=arrayIncludes,isCommon=true,length=array.length,result=[],valuesLength=values.length;if(!length){return result;}if(iteratee){values=arrayMap(values,baseUnary(iteratee));}if(comparator){includes=arrayIncludesWith;isCommon=false;}else if(values.length>=LARGE_ARRAY_SIZE){includes=cacheHas;isCommon=false;values=new SetCache(values);}outer:while(++index<length){var value=array[index],computed=iteratee==null?value:iteratee(value);value=comparator||value!==0?value:0;if(isCommon&&computed===computed){var valuesIndex=valuesLength;while(valuesIndex--){if(values[valuesIndex]===computed){continue outer;}}result.push(value);}else if(!includes(values,computed,comparator)){result.push(value);}}return result;}/**
+ * The base implementation of `_.forEach` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array|Object} Returns `collection`.
+ */var baseEach=createBaseEach(baseForOwn);/**
+ * The base implementation of `_.forEachRight` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array|Object} Returns `collection`.
+ */var baseEachRight=createBaseEach(baseForOwnRight,true);/**
+ * The base implementation of `_.every` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {boolean} Returns `true` if all elements pass the predicate check,
+ * else `false`
+ */function baseEvery(collection,predicate){var result=true;baseEach(collection,function(value,index,collection){result=!!predicate(value,index,collection);return result;});return result;}/**
+ * The base implementation of methods like `_.max` and `_.min` which accepts a
+ * `comparator` to determine the extremum value.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The iteratee invoked per iteration.
+ * @param {Function} comparator The comparator used to compare values.
+ * @returns {*} Returns the extremum value.
+ */function baseExtremum(array,iteratee,comparator){var index=-1,length=array.length;while(++index<length){var value=array[index],current=iteratee(value);if(current!=null&&(computed===undefined$1?current===current&&!isSymbol(current):comparator(current,computed))){var computed=current,result=value;}}return result;}/**
+ * The base implementation of `_.fill` without an iteratee call guard.
+ *
+ * @private
+ * @param {Array} array The array to fill.
+ * @param {*} value The value to fill `array` with.
+ * @param {number} [start=0] The start position.
+ * @param {number} [end=array.length] The end position.
+ * @returns {Array} Returns `array`.
+ */function baseFill(array,value,start,end){var length=array.length;start=toInteger(start);if(start<0){start=-start>length?0:length+start;}end=end===undefined$1||end>length?length:toInteger(end);if(end<0){end+=length;}end=start>end?0:toLength(end);while(start<end){array[start++]=value;}return array;}/**
+ * The base implementation of `_.filter` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {Array} Returns the new filtered array.
+ */function baseFilter(collection,predicate){var result=[];baseEach(collection,function(value,index,collection){if(predicate(value,index,collection)){result.push(value);}});return result;}/**
+ * The base implementation of `_.flatten` with support for restricting flattening.
+ *
+ * @private
+ * @param {Array} array The array to flatten.
+ * @param {number} depth The maximum recursion depth.
+ * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
+ * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
+ * @param {Array} [result=[]] The initial result value.
+ * @returns {Array} Returns the new flattened array.
+ */function baseFlatten(array,depth,predicate,isStrict,result){var index=-1,length=array.length;predicate||(predicate=isFlattenable);result||(result=[]);while(++index<length){var value=array[index];if(depth>0&&predicate(value)){if(depth>1){// Recursively flatten arrays (susceptible to call stack limits).
+baseFlatten(value,depth-1,predicate,isStrict,result);}else {arrayPush(result,value);}}else if(!isStrict){result[result.length]=value;}}return result;}/**
+ * The base implementation of `baseForOwn` which iterates over `object`
+ * properties returned by `keysFunc` and invokes `iteratee` for each property.
+ * Iteratee functions may exit iteration early by explicitly returning `false`.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {Function} keysFunc The function to get the keys of `object`.
+ * @returns {Object} Returns `object`.
+ */var baseFor=createBaseFor();/**
+ * This function is like `baseFor` except that it iterates over properties
+ * in the opposite order.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {Function} keysFunc The function to get the keys of `object`.
+ * @returns {Object} Returns `object`.
+ */var baseForRight=createBaseFor(true);/**
+ * The base implementation of `_.forOwn` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ */function baseForOwn(object,iteratee){return object&&baseFor(object,iteratee,keys);}/**
+ * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ */function baseForOwnRight(object,iteratee){return object&&baseForRight(object,iteratee,keys);}/**
+ * The base implementation of `_.functions` which creates an array of
+ * `object` function property names filtered from `props`.
+ *
+ * @private
+ * @param {Object} object The object to inspect.
+ * @param {Array} props The property names to filter.
+ * @returns {Array} Returns the function names.
+ */function baseFunctions(object,props){return arrayFilter(props,function(key){return isFunction(object[key]);});}/**
+ * The base implementation of `_.get` without support for default values.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the property to get.
+ * @returns {*} Returns the resolved value.
+ */function baseGet(object,path){path=castPath(path,object);var index=0,length=path.length;while(object!=null&&index<length){object=object[toKey(path[index++])];}return index&&index==length?object:undefined$1;}/**
+ * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
+ * `keysFunc` and `symbolsFunc` to get the enumerable property names and
+ * symbols of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Function} keysFunc The function to get the keys of `object`.
+ * @param {Function} symbolsFunc The function to get the symbols of `object`.
+ * @returns {Array} Returns the array of property names and symbols.
+ */function baseGetAllKeys(object,keysFunc,symbolsFunc){var result=keysFunc(object);return isArray(object)?result:arrayPush(result,symbolsFunc(object));}/**
+ * The base implementation of `getTag` without fallbacks for buggy environments.
+ *
+ * @private
+ * @param {*} value The value to query.
+ * @returns {string} Returns the `toStringTag`.
+ */function baseGetTag(value){if(value==null){return value===undefined$1?undefinedTag:nullTag;}return symToStringTag&&symToStringTag in Object(value)?getRawTag(value):objectToString(value);}/**
+ * The base implementation of `_.gt` which doesn't coerce arguments.
+ *
+ * @private
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if `value` is greater than `other`,
+ * else `false`.
+ */function baseGt(value,other){return value>other;}/**
+ * The base implementation of `_.has` without support for deep paths.
+ *
+ * @private
+ * @param {Object} [object] The object to query.
+ * @param {Array|string} key The key to check.
+ * @returns {boolean} Returns `true` if `key` exists, else `false`.
+ */function baseHas(object,key){return object!=null&&hasOwnProperty.call(object,key);}/**
+ * The base implementation of `_.hasIn` without support for deep paths.
+ *
+ * @private
+ * @param {Object} [object] The object to query.
+ * @param {Array|string} key The key to check.
+ * @returns {boolean} Returns `true` if `key` exists, else `false`.
+ */function baseHasIn(object,key){return object!=null&&key in Object(object);}/**
+ * The base implementation of `_.inRange` which doesn't coerce arguments.
+ *
+ * @private
+ * @param {number} number The number to check.
+ * @param {number} start The start of the range.
+ * @param {number} end The end of the range.
+ * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
+ */function baseInRange(number,start,end){return number>=nativeMin(start,end)&&number<nativeMax(start,end);}/**
+ * The base implementation of methods like `_.intersection`, without support
+ * for iteratee shorthands, that accepts an array of arrays to inspect.
+ *
+ * @private
+ * @param {Array} arrays The arrays to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of shared values.
+ */function baseIntersection(arrays,iteratee,comparator){var includes=comparator?arrayIncludesWith:arrayIncludes,length=arrays[0].length,othLength=arrays.length,othIndex=othLength,caches=Array(othLength),maxLength=Infinity,result=[];while(othIndex--){var array=arrays[othIndex];if(othIndex&&iteratee){array=arrayMap(array,baseUnary(iteratee));}maxLength=nativeMin(array.length,maxLength);caches[othIndex]=!comparator&&(iteratee||length>=120&&array.length>=120)?new SetCache(othIndex&&array):undefined$1;}array=arrays[0];var index=-1,seen=caches[0];outer:while(++index<length&&result.length<maxLength){var value=array[index],computed=iteratee?iteratee(value):value;value=comparator||value!==0?value:0;if(!(seen?cacheHas(seen,computed):includes(result,computed,comparator))){othIndex=othLength;while(--othIndex){var cache=caches[othIndex];if(!(cache?cacheHas(cache,computed):includes(arrays[othIndex],computed,comparator))){continue outer;}}if(seen){seen.push(computed);}result.push(value);}}return result;}/**
+ * The base implementation of `_.invert` and `_.invertBy` which inverts
+ * `object` with values transformed by `iteratee` and set by `setter`.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} setter The function to set `accumulator` values.
+ * @param {Function} iteratee The iteratee to transform values.
+ * @param {Object} accumulator The initial inverted object.
+ * @returns {Function} Returns `accumulator`.
+ */function baseInverter(object,setter,iteratee,accumulator){baseForOwn(object,function(value,key,object){setter(accumulator,iteratee(value),key,object);});return accumulator;}/**
+ * The base implementation of `_.invoke` without support for individual
+ * method arguments.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the method to invoke.
+ * @param {Array} args The arguments to invoke the method with.
+ * @returns {*} Returns the result of the invoked method.
+ */function baseInvoke(object,path,args){path=castPath(path,object);object=parent(object,path);var func=object==null?object:object[toKey(last(path))];return func==null?undefined$1:apply(func,object,args);}/**
+ * The base implementation of `_.isArguments`.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an `arguments` object,
+ */function baseIsArguments(value){return isObjectLike(value)&&baseGetTag(value)==argsTag;}/**
+ * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
+ */function baseIsArrayBuffer(value){return isObjectLike(value)&&baseGetTag(value)==arrayBufferTag;}/**
+ * The base implementation of `_.isDate` without Node.js optimizations.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
+ */function baseIsDate(value){return isObjectLike(value)&&baseGetTag(value)==dateTag;}/**
+ * The base implementation of `_.isEqual` which supports partial comparisons
+ * and tracks traversed objects.
+ *
+ * @private
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @param {boolean} bitmask The bitmask flags.
+ * 1 - Unordered comparison
+ * 2 - Partial comparison
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {Object} [stack] Tracks traversed `value` and `other` objects.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ */function baseIsEqual(value,other,bitmask,customizer,stack){if(value===other){return true;}if(value==null||other==null||!isObjectLike(value)&&!isObjectLike(other)){return value!==value&&other!==other;}return baseIsEqualDeep(value,other,bitmask,customizer,baseIsEqual,stack);}/**
+ * A specialized version of `baseIsEqual` for arrays and objects which performs
+ * deep comparisons and tracks traversed objects enabling objects with circular
+ * references to be compared.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
+ * @param {Function} customizer The function to customize comparisons.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Object} [stack] Tracks traversed `object` and `other` objects.
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+ */function baseIsEqualDeep(object,other,bitmask,customizer,equalFunc,stack){var objIsArr=isArray(object),othIsArr=isArray(other),objTag=objIsArr?arrayTag:getTag(object),othTag=othIsArr?arrayTag:getTag(other);objTag=objTag==argsTag?objectTag:objTag;othTag=othTag==argsTag?objectTag:othTag;var objIsObj=objTag==objectTag,othIsObj=othTag==objectTag,isSameTag=objTag==othTag;if(isSameTag&&isBuffer(object)){if(!isBuffer(other)){return false;}objIsArr=true;objIsObj=false;}if(isSameTag&&!objIsObj){stack||(stack=new Stack());return objIsArr||isTypedArray(object)?equalArrays(object,other,bitmask,customizer,equalFunc,stack):equalByTag(object,other,objTag,bitmask,customizer,equalFunc,stack);}if(!(bitmask&COMPARE_PARTIAL_FLAG)){var objIsWrapped=objIsObj&&hasOwnProperty.call(object,'__wrapped__'),othIsWrapped=othIsObj&&hasOwnProperty.call(other,'__wrapped__');if(objIsWrapped||othIsWrapped){var objUnwrapped=objIsWrapped?object.value():object,othUnwrapped=othIsWrapped?other.value():other;stack||(stack=new Stack());return equalFunc(objUnwrapped,othUnwrapped,bitmask,customizer,stack);}}if(!isSameTag){return false;}stack||(stack=new Stack());return equalObjects(object,other,bitmask,customizer,equalFunc,stack);}/**
+ * The base implementation of `_.isMap` without Node.js optimizations.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a map, else `false`.
+ */function baseIsMap(value){return isObjectLike(value)&&getTag(value)==mapTag;}/**
+ * The base implementation of `_.isMatch` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Object} object The object to inspect.
+ * @param {Object} source The object of property values to match.
+ * @param {Array} matchData The property names, values, and compare flags to match.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @returns {boolean} Returns `true` if `object` is a match, else `false`.
+ */function baseIsMatch(object,source,matchData,customizer){var index=matchData.length,length=index,noCustomizer=!customizer;if(object==null){return !length;}object=Object(object);while(index--){var data=matchData[index];if(noCustomizer&&data[2]?data[1]!==object[data[0]]:!(data[0]in object)){return false;}}while(++index<length){data=matchData[index];var key=data[0],objValue=object[key],srcValue=data[1];if(noCustomizer&&data[2]){if(objValue===undefined$1&&!(key in object)){return false;}}else {var stack=new Stack();if(customizer){var result=customizer(objValue,srcValue,key,object,source,stack);}if(!(result===undefined$1?baseIsEqual(srcValue,objValue,COMPARE_PARTIAL_FLAG|COMPARE_UNORDERED_FLAG,customizer,stack):result)){return false;}}}return true;}/**
+ * The base implementation of `_.isNative` without bad shim checks.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a native function,
+ * else `false`.
+ */function baseIsNative(value){if(!isObject(value)||isMasked(value)){return false;}var pattern=isFunction(value)?reIsNative:reIsHostCtor;return pattern.test(toSource(value));}/**
+ * The base implementation of `_.isRegExp` without Node.js optimizations.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
+ */function baseIsRegExp(value){return isObjectLike(value)&&baseGetTag(value)==regexpTag;}/**
+ * The base implementation of `_.isSet` without Node.js optimizations.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a set, else `false`.
+ */function baseIsSet(value){return isObjectLike(value)&&getTag(value)==setTag;}/**
+ * The base implementation of `_.isTypedArray` without Node.js optimizations.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
+ */function baseIsTypedArray(value){return isObjectLike(value)&&isLength(value.length)&&!!typedArrayTags[baseGetTag(value)];}/**
+ * The base implementation of `_.iteratee`.
+ *
+ * @private
+ * @param {*} [value=_.identity] The value to convert to an iteratee.
+ * @returns {Function} Returns the iteratee.
+ */function baseIteratee(value){// Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
+// See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
+if(typeof value=='function'){return value;}if(value==null){return identity;}if(typeof value=='object'){return isArray(value)?baseMatchesProperty(value[0],value[1]):baseMatches(value);}return property(value);}/**
+ * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */function baseKeys(object){if(!isPrototype(object)){return nativeKeys(object);}var result=[];for(var key in Object(object)){if(hasOwnProperty.call(object,key)&&key!='constructor'){result.push(key);}}return result;}/**
+ * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */function baseKeysIn(object){if(!isObject(object)){return nativeKeysIn(object);}var isProto=isPrototype(object),result=[];for(var key in object){if(!(key=='constructor'&&(isProto||!hasOwnProperty.call(object,key)))){result.push(key);}}return result;}/**
+ * The base implementation of `_.lt` which doesn't coerce arguments.
+ *
+ * @private
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if `value` is less than `other`,
+ * else `false`.
+ */function baseLt(value,other){return value<other;}/**
+ * The base implementation of `_.map` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the new mapped array.
+ */function baseMap(collection,iteratee){var index=-1,result=isArrayLike(collection)?Array(collection.length):[];baseEach(collection,function(value,key,collection){result[++index]=iteratee(value,key,collection);});return result;}/**
+ * The base implementation of `_.matches` which doesn't clone `source`.
+ *
+ * @private
+ * @param {Object} source The object of property values to match.
+ * @returns {Function} Returns the new spec function.
+ */function baseMatches(source){var matchData=getMatchData(source);if(matchData.length==1&&matchData[0][2]){return matchesStrictComparable(matchData[0][0],matchData[0][1]);}return function(object){return object===source||baseIsMatch(object,source,matchData);};}/**
+ * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
+ *
+ * @private
+ * @param {string} path The path of the property to get.
+ * @param {*} srcValue The value to match.
+ * @returns {Function} Returns the new spec function.
+ */function baseMatchesProperty(path,srcValue){if(isKey(path)&&isStrictComparable(srcValue)){return matchesStrictComparable(toKey(path),srcValue);}return function(object){var objValue=get(object,path);return objValue===undefined$1&&objValue===srcValue?hasIn(object,path):baseIsEqual(srcValue,objValue,COMPARE_PARTIAL_FLAG|COMPARE_UNORDERED_FLAG);};}/**
+ * The base implementation of `_.merge` without support for multiple sources.
+ *
+ * @private
+ * @param {Object} object The destination object.
+ * @param {Object} source The source object.
+ * @param {number} srcIndex The index of `source`.
+ * @param {Function} [customizer] The function to customize merged values.
+ * @param {Object} [stack] Tracks traversed source values and their merged
+ * counterparts.
+ */function baseMerge(object,source,srcIndex,customizer,stack){if(object===source){return;}baseFor(source,function(srcValue,key){stack||(stack=new Stack());if(isObject(srcValue)){baseMergeDeep(object,source,key,srcIndex,baseMerge,customizer,stack);}else {var newValue=customizer?customizer(safeGet(object,key),srcValue,key+'',object,source,stack):undefined$1;if(newValue===undefined$1){newValue=srcValue;}assignMergeValue(object,key,newValue);}},keysIn);}/**
+ * A specialized version of `baseMerge` for arrays and objects which performs
+ * deep merges and tracks traversed objects enabling objects with circular
+ * references to be merged.
+ *
+ * @private
+ * @param {Object} object The destination object.
+ * @param {Object} source The source object.
+ * @param {string} key The key of the value to merge.
+ * @param {number} srcIndex The index of `source`.
+ * @param {Function} mergeFunc The function to merge values.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @param {Object} [stack] Tracks traversed source values and their merged
+ * counterparts.
+ */function baseMergeDeep(object,source,key,srcIndex,mergeFunc,customizer,stack){var objValue=safeGet(object,key),srcValue=safeGet(source,key),stacked=stack.get(srcValue);if(stacked){assignMergeValue(object,key,stacked);return;}var newValue=customizer?customizer(objValue,srcValue,key+'',object,source,stack):undefined$1;var isCommon=newValue===undefined$1;if(isCommon){var isArr=isArray(srcValue),isBuff=!isArr&&isBuffer(srcValue),isTyped=!isArr&&!isBuff&&isTypedArray(srcValue);newValue=srcValue;if(isArr||isBuff||isTyped){if(isArray(objValue)){newValue=objValue;}else if(isArrayLikeObject(objValue)){newValue=copyArray(objValue);}else if(isBuff){isCommon=false;newValue=cloneBuffer(srcValue,true);}else if(isTyped){isCommon=false;newValue=cloneTypedArray(srcValue,true);}else {newValue=[];}}else if(isPlainObject(srcValue)||isArguments(srcValue)){newValue=objValue;if(isArguments(objValue)){newValue=toPlainObject(objValue);}else if(!isObject(objValue)||isFunction(objValue)){newValue=initCloneObject(srcValue);}}else {isCommon=false;}}if(isCommon){// Recursively merge objects and arrays (susceptible to call stack limits).
+stack.set(srcValue,newValue);mergeFunc(newValue,srcValue,srcIndex,customizer,stack);stack['delete'](srcValue);}assignMergeValue(object,key,newValue);}/**
+ * The base implementation of `_.nth` which doesn't coerce arguments.
+ *
+ * @private
+ * @param {Array} array The array to query.
+ * @param {number} n The index of the element to return.
+ * @returns {*} Returns the nth element of `array`.
+ */function baseNth(array,n){var length=array.length;if(!length){return;}n+=n<0?length:0;return isIndex(n,length)?array[n]:undefined$1;}/**
+ * The base implementation of `_.orderBy` without param guards.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
+ * @param {string[]} orders The sort orders of `iteratees`.
+ * @returns {Array} Returns the new sorted array.
+ */function baseOrderBy(collection,iteratees,orders){if(iteratees.length){iteratees=arrayMap(iteratees,function(iteratee){if(isArray(iteratee)){return function(value){return baseGet(value,iteratee.length===1?iteratee[0]:iteratee);};}return iteratee;});}else {iteratees=[identity];}var index=-1;iteratees=arrayMap(iteratees,baseUnary(getIteratee()));var result=baseMap(collection,function(value,key,collection){var criteria=arrayMap(iteratees,function(iteratee){return iteratee(value);});return {'criteria':criteria,'index':++index,'value':value};});return baseSortBy(result,function(object,other){return compareMultiple(object,other,orders);});}/**
+ * The base implementation of `_.pick` without support for individual
+ * property identifiers.
+ *
+ * @private
+ * @param {Object} object The source object.
+ * @param {string[]} paths The property paths to pick.
+ * @returns {Object} Returns the new object.
+ */function basePick(object,paths){return basePickBy(object,paths,function(value,path){return hasIn(object,path);});}/**
+ * The base implementation of `_.pickBy` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Object} object The source object.
+ * @param {string[]} paths The property paths to pick.
+ * @param {Function} predicate The function invoked per property.
+ * @returns {Object} Returns the new object.
+ */function basePickBy(object,paths,predicate){var index=-1,length=paths.length,result={};while(++index<length){var path=paths[index],value=baseGet(object,path);if(predicate(value,path)){baseSet(result,castPath(path,object),value);}}return result;}/**
+ * A specialized version of `baseProperty` which supports deep paths.
+ *
+ * @private
+ * @param {Array|string} path The path of the property to get.
+ * @returns {Function} Returns the new accessor function.
+ */function basePropertyDeep(path){return function(object){return baseGet(object,path);};}/**
+ * The base implementation of `_.pullAllBy` without support for iteratee
+ * shorthands.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to remove.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns `array`.
+ */function basePullAll(array,values,iteratee,comparator){var indexOf=comparator?baseIndexOfWith:baseIndexOf,index=-1,length=values.length,seen=array;if(array===values){values=copyArray(values);}if(iteratee){seen=arrayMap(array,baseUnary(iteratee));}while(++index<length){var fromIndex=0,value=values[index],computed=iteratee?iteratee(value):value;while((fromIndex=indexOf(seen,computed,fromIndex,comparator))>-1){if(seen!==array){splice.call(seen,fromIndex,1);}splice.call(array,fromIndex,1);}}return array;}/**
+ * The base implementation of `_.pullAt` without support for individual
+ * indexes or capturing the removed elements.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {number[]} indexes The indexes of elements to remove.
+ * @returns {Array} Returns `array`.
+ */function basePullAt(array,indexes){var length=array?indexes.length:0,lastIndex=length-1;while(length--){var index=indexes[length];if(length==lastIndex||index!==previous){var previous=index;if(isIndex(index)){splice.call(array,index,1);}else {baseUnset(array,index);}}}return array;}/**
+ * The base implementation of `_.random` without support for returning
+ * floating-point numbers.
+ *
+ * @private
+ * @param {number} lower The lower bound.
+ * @param {number} upper The upper bound.
+ * @returns {number} Returns the random number.
+ */function baseRandom(lower,upper){return lower+nativeFloor(nativeRandom()*(upper-lower+1));}/**
+ * The base implementation of `_.range` and `_.rangeRight` which doesn't
+ * coerce arguments.
+ *
+ * @private
+ * @param {number} start The start of the range.
+ * @param {number} end The end of the range.
+ * @param {number} step The value to increment or decrement by.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Array} Returns the range of numbers.
+ */function baseRange(start,end,step,fromRight){var index=-1,length=nativeMax(nativeCeil((end-start)/(step||1)),0),result=Array(length);while(length--){result[fromRight?length:++index]=start;start+=step;}return result;}/**
+ * The base implementation of `_.repeat` which doesn't coerce arguments.
+ *
+ * @private
+ * @param {string} string The string to repeat.
+ * @param {number} n The number of times to repeat the string.
+ * @returns {string} Returns the repeated string.
+ */function baseRepeat(string,n){var result='';if(!string||n<1||n>MAX_SAFE_INTEGER){return result;}// Leverage the exponentiation by squaring algorithm for a faster repeat.
+// See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
+do{if(n%2){result+=string;}n=nativeFloor(n/2);if(n){string+=string;}}while(n);return result;}/**
+ * The base implementation of `_.rest` which doesn't validate or coerce arguments.
+ *
+ * @private
+ * @param {Function} func The function to apply a rest parameter to.
+ * @param {number} [start=func.length-1] The start position of the rest parameter.
+ * @returns {Function} Returns the new function.
+ */function baseRest(func,start){return setToString(overRest(func,start,identity),func+'');}/**
+ * The base implementation of `_.sample`.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to sample.
+ * @returns {*} Returns the random element.
+ */function baseSample(collection){return arraySample(values(collection));}/**
+ * The base implementation of `_.sampleSize` without param guards.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to sample.
+ * @param {number} n The number of elements to sample.
+ * @returns {Array} Returns the random elements.
+ */function baseSampleSize(collection,n){var array=values(collection);return shuffleSelf(array,baseClamp(n,0,array.length));}/**
+ * The base implementation of `_.set`.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to set.
+ * @param {*} value The value to set.
+ * @param {Function} [customizer] The function to customize path creation.
+ * @returns {Object} Returns `object`.
+ */function baseSet(object,path,value,customizer){if(!isObject(object)){return object;}path=castPath(path,object);var index=-1,length=path.length,lastIndex=length-1,nested=object;while(nested!=null&&++index<length){var key=toKey(path[index]),newValue=value;if(key==='__proto__'||key==='constructor'||key==='prototype'){return object;}if(index!=lastIndex){var objValue=nested[key];newValue=customizer?customizer(objValue,key,nested):undefined$1;if(newValue===undefined$1){newValue=isObject(objValue)?objValue:isIndex(path[index+1])?[]:{};}}assignValue(nested,key,newValue);nested=nested[key];}return object;}/**
+ * The base implementation of `setData` without support for hot loop shorting.
+ *
+ * @private
+ * @param {Function} func The function to associate metadata with.
+ * @param {*} data The metadata.
+ * @returns {Function} Returns `func`.
+ */var baseSetData=!metaMap?identity:function(func,data){metaMap.set(func,data);return func;};/**
+ * The base implementation of `setToString` without support for hot loop shorting.
+ *
+ * @private
+ * @param {Function} func The function to modify.
+ * @param {Function} string The `toString` result.
+ * @returns {Function} Returns `func`.
+ */var baseSetToString=!defineProperty?identity:function(func,string){return defineProperty(func,'toString',{'configurable':true,'enumerable':false,'value':constant(string),'writable':true});};/**
+ * The base implementation of `_.shuffle`.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to shuffle.
+ * @returns {Array} Returns the new shuffled array.
+ */function baseShuffle(collection){return shuffleSelf(values(collection));}/**
+ * The base implementation of `_.slice` without an iteratee call guard.
+ *
+ * @private
+ * @param {Array} array The array to slice.
+ * @param {number} [start=0] The start position.
+ * @param {number} [end=array.length] The end position.
+ * @returns {Array} Returns the slice of `array`.
+ */function baseSlice(array,start,end){var index=-1,length=array.length;if(start<0){start=-start>length?0:length+start;}end=end>length?length:end;if(end<0){end+=length;}length=start>end?0:end-start>>>0;start>>>=0;var result=Array(length);while(++index<length){result[index]=array[index+start];}return result;}/**
+ * The base implementation of `_.some` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {boolean} Returns `true` if any element passes the predicate check,
+ * else `false`.
+ */function baseSome(collection,predicate){var result;baseEach(collection,function(value,index,collection){result=predicate(value,index,collection);return !result;});return !!result;}/**
+ * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
+ * performs a binary search of `array` to determine the index at which `value`
+ * should be inserted into `array` in order to maintain its sort order.
+ *
+ * @private
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @param {boolean} [retHighest] Specify returning the highest qualified index.
+ * @returns {number} Returns the index at which `value` should be inserted
+ * into `array`.
+ */function baseSortedIndex(array,value,retHighest){var low=0,high=array==null?low:array.length;if(typeof value=='number'&&value===value&&high<=HALF_MAX_ARRAY_LENGTH){while(low<high){var mid=low+high>>>1,computed=array[mid];if(computed!==null&&!isSymbol(computed)&&(retHighest?computed<=value:computed<value)){low=mid+1;}else {high=mid;}}return high;}return baseSortedIndexBy(array,value,identity,retHighest);}/**
+ * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
+ * which invokes `iteratee` for `value` and each element of `array` to compute
+ * their sort ranking. The iteratee is invoked with one argument; (value).
+ *
+ * @private
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @param {Function} iteratee The iteratee invoked per element.
+ * @param {boolean} [retHighest] Specify returning the highest qualified index.
+ * @returns {number} Returns the index at which `value` should be inserted
+ * into `array`.
+ */function baseSortedIndexBy(array,value,iteratee,retHighest){var low=0,high=array==null?0:array.length;if(high===0){return 0;}value=iteratee(value);var valIsNaN=value!==value,valIsNull=value===null,valIsSymbol=isSymbol(value),valIsUndefined=value===undefined$1;while(low<high){var mid=nativeFloor((low+high)/2),computed=iteratee(array[mid]),othIsDefined=computed!==undefined$1,othIsNull=computed===null,othIsReflexive=computed===computed,othIsSymbol=isSymbol(computed);if(valIsNaN){var setLow=retHighest||othIsReflexive;}else if(valIsUndefined){setLow=othIsReflexive&&(retHighest||othIsDefined);}else if(valIsNull){setLow=othIsReflexive&&othIsDefined&&(retHighest||!othIsNull);}else if(valIsSymbol){setLow=othIsReflexive&&othIsDefined&&!othIsNull&&(retHighest||!othIsSymbol);}else if(othIsNull||othIsSymbol){setLow=false;}else {setLow=retHighest?computed<=value:computed<value;}if(setLow){low=mid+1;}else {high=mid;}}return nativeMin(high,MAX_ARRAY_INDEX);}/**
+ * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
+ * support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ */function baseSortedUniq(array,iteratee){var index=-1,length=array.length,resIndex=0,result=[];while(++index<length){var value=array[index],computed=iteratee?iteratee(value):value;if(!index||!eq(computed,seen)){var seen=computed;result[resIndex++]=value===0?0:value;}}return result;}/**
+ * The base implementation of `_.toNumber` which doesn't ensure correct
+ * conversions of binary, hexadecimal, or octal string values.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {number} Returns the number.
+ */function baseToNumber(value){if(typeof value=='number'){return value;}if(isSymbol(value)){return NAN;}return +value;}/**
+ * The base implementation of `_.toString` which doesn't convert nullish
+ * values to empty strings.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {string} Returns the string.
+ */function baseToString(value){// Exit early for strings to avoid a performance hit in some environments.
+if(typeof value=='string'){return value;}if(isArray(value)){// Recursively convert values (susceptible to call stack limits).
+return arrayMap(value,baseToString)+'';}if(isSymbol(value)){return symbolToString?symbolToString.call(value):'';}var result=value+'';return result=='0'&&1/value==-INFINITY?'-0':result;}/**
+ * The base implementation of `_.uniqBy` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ */function baseUniq(array,iteratee,comparator){var index=-1,includes=arrayIncludes,length=array.length,isCommon=true,result=[],seen=result;if(comparator){isCommon=false;includes=arrayIncludesWith;}else if(length>=LARGE_ARRAY_SIZE){var set=iteratee?null:createSet(array);if(set){return setToArray(set);}isCommon=false;includes=cacheHas;seen=new SetCache();}else {seen=iteratee?[]:result;}outer:while(++index<length){var value=array[index],computed=iteratee?iteratee(value):value;value=comparator||value!==0?value:0;if(isCommon&&computed===computed){var seenIndex=seen.length;while(seenIndex--){if(seen[seenIndex]===computed){continue outer;}}if(iteratee){seen.push(computed);}result.push(value);}else if(!includes(seen,computed,comparator)){if(seen!==result){seen.push(computed);}result.push(value);}}return result;}/**
+ * The base implementation of `_.unset`.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The property path to unset.
+ * @returns {boolean} Returns `true` if the property is deleted, else `false`.
+ */function baseUnset(object,path){path=castPath(path,object);object=parent(object,path);return object==null||delete object[toKey(last(path))];}/**
+ * The base implementation of `_.update`.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to update.
+ * @param {Function} updater The function to produce the updated value.
+ * @param {Function} [customizer] The function to customize path creation.
+ * @returns {Object} Returns `object`.
+ */function baseUpdate(object,path,updater,customizer){return baseSet(object,path,updater(baseGet(object,path)),customizer);}/**
+ * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
+ * without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to query.
+ * @param {Function} predicate The function invoked per iteration.
+ * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Array} Returns the slice of `array`.
+ */function baseWhile(array,predicate,isDrop,fromRight){var length=array.length,index=fromRight?length:-1;while((fromRight?index--:++index<length)&&predicate(array[index],index,array)){}return isDrop?baseSlice(array,fromRight?0:index,fromRight?index+1:length):baseSlice(array,fromRight?index+1:0,fromRight?length:index);}/**
+ * The base implementation of `wrapperValue` which returns the result of
+ * performing a sequence of actions on the unwrapped `value`, where each
+ * successive action is supplied the return value of the previous.
+ *
+ * @private
+ * @param {*} value The unwrapped value.
+ * @param {Array} actions Actions to perform to resolve the unwrapped value.
+ * @returns {*} Returns the resolved value.
+ */function baseWrapperValue(value,actions){var result=value;if(result instanceof LazyWrapper){result=result.value();}return arrayReduce(actions,function(result,action){return action.func.apply(action.thisArg,arrayPush([result],action.args));},result);}/**
+ * The base implementation of methods like `_.xor`, without support for
+ * iteratee shorthands, that accepts an array of arrays to inspect.
+ *
+ * @private
+ * @param {Array} arrays The arrays to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of values.
+ */function baseXor(arrays,iteratee,comparator){var length=arrays.length;if(length<2){return length?baseUniq(arrays[0]):[];}var index=-1,result=Array(length);while(++index<length){var array=arrays[index],othIndex=-1;while(++othIndex<length){if(othIndex!=index){result[index]=baseDifference(result[index]||array,arrays[othIndex],iteratee,comparator);}}}return baseUniq(baseFlatten(result,1),iteratee,comparator);}/**
+ * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
+ *
+ * @private
+ * @param {Array} props The property identifiers.
+ * @param {Array} values The property values.
+ * @param {Function} assignFunc The function to assign values.
+ * @returns {Object} Returns the new object.
+ */function baseZipObject(props,values,assignFunc){var index=-1,length=props.length,valsLength=values.length,result={};while(++index<length){var value=index<valsLength?values[index]:undefined$1;assignFunc(result,props[index],value);}return result;}/**
+ * Casts `value` to an empty array if it's not an array like object.
+ *
+ * @private
+ * @param {*} value The value to inspect.
+ * @returns {Array|Object} Returns the cast array-like object.
+ */function castArrayLikeObject(value){return isArrayLikeObject(value)?value:[];}/**
+ * Casts `value` to `identity` if it's not a function.
+ *
+ * @private
+ * @param {*} value The value to inspect.
+ * @returns {Function} Returns cast function.
+ */function castFunction(value){return typeof value=='function'?value:identity;}/**
+ * Casts `value` to a path array if it's not one.
+ *
+ * @private
+ * @param {*} value The value to inspect.
+ * @param {Object} [object] The object to query keys on.
+ * @returns {Array} Returns the cast property path array.
+ */function castPath(value,object){if(isArray(value)){return value;}return isKey(value,object)?[value]:stringToPath(toString(value));}/**
+ * A `baseRest` alias which can be replaced with `identity` by module
+ * replacement plugins.
+ *
+ * @private
+ * @type {Function}
+ * @param {Function} func The function to apply a rest parameter to.
+ * @returns {Function} Returns the new function.
+ */var castRest=baseRest;/**
+ * Casts `array` to a slice if it's needed.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {number} start The start position.
+ * @param {number} [end=array.length] The end position.
+ * @returns {Array} Returns the cast slice.
+ */function castSlice(array,start,end){var length=array.length;end=end===undefined$1?length:end;return !start&&end>=length?array:baseSlice(array,start,end);}/**
+ * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
+ *
+ * @private
+ * @param {number|Object} id The timer id or timeout object of the timer to clear.
+ */var clearTimeout=ctxClearTimeout||function(id){return root.clearTimeout(id);};/**
+ * Creates a clone of `buffer`.
+ *
+ * @private
+ * @param {Buffer} buffer The buffer to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Buffer} Returns the cloned buffer.
+ */function cloneBuffer(buffer,isDeep){if(isDeep){return buffer.slice();}var length=buffer.length,result=allocUnsafe?allocUnsafe(length):new buffer.constructor(length);buffer.copy(result);return result;}/**
+ * Creates a clone of `arrayBuffer`.
+ *
+ * @private
+ * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
+ * @returns {ArrayBuffer} Returns the cloned array buffer.
+ */function cloneArrayBuffer(arrayBuffer){var result=new arrayBuffer.constructor(arrayBuffer.byteLength);new Uint8Array(result).set(new Uint8Array(arrayBuffer));return result;}/**
+ * Creates a clone of `dataView`.
+ *
+ * @private
+ * @param {Object} dataView The data view to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Object} Returns the cloned data view.
+ */function cloneDataView(dataView,isDeep){var buffer=isDeep?cloneArrayBuffer(dataView.buffer):dataView.buffer;return new dataView.constructor(buffer,dataView.byteOffset,dataView.byteLength);}/**
+ * Creates a clone of `regexp`.
+ *
+ * @private
+ * @param {Object} regexp The regexp to clone.
+ * @returns {Object} Returns the cloned regexp.
+ */function cloneRegExp(regexp){var result=new regexp.constructor(regexp.source,reFlags.exec(regexp));result.lastIndex=regexp.lastIndex;return result;}/**
+ * Creates a clone of the `symbol` object.
+ *
+ * @private
+ * @param {Object} symbol The symbol object to clone.
+ * @returns {Object} Returns the cloned symbol object.
+ */function cloneSymbol(symbol){return symbolValueOf?Object(symbolValueOf.call(symbol)):{};}/**
+ * Creates a clone of `typedArray`.
+ *
+ * @private
+ * @param {Object} typedArray The typed array to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Object} Returns the cloned typed array.
+ */function cloneTypedArray(typedArray,isDeep){var buffer=isDeep?cloneArrayBuffer(typedArray.buffer):typedArray.buffer;return new typedArray.constructor(buffer,typedArray.byteOffset,typedArray.length);}/**
+ * Compares values to sort them in ascending order.
+ *
+ * @private
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {number} Returns the sort order indicator for `value`.
+ */function compareAscending(value,other){if(value!==other){var valIsDefined=value!==undefined$1,valIsNull=value===null,valIsReflexive=value===value,valIsSymbol=isSymbol(value);var othIsDefined=other!==undefined$1,othIsNull=other===null,othIsReflexive=other===other,othIsSymbol=isSymbol(other);if(!othIsNull&&!othIsSymbol&&!valIsSymbol&&value>other||valIsSymbol&&othIsDefined&&othIsReflexive&&!othIsNull&&!othIsSymbol||valIsNull&&othIsDefined&&othIsReflexive||!valIsDefined&&othIsReflexive||!valIsReflexive){return 1;}if(!valIsNull&&!valIsSymbol&&!othIsSymbol&&value<other||othIsSymbol&&valIsDefined&&valIsReflexive&&!valIsNull&&!valIsSymbol||othIsNull&&valIsDefined&&valIsReflexive||!othIsDefined&&valIsReflexive||!othIsReflexive){return -1;}}return 0;}/**
+ * Used by `_.orderBy` to compare multiple properties of a value to another
+ * and stable sort them.
+ *
+ * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
+ * specify an order of "desc" for descending or "asc" for ascending sort order
+ * of corresponding values.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {boolean[]|string[]} orders The order to sort by for each property.
+ * @returns {number} Returns the sort order indicator for `object`.
+ */function compareMultiple(object,other,orders){var index=-1,objCriteria=object.criteria,othCriteria=other.criteria,length=objCriteria.length,ordersLength=orders.length;while(++index<length){var result=compareAscending(objCriteria[index],othCriteria[index]);if(result){if(index>=ordersLength){return result;}var order=orders[index];return result*(order=='desc'?-1:1);}}// Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
+// that causes it, under certain circumstances, to provide the same value for
+// `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
+// for more details.
+//
+// This also ensures a stable sort in V8 and other engines.
+// See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
+return object.index-other.index;}/**
+ * Creates an array that is the composition of partially applied arguments,
+ * placeholders, and provided arguments into a single array of arguments.
+ *
+ * @private
+ * @param {Array} args The provided arguments.
+ * @param {Array} partials The arguments to prepend to those provided.
+ * @param {Array} holders The `partials` placeholder indexes.
+ * @params {boolean} [isCurried] Specify composing for a curried function.
+ * @returns {Array} Returns the new array of composed arguments.
+ */function composeArgs(args,partials,holders,isCurried){var argsIndex=-1,argsLength=args.length,holdersLength=holders.length,leftIndex=-1,leftLength=partials.length,rangeLength=nativeMax(argsLength-holdersLength,0),result=Array(leftLength+rangeLength),isUncurried=!isCurried;while(++leftIndex<leftLength){result[leftIndex]=partials[leftIndex];}while(++argsIndex<holdersLength){if(isUncurried||argsIndex<argsLength){result[holders[argsIndex]]=args[argsIndex];}}while(rangeLength--){result[leftIndex++]=args[argsIndex++];}return result;}/**
+ * This function is like `composeArgs` except that the arguments composition
+ * is tailored for `_.partialRight`.
+ *
+ * @private
+ * @param {Array} args The provided arguments.
+ * @param {Array} partials The arguments to append to those provided.
+ * @param {Array} holders The `partials` placeholder indexes.
+ * @params {boolean} [isCurried] Specify composing for a curried function.
+ * @returns {Array} Returns the new array of composed arguments.
+ */function composeArgsRight(args,partials,holders,isCurried){var argsIndex=-1,argsLength=args.length,holdersIndex=-1,holdersLength=holders.length,rightIndex=-1,rightLength=partials.length,rangeLength=nativeMax(argsLength-holdersLength,0),result=Array(rangeLength+rightLength),isUncurried=!isCurried;while(++argsIndex<rangeLength){result[argsIndex]=args[argsIndex];}var offset=argsIndex;while(++rightIndex<rightLength){result[offset+rightIndex]=partials[rightIndex];}while(++holdersIndex<holdersLength){if(isUncurried||argsIndex<argsLength){result[offset+holders[holdersIndex]]=args[argsIndex++];}}return result;}/**
+ * Copies the values of `source` to `array`.
+ *
+ * @private
+ * @param {Array} source The array to copy values from.
+ * @param {Array} [array=[]] The array to copy values to.
+ * @returns {Array} Returns `array`.
+ */function copyArray(source,array){var index=-1,length=source.length;array||(array=Array(length));while(++index<length){array[index]=source[index];}return array;}/**
+ * Copies properties of `source` to `object`.
+ *
+ * @private
+ * @param {Object} source The object to copy properties from.
+ * @param {Array} props The property identifiers to copy.
+ * @param {Object} [object={}] The object to copy properties to.
+ * @param {Function} [customizer] The function to customize copied values.
+ * @returns {Object} Returns `object`.
+ */function copyObject(source,props,object,customizer){var isNew=!object;object||(object={});var index=-1,length=props.length;while(++index<length){var key=props[index];var newValue=customizer?customizer(object[key],source[key],key,object,source):undefined$1;if(newValue===undefined$1){newValue=source[key];}if(isNew){baseAssignValue(object,key,newValue);}else {assignValue(object,key,newValue);}}return object;}/**
+ * Copies own symbols of `source` to `object`.
+ *
+ * @private
+ * @param {Object} source The object to copy symbols from.
+ * @param {Object} [object={}] The object to copy symbols to.
+ * @returns {Object} Returns `object`.
+ */function copySymbols(source,object){return copyObject(source,getSymbols(source),object);}/**
+ * Copies own and inherited symbols of `source` to `object`.
+ *
+ * @private
+ * @param {Object} source The object to copy symbols from.
+ * @param {Object} [object={}] The object to copy symbols to.
+ * @returns {Object} Returns `object`.
+ */function copySymbolsIn(source,object){return copyObject(source,getSymbolsIn(source),object);}/**
+ * Creates a function like `_.groupBy`.
+ *
+ * @private
+ * @param {Function} setter The function to set accumulator values.
+ * @param {Function} [initializer] The accumulator object initializer.
+ * @returns {Function} Returns the new aggregator function.
+ */function createAggregator(setter,initializer){return function(collection,iteratee){var func=isArray(collection)?arrayAggregator:baseAggregator,accumulator=initializer?initializer():{};return func(collection,setter,getIteratee(iteratee,2),accumulator);};}/**
+ * Creates a function like `_.assign`.
+ *
+ * @private
+ * @param {Function} assigner The function to assign values.
+ * @returns {Function} Returns the new assigner function.
+ */function createAssigner(assigner){return baseRest(function(object,sources){var index=-1,length=sources.length,customizer=length>1?sources[length-1]:undefined$1,guard=length>2?sources[2]:undefined$1;customizer=assigner.length>3&&typeof customizer=='function'?(length--,customizer):undefined$1;if(guard&&isIterateeCall(sources[0],sources[1],guard)){customizer=length<3?undefined$1:customizer;length=1;}object=Object(object);while(++index<length){var source=sources[index];if(source){assigner(object,source,index,customizer);}}return object;});}/**
+ * Creates a `baseEach` or `baseEachRight` function.
+ *
+ * @private
+ * @param {Function} eachFunc The function to iterate over a collection.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
+ */function createBaseEach(eachFunc,fromRight){return function(collection,iteratee){if(collection==null){return collection;}if(!isArrayLike(collection)){return eachFunc(collection,iteratee);}var length=collection.length,index=fromRight?length:-1,iterable=Object(collection);while(fromRight?index--:++index<length){if(iteratee(iterable[index],index,iterable)===false){break;}}return collection;};}/**
+ * Creates a base function for methods like `_.forIn` and `_.forOwn`.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
+ */function createBaseFor(fromRight){return function(object,iteratee,keysFunc){var index=-1,iterable=Object(object),props=keysFunc(object),length=props.length;while(length--){var key=props[fromRight?length:++index];if(iteratee(iterable[key],key,iterable)===false){break;}}return object;};}/**
+ * Creates a function that wraps `func` to invoke it with the optional `this`
+ * binding of `thisArg`.
+ *
+ * @private
+ * @param {Function} func The function to wrap.
+ * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+ * @param {*} [thisArg] The `this` binding of `func`.
+ * @returns {Function} Returns the new wrapped function.
+ */function createBind(func,bitmask,thisArg){var isBind=bitmask&WRAP_BIND_FLAG,Ctor=createCtor(func);function wrapper(){var fn=this&&this!==root&&this instanceof wrapper?Ctor:func;return fn.apply(isBind?thisArg:this,arguments);}return wrapper;}/**
+ * Creates a function like `_.lowerFirst`.
+ *
+ * @private
+ * @param {string} methodName The name of the `String` case method to use.
+ * @returns {Function} Returns the new case function.
+ */function createCaseFirst(methodName){return function(string){string=toString(string);var strSymbols=hasUnicode(string)?stringToArray(string):undefined$1;var chr=strSymbols?strSymbols[0]:string.charAt(0);var trailing=strSymbols?castSlice(strSymbols,1).join(''):string.slice(1);return chr[methodName]()+trailing;};}/**
+ * Creates a function like `_.camelCase`.
+ *
+ * @private
+ * @param {Function} callback The function to combine each word.
+ * @returns {Function} Returns the new compounder function.
+ */function createCompounder(callback){return function(string){return arrayReduce(words(deburr(string).replace(reApos,'')),callback,'');};}/**
+ * Creates a function that produces an instance of `Ctor` regardless of
+ * whether it was invoked as part of a `new` expression or by `call` or `apply`.
+ *
+ * @private
+ * @param {Function} Ctor The constructor to wrap.
+ * @returns {Function} Returns the new wrapped function.
+ */function createCtor(Ctor){return function(){// Use a `switch` statement to work with class constructors. See
+// http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
+// for more details.
+var args=arguments;switch(args.length){case 0:return new Ctor();case 1:return new Ctor(args[0]);case 2:return new Ctor(args[0],args[1]);case 3:return new Ctor(args[0],args[1],args[2]);case 4:return new Ctor(args[0],args[1],args[2],args[3]);case 5:return new Ctor(args[0],args[1],args[2],args[3],args[4]);case 6:return new Ctor(args[0],args[1],args[2],args[3],args[4],args[5]);case 7:return new Ctor(args[0],args[1],args[2],args[3],args[4],args[5],args[6]);}var thisBinding=baseCreate(Ctor.prototype),result=Ctor.apply(thisBinding,args);// Mimic the constructor's `return` behavior.
+// See https://es5.github.io/#x13.2.2 for more details.
+return isObject(result)?result:thisBinding;};}/**
+ * Creates a function that wraps `func` to enable currying.
+ *
+ * @private
+ * @param {Function} func The function to wrap.
+ * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+ * @param {number} arity The arity of `func`.
+ * @returns {Function} Returns the new wrapped function.
+ */function createCurry(func,bitmask,arity){var Ctor=createCtor(func);function wrapper(){var length=arguments.length,args=Array(length),index=length,placeholder=getHolder(wrapper);while(index--){args[index]=arguments[index];}var holders=length<3&&args[0]!==placeholder&&args[length-1]!==placeholder?[]:replaceHolders(args,placeholder);length-=holders.length;if(length<arity){return createRecurry(func,bitmask,createHybrid,wrapper.placeholder,undefined$1,args,holders,undefined$1,undefined$1,arity-length);}var fn=this&&this!==root&&this instanceof wrapper?Ctor:func;return apply(fn,this,args);}return wrapper;}/**
+ * Creates a `_.find` or `_.findLast` function.
+ *
+ * @private
+ * @param {Function} findIndexFunc The function to find the collection index.
+ * @returns {Function} Returns the new find function.
+ */function createFind(findIndexFunc){return function(collection,predicate,fromIndex){var iterable=Object(collection);if(!isArrayLike(collection)){var iteratee=getIteratee(predicate,3);collection=keys(collection);predicate=function(key){return iteratee(iterable[key],key,iterable);};}var index=findIndexFunc(collection,predicate,fromIndex);return index>-1?iterable[iteratee?collection[index]:index]:undefined$1;};}/**
+ * Creates a `_.flow` or `_.flowRight` function.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new flow function.
+ */function createFlow(fromRight){return flatRest(function(funcs){var length=funcs.length,index=length,prereq=LodashWrapper.prototype.thru;if(fromRight){funcs.reverse();}while(index--){var func=funcs[index];if(typeof func!='function'){throw new TypeError(FUNC_ERROR_TEXT);}if(prereq&&!wrapper&&getFuncName(func)=='wrapper'){var wrapper=new LodashWrapper([],true);}}index=wrapper?index:length;while(++index<length){func=funcs[index];var funcName=getFuncName(func),data=funcName=='wrapper'?getData(func):undefined$1;if(data&&isLaziable(data[0])&&data[1]==(WRAP_ARY_FLAG|WRAP_CURRY_FLAG|WRAP_PARTIAL_FLAG|WRAP_REARG_FLAG)&&!data[4].length&&data[9]==1){wrapper=wrapper[getFuncName(data[0])].apply(wrapper,data[3]);}else {wrapper=func.length==1&&isLaziable(func)?wrapper[funcName]():wrapper.thru(func);}}return function(){var args=arguments,value=args[0];if(wrapper&&args.length==1&&isArray(value)){return wrapper.plant(value).value();}var index=0,result=length?funcs[index].apply(this,args):value;while(++index<length){result=funcs[index].call(this,result);}return result;};});}/**
+ * Creates a function that wraps `func` to invoke it with optional `this`
+ * binding of `thisArg`, partial application, and currying.
+ *
+ * @private
+ * @param {Function|string} func The function or method name to wrap.
+ * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+ * @param {*} [thisArg] The `this` binding of `func`.
+ * @param {Array} [partials] The arguments to prepend to those provided to
+ * the new function.
+ * @param {Array} [holders] The `partials` placeholder indexes.
+ * @param {Array} [partialsRight] The arguments to append to those provided
+ * to the new function.
+ * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
+ * @param {Array} [argPos] The argument positions of the new function.
+ * @param {number} [ary] The arity cap of `func`.
+ * @param {number} [arity] The arity of `func`.
+ * @returns {Function} Returns the new wrapped function.
+ */function createHybrid(func,bitmask,thisArg,partials,holders,partialsRight,holdersRight,argPos,ary,arity){var isAry=bitmask&WRAP_ARY_FLAG,isBind=bitmask&WRAP_BIND_FLAG,isBindKey=bitmask&WRAP_BIND_KEY_FLAG,isCurried=bitmask&(WRAP_CURRY_FLAG|WRAP_CURRY_RIGHT_FLAG),isFlip=bitmask&WRAP_FLIP_FLAG,Ctor=isBindKey?undefined$1:createCtor(func);function wrapper(){var length=arguments.length,args=Array(length),index=length;while(index--){args[index]=arguments[index];}if(isCurried){var placeholder=getHolder(wrapper),holdersCount=countHolders(args,placeholder);}if(partials){args=composeArgs(args,partials,holders,isCurried);}if(partialsRight){args=composeArgsRight(args,partialsRight,holdersRight,isCurried);}length-=holdersCount;if(isCurried&&length<arity){var newHolders=replaceHolders(args,placeholder);return createRecurry(func,bitmask,createHybrid,wrapper.placeholder,thisArg,args,newHolders,argPos,ary,arity-length);}var thisBinding=isBind?thisArg:this,fn=isBindKey?thisBinding[func]:func;length=args.length;if(argPos){args=reorder(args,argPos);}else if(isFlip&&length>1){args.reverse();}if(isAry&&ary<length){args.length=ary;}if(this&&this!==root&&this instanceof wrapper){fn=Ctor||createCtor(fn);}return fn.apply(thisBinding,args);}return wrapper;}/**
+ * Creates a function like `_.invertBy`.
+ *
+ * @private
+ * @param {Function} setter The function to set accumulator values.
+ * @param {Function} toIteratee The function to resolve iteratees.
+ * @returns {Function} Returns the new inverter function.
+ */function createInverter(setter,toIteratee){return function(object,iteratee){return baseInverter(object,setter,toIteratee(iteratee),{});};}/**
+ * Creates a function that performs a mathematical operation on two values.
+ *
+ * @private
+ * @param {Function} operator The function to perform the operation.
+ * @param {number} [defaultValue] The value used for `undefined` arguments.
+ * @returns {Function} Returns the new mathematical operation function.
+ */function createMathOperation(operator,defaultValue){return function(value,other){var result;if(value===undefined$1&&other===undefined$1){return defaultValue;}if(value!==undefined$1){result=value;}if(other!==undefined$1){if(result===undefined$1){return other;}if(typeof value=='string'||typeof other=='string'){value=baseToString(value);other=baseToString(other);}else {value=baseToNumber(value);other=baseToNumber(other);}result=operator(value,other);}return result;};}/**
+ * Creates a function like `_.over`.
+ *
+ * @private
+ * @param {Function} arrayFunc The function to iterate over iteratees.
+ * @returns {Function} Returns the new over function.
+ */function createOver(arrayFunc){return flatRest(function(iteratees){iteratees=arrayMap(iteratees,baseUnary(getIteratee()));return baseRest(function(args){var thisArg=this;return arrayFunc(iteratees,function(iteratee){return apply(iteratee,thisArg,args);});});});}/**
+ * Creates the padding for `string` based on `length`. The `chars` string
+ * is truncated if the number of characters exceeds `length`.
+ *
+ * @private
+ * @param {number} length The padding length.
+ * @param {string} [chars=' '] The string used as padding.
+ * @returns {string} Returns the padding for `string`.
+ */function createPadding(length,chars){chars=chars===undefined$1?' ':baseToString(chars);var charsLength=chars.length;if(charsLength<2){return charsLength?baseRepeat(chars,length):chars;}var result=baseRepeat(chars,nativeCeil(length/stringSize(chars)));return hasUnicode(chars)?castSlice(stringToArray(result),0,length).join(''):result.slice(0,length);}/**
+ * Creates a function that wraps `func` to invoke it with the `this` binding
+ * of `thisArg` and `partials` prepended to the arguments it receives.
+ *
+ * @private
+ * @param {Function} func The function to wrap.
+ * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {Array} partials The arguments to prepend to those provided to
+ * the new function.
+ * @returns {Function} Returns the new wrapped function.
+ */function createPartial(func,bitmask,thisArg,partials){var isBind=bitmask&WRAP_BIND_FLAG,Ctor=createCtor(func);function wrapper(){var argsIndex=-1,argsLength=arguments.length,leftIndex=-1,leftLength=partials.length,args=Array(leftLength+argsLength),fn=this&&this!==root&&this instanceof wrapper?Ctor:func;while(++leftIndex<leftLength){args[leftIndex]=partials[leftIndex];}while(argsLength--){args[leftIndex++]=arguments[++argsIndex];}return apply(fn,isBind?thisArg:this,args);}return wrapper;}/**
+ * Creates a `_.range` or `_.rangeRight` function.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new range function.
+ */function createRange(fromRight){return function(start,end,step){if(step&&typeof step!='number'&&isIterateeCall(start,end,step)){end=step=undefined$1;}// Ensure the sign of `-0` is preserved.
+start=toFinite(start);if(end===undefined$1){end=start;start=0;}else {end=toFinite(end);}step=step===undefined$1?start<end?1:-1:toFinite(step);return baseRange(start,end,step,fromRight);};}/**
+ * Creates a function that performs a relational operation on two values.
+ *
+ * @private
+ * @param {Function} operator The function to perform the operation.
+ * @returns {Function} Returns the new relational operation function.
+ */function createRelationalOperation(operator){return function(value,other){if(!(typeof value=='string'&&typeof other=='string')){value=toNumber(value);other=toNumber(other);}return operator(value,other);};}/**
+ * Creates a function that wraps `func` to continue currying.
+ *
+ * @private
+ * @param {Function} func The function to wrap.
+ * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+ * @param {Function} wrapFunc The function to create the `func` wrapper.
+ * @param {*} placeholder The placeholder value.
+ * @param {*} [thisArg] The `this` binding of `func`.
+ * @param {Array} [partials] The arguments to prepend to those provided to
+ * the new function.
+ * @param {Array} [holders] The `partials` placeholder indexes.
+ * @param {Array} [argPos] The argument positions of the new function.
+ * @param {number} [ary] The arity cap of `func`.
+ * @param {number} [arity] The arity of `func`.
+ * @returns {Function} Returns the new wrapped function.
+ */function createRecurry(func,bitmask,wrapFunc,placeholder,thisArg,partials,holders,argPos,ary,arity){var isCurry=bitmask&WRAP_CURRY_FLAG,newHolders=isCurry?holders:undefined$1,newHoldersRight=isCurry?undefined$1:holders,newPartials=isCurry?partials:undefined$1,newPartialsRight=isCurry?undefined$1:partials;bitmask|=isCurry?WRAP_PARTIAL_FLAG:WRAP_PARTIAL_RIGHT_FLAG;bitmask&=~(isCurry?WRAP_PARTIAL_RIGHT_FLAG:WRAP_PARTIAL_FLAG);if(!(bitmask&WRAP_CURRY_BOUND_FLAG)){bitmask&=~(WRAP_BIND_FLAG|WRAP_BIND_KEY_FLAG);}var newData=[func,bitmask,thisArg,newPartials,newHolders,newPartialsRight,newHoldersRight,argPos,ary,arity];var result=wrapFunc.apply(undefined$1,newData);if(isLaziable(func)){setData(result,newData);}result.placeholder=placeholder;return setWrapToString(result,func,bitmask);}/**
+ * Creates a function like `_.round`.
+ *
+ * @private
+ * @param {string} methodName The name of the `Math` method to use when rounding.
+ * @returns {Function} Returns the new round function.
+ */function createRound(methodName){var func=Math[methodName];return function(number,precision){number=toNumber(number);precision=precision==null?0:nativeMin(toInteger(precision),292);if(precision&&nativeIsFinite(number)){// Shift with exponential notation to avoid floating-point issues.
+// See [MDN](https://mdn.io/round#Examples) for more details.
+var pair=(toString(number)+'e').split('e'),value=func(pair[0]+'e'+(+pair[1]+precision));pair=(toString(value)+'e').split('e');return +(pair[0]+'e'+(+pair[1]-precision));}return func(number);};}/**
+ * Creates a set object of `values`.
+ *
+ * @private
+ * @param {Array} values The values to add to the set.
+ * @returns {Object} Returns the new set.
+ */var createSet=!(Set&&1/setToArray(new Set([,-0]))[1]==INFINITY)?noop:function(values){return new Set(values);};/**
+ * Creates a `_.toPairs` or `_.toPairsIn` function.
+ *
+ * @private
+ * @param {Function} keysFunc The function to get the keys of a given object.
+ * @returns {Function} Returns the new pairs function.
+ */function createToPairs(keysFunc){return function(object){var tag=getTag(object);if(tag==mapTag){return mapToArray(object);}if(tag==setTag){return setToPairs(object);}return baseToPairs(object,keysFunc(object));};}/**
+ * Creates a function that either curries or invokes `func` with optional
+ * `this` binding and partially applied arguments.
+ *
+ * @private
+ * @param {Function|string} func The function or method name to wrap.
+ * @param {number} bitmask The bitmask flags.
+ * 1 - `_.bind`
+ * 2 - `_.bindKey`
+ * 4 - `_.curry` or `_.curryRight` of a bound function
+ * 8 - `_.curry`
+ * 16 - `_.curryRight`
+ * 32 - `_.partial`
+ * 64 - `_.partialRight`
+ * 128 - `_.rearg`
+ * 256 - `_.ary`
+ * 512 - `_.flip`
+ * @param {*} [thisArg] The `this` binding of `func`.
+ * @param {Array} [partials] The arguments to be partially applied.
+ * @param {Array} [holders] The `partials` placeholder indexes.
+ * @param {Array} [argPos] The argument positions of the new function.
+ * @param {number} [ary] The arity cap of `func`.
+ * @param {number} [arity] The arity of `func`.
+ * @returns {Function} Returns the new wrapped function.
+ */function createWrap(func,bitmask,thisArg,partials,holders,argPos,ary,arity){var isBindKey=bitmask&WRAP_BIND_KEY_FLAG;if(!isBindKey&&typeof func!='function'){throw new TypeError(FUNC_ERROR_TEXT);}var length=partials?partials.length:0;if(!length){bitmask&=~(WRAP_PARTIAL_FLAG|WRAP_PARTIAL_RIGHT_FLAG);partials=holders=undefined$1;}ary=ary===undefined$1?ary:nativeMax(toInteger(ary),0);arity=arity===undefined$1?arity:toInteger(arity);length-=holders?holders.length:0;if(bitmask&WRAP_PARTIAL_RIGHT_FLAG){var partialsRight=partials,holdersRight=holders;partials=holders=undefined$1;}var data=isBindKey?undefined$1:getData(func);var newData=[func,bitmask,thisArg,partials,holders,partialsRight,holdersRight,argPos,ary,arity];if(data){mergeData(newData,data);}func=newData[0];bitmask=newData[1];thisArg=newData[2];partials=newData[3];holders=newData[4];arity=newData[9]=newData[9]===undefined$1?isBindKey?0:func.length:nativeMax(newData[9]-length,0);if(!arity&&bitmask&(WRAP_CURRY_FLAG|WRAP_CURRY_RIGHT_FLAG)){bitmask&=~(WRAP_CURRY_FLAG|WRAP_CURRY_RIGHT_FLAG);}if(!bitmask||bitmask==WRAP_BIND_FLAG){var result=createBind(func,bitmask,thisArg);}else if(bitmask==WRAP_CURRY_FLAG||bitmask==WRAP_CURRY_RIGHT_FLAG){result=createCurry(func,bitmask,arity);}else if((bitmask==WRAP_PARTIAL_FLAG||bitmask==(WRAP_BIND_FLAG|WRAP_PARTIAL_FLAG))&&!holders.length){result=createPartial(func,bitmask,thisArg,partials);}else {result=createHybrid.apply(undefined$1,newData);}var setter=data?baseSetData:setData;return setWrapToString(setter(result,newData),func,bitmask);}/**
+ * Used by `_.defaults` to customize its `_.assignIn` use to assign properties
+ * of source objects to the destination object for all destination properties
+ * that resolve to `undefined`.
+ *
+ * @private
+ * @param {*} objValue The destination value.
+ * @param {*} srcValue The source value.
+ * @param {string} key The key of the property to assign.
+ * @param {Object} object The parent object of `objValue`.
+ * @returns {*} Returns the value to assign.
+ */function customDefaultsAssignIn(objValue,srcValue,key,object){if(objValue===undefined$1||eq(objValue,objectProto[key])&&!hasOwnProperty.call(object,key)){return srcValue;}return objValue;}/**
+ * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
+ * objects into destination objects that are passed thru.
+ *
+ * @private
+ * @param {*} objValue The destination value.
+ * @param {*} srcValue The source value.
+ * @param {string} key The key of the property to merge.
+ * @param {Object} object The parent object of `objValue`.
+ * @param {Object} source The parent object of `srcValue`.
+ * @param {Object} [stack] Tracks traversed source values and their merged
+ * counterparts.
+ * @returns {*} Returns the value to assign.
+ */function customDefaultsMerge(objValue,srcValue,key,object,source,stack){if(isObject(objValue)&&isObject(srcValue)){// Recursively merge objects and arrays (susceptible to call stack limits).
+stack.set(srcValue,objValue);baseMerge(objValue,srcValue,undefined$1,customDefaultsMerge,stack);stack['delete'](srcValue);}return objValue;}/**
+ * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
+ * objects.
+ *
+ * @private
+ * @param {*} value The value to inspect.
+ * @param {string} key The key of the property to inspect.
+ * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
+ */function customOmitClone(value){return isPlainObject(value)?undefined$1:value;}/**
+ * A specialized version of `baseIsEqualDeep` for arrays with support for
+ * partial deep comparisons.
+ *
+ * @private
+ * @param {Array} array The array to compare.
+ * @param {Array} other The other array to compare.
+ * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
+ * @param {Function} customizer The function to customize comparisons.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Object} stack Tracks traversed `array` and `other` objects.
+ * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
+ */function equalArrays(array,other,bitmask,customizer,equalFunc,stack){var isPartial=bitmask&COMPARE_PARTIAL_FLAG,arrLength=array.length,othLength=other.length;if(arrLength!=othLength&&!(isPartial&&othLength>arrLength)){return false;}// Check that cyclic values are equal.
+var arrStacked=stack.get(array);var othStacked=stack.get(other);if(arrStacked&&othStacked){return arrStacked==other&&othStacked==array;}var index=-1,result=true,seen=bitmask&COMPARE_UNORDERED_FLAG?new SetCache():undefined$1;stack.set(array,other);stack.set(other,array);// Ignore non-index properties.
+while(++index<arrLength){var arrValue=array[index],othValue=other[index];if(customizer){var compared=isPartial?customizer(othValue,arrValue,index,other,array,stack):customizer(arrValue,othValue,index,array,other,stack);}if(compared!==undefined$1){if(compared){continue;}result=false;break;}// Recursively compare arrays (susceptible to call stack limits).
+if(seen){if(!arraySome(other,function(othValue,othIndex){if(!cacheHas(seen,othIndex)&&(arrValue===othValue||equalFunc(arrValue,othValue,bitmask,customizer,stack))){return seen.push(othIndex);}})){result=false;break;}}else if(!(arrValue===othValue||equalFunc(arrValue,othValue,bitmask,customizer,stack))){result=false;break;}}stack['delete'](array);stack['delete'](other);return result;}/**
+ * A specialized version of `baseIsEqualDeep` for comparing objects of
+ * the same `toStringTag`.
+ *
+ * **Note:** This function only supports comparing values with tags of
+ * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {string} tag The `toStringTag` of the objects to compare.
+ * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
+ * @param {Function} customizer The function to customize comparisons.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Object} stack Tracks traversed `object` and `other` objects.
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+ */function equalByTag(object,other,tag,bitmask,customizer,equalFunc,stack){switch(tag){case dataViewTag:if(object.byteLength!=other.byteLength||object.byteOffset!=other.byteOffset){return false;}object=object.buffer;other=other.buffer;case arrayBufferTag:if(object.byteLength!=other.byteLength||!equalFunc(new Uint8Array(object),new Uint8Array(other))){return false;}return true;case boolTag:case dateTag:case numberTag:// Coerce booleans to `1` or `0` and dates to milliseconds.
+// Invalid dates are coerced to `NaN`.
+return eq(+object,+other);case errorTag:return object.name==other.name&&object.message==other.message;case regexpTag:case stringTag:// Coerce regexes to strings and treat strings, primitives and objects,
+// as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
+// for more details.
+return object==other+'';case mapTag:var convert=mapToArray;case setTag:var isPartial=bitmask&COMPARE_PARTIAL_FLAG;convert||(convert=setToArray);if(object.size!=other.size&&!isPartial){return false;}// Assume cyclic values are equal.
+var stacked=stack.get(object);if(stacked){return stacked==other;}bitmask|=COMPARE_UNORDERED_FLAG;// Recursively compare objects (susceptible to call stack limits).
+stack.set(object,other);var result=equalArrays(convert(object),convert(other),bitmask,customizer,equalFunc,stack);stack['delete'](object);return result;case symbolTag:if(symbolValueOf){return symbolValueOf.call(object)==symbolValueOf.call(other);}}return false;}/**
+ * A specialized version of `baseIsEqualDeep` for objects with support for
+ * partial deep comparisons.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
+ * @param {Function} customizer The function to customize comparisons.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Object} stack Tracks traversed `object` and `other` objects.
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+ */function equalObjects(object,other,bitmask,customizer,equalFunc,stack){var isPartial=bitmask&COMPARE_PARTIAL_FLAG,objProps=getAllKeys(object),objLength=objProps.length,othProps=getAllKeys(other),othLength=othProps.length;if(objLength!=othLength&&!isPartial){return false;}var index=objLength;while(index--){var key=objProps[index];if(!(isPartial?key in other:hasOwnProperty.call(other,key))){return false;}}// Check that cyclic values are equal.
+var objStacked=stack.get(object);var othStacked=stack.get(other);if(objStacked&&othStacked){return objStacked==other&&othStacked==object;}var result=true;stack.set(object,other);stack.set(other,object);var skipCtor=isPartial;while(++index<objLength){key=objProps[index];var objValue=object[key],othValue=other[key];if(customizer){var compared=isPartial?customizer(othValue,objValue,key,other,object,stack):customizer(objValue,othValue,key,object,other,stack);}// Recursively compare objects (susceptible to call stack limits).
+if(!(compared===undefined$1?objValue===othValue||equalFunc(objValue,othValue,bitmask,customizer,stack):compared)){result=false;break;}skipCtor||(skipCtor=key=='constructor');}if(result&&!skipCtor){var objCtor=object.constructor,othCtor=other.constructor;// Non `Object` object instances with different constructors are not equal.
+if(objCtor!=othCtor&&'constructor'in object&&'constructor'in other&&!(typeof objCtor=='function'&&objCtor instanceof objCtor&&typeof othCtor=='function'&&othCtor instanceof othCtor)){result=false;}}stack['delete'](object);stack['delete'](other);return result;}/**
+ * A specialized version of `baseRest` which flattens the rest array.
+ *
+ * @private
+ * @param {Function} func The function to apply a rest parameter to.
+ * @returns {Function} Returns the new function.
+ */function flatRest(func){return setToString(overRest(func,undefined$1,flatten),func+'');}/**
+ * Creates an array of own enumerable property names and symbols of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names and symbols.
+ */function getAllKeys(object){return baseGetAllKeys(object,keys,getSymbols);}/**
+ * Creates an array of own and inherited enumerable property names and
+ * symbols of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names and symbols.
+ */function getAllKeysIn(object){return baseGetAllKeys(object,keysIn,getSymbolsIn);}/**
+ * Gets metadata for `func`.
+ *
+ * @private
+ * @param {Function} func The function to query.
+ * @returns {*} Returns the metadata for `func`.
+ */var getData=!metaMap?noop:function(func){return metaMap.get(func);};/**
+ * Gets the name of `func`.
+ *
+ * @private
+ * @param {Function} func The function to query.
+ * @returns {string} Returns the function name.
+ */function getFuncName(func){var result=func.name+'',array=realNames[result],length=hasOwnProperty.call(realNames,result)?array.length:0;while(length--){var data=array[length],otherFunc=data.func;if(otherFunc==null||otherFunc==func){return data.name;}}return result;}/**
+ * Gets the argument placeholder value for `func`.
+ *
+ * @private
+ * @param {Function} func The function to inspect.
+ * @returns {*} Returns the placeholder value.
+ */function getHolder(func){var object=hasOwnProperty.call(lodash,'placeholder')?lodash:func;return object.placeholder;}/**
+ * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
+ * this function returns the custom method, otherwise it returns `baseIteratee`.
+ * If arguments are provided, the chosen function is invoked with them and
+ * its result is returned.
+ *
+ * @private
+ * @param {*} [value] The value to convert to an iteratee.
+ * @param {number} [arity] The arity of the created iteratee.
+ * @returns {Function} Returns the chosen function or its result.
+ */function getIteratee(){var result=lodash.iteratee||iteratee;result=result===iteratee?baseIteratee:result;return arguments.length?result(arguments[0],arguments[1]):result;}/**
+ * Gets the data for `map`.
+ *
+ * @private
+ * @param {Object} map The map to query.
+ * @param {string} key The reference key.
+ * @returns {*} Returns the map data.
+ */function getMapData(map,key){var data=map.__data__;return isKeyable(key)?data[typeof key=='string'?'string':'hash']:data.map;}/**
+ * Gets the property names, values, and compare flags of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the match data of `object`.
+ */function getMatchData(object){var result=keys(object),length=result.length;while(length--){var key=result[length],value=object[key];result[length]=[key,value,isStrictComparable(value)];}return result;}/**
+ * Gets the native function at `key` of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {string} key The key of the method to get.
+ * @returns {*} Returns the function if it's native, else `undefined`.
+ */function getNative(object,key){var value=getValue(object,key);return baseIsNative(value)?value:undefined$1;}/**
+ * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
+ *
+ * @private
+ * @param {*} value The value to query.
+ * @returns {string} Returns the raw `toStringTag`.
+ */function getRawTag(value){var isOwn=hasOwnProperty.call(value,symToStringTag),tag=value[symToStringTag];try{value[symToStringTag]=undefined$1;var unmasked=true;}catch(e){}var result=nativeObjectToString.call(value);if(unmasked){if(isOwn){value[symToStringTag]=tag;}else {delete value[symToStringTag];}}return result;}/**
+ * Creates an array of the own enumerable symbols of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of symbols.
+ */var getSymbols=!nativeGetSymbols?stubArray:function(object){if(object==null){return [];}object=Object(object);return arrayFilter(nativeGetSymbols(object),function(symbol){return propertyIsEnumerable.call(object,symbol);});};/**
+ * Creates an array of the own and inherited enumerable symbols of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of symbols.
+ */var getSymbolsIn=!nativeGetSymbols?stubArray:function(object){var result=[];while(object){arrayPush(result,getSymbols(object));object=getPrototype(object);}return result;};/**
+ * Gets the `toStringTag` of `value`.
+ *
+ * @private
+ * @param {*} value The value to query.
+ * @returns {string} Returns the `toStringTag`.
+ */var getTag=baseGetTag;// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
+if(DataView&&getTag(new DataView(new ArrayBuffer(1)))!=dataViewTag||Map&&getTag(new Map())!=mapTag||Promise&&getTag(Promise.resolve())!=promiseTag||Set&&getTag(new Set())!=setTag||WeakMap&&getTag(new WeakMap())!=weakMapTag){getTag=function(value){var result=baseGetTag(value),Ctor=result==objectTag?value.constructor:undefined$1,ctorString=Ctor?toSource(Ctor):'';if(ctorString){switch(ctorString){case dataViewCtorString:return dataViewTag;case mapCtorString:return mapTag;case promiseCtorString:return promiseTag;case setCtorString:return setTag;case weakMapCtorString:return weakMapTag;}}return result;};}/**
+ * Gets the view, applying any `transforms` to the `start` and `end` positions.
+ *
+ * @private
+ * @param {number} start The start of the view.
+ * @param {number} end The end of the view.
+ * @param {Array} transforms The transformations to apply to the view.
+ * @returns {Object} Returns an object containing the `start` and `end`
+ * positions of the view.
+ */function getView(start,end,transforms){var index=-1,length=transforms.length;while(++index<length){var data=transforms[index],size=data.size;switch(data.type){case'drop':start+=size;break;case'dropRight':end-=size;break;case'take':end=nativeMin(end,start+size);break;case'takeRight':start=nativeMax(start,end-size);break;}}return {'start':start,'end':end};}/**
+ * Extracts wrapper details from the `source` body comment.
+ *
+ * @private
+ * @param {string} source The source to inspect.
+ * @returns {Array} Returns the wrapper details.
+ */function getWrapDetails(source){var match=source.match(reWrapDetails);return match?match[1].split(reSplitDetails):[];}/**
+ * Checks if `path` exists on `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path to check.
+ * @param {Function} hasFunc The function to check properties.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ */function hasPath(object,path,hasFunc){path=castPath(path,object);var index=-1,length=path.length,result=false;while(++index<length){var key=toKey(path[index]);if(!(result=object!=null&&hasFunc(object,key))){break;}object=object[key];}if(result||++index!=length){return result;}length=object==null?0:object.length;return !!length&&isLength(length)&&isIndex(key,length)&&(isArray(object)||isArguments(object));}/**
+ * Initializes an array clone.
+ *
+ * @private
+ * @param {Array} array The array to clone.
+ * @returns {Array} Returns the initialized clone.
+ */function initCloneArray(array){var length=array.length,result=new array.constructor(length);// Add properties assigned by `RegExp#exec`.
+if(length&&typeof array[0]=='string'&&hasOwnProperty.call(array,'index')){result.index=array.index;result.input=array.input;}return result;}/**
+ * Initializes an object clone.
+ *
+ * @private
+ * @param {Object} object The object to clone.
+ * @returns {Object} Returns the initialized clone.
+ */function initCloneObject(object){return typeof object.constructor=='function'&&!isPrototype(object)?baseCreate(getPrototype(object)):{};}/**
+ * Initializes an object clone based on its `toStringTag`.
+ *
+ * **Note:** This function only supports cloning values with tags of
+ * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
+ *
+ * @private
+ * @param {Object} object The object to clone.
+ * @param {string} tag The `toStringTag` of the object to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Object} Returns the initialized clone.
+ */function initCloneByTag(object,tag,isDeep){var Ctor=object.constructor;switch(tag){case arrayBufferTag:return cloneArrayBuffer(object);case boolTag:case dateTag:return new Ctor(+object);case dataViewTag:return cloneDataView(object,isDeep);case float32Tag:case float64Tag:case int8Tag:case int16Tag:case int32Tag:case uint8Tag:case uint8ClampedTag:case uint16Tag:case uint32Tag:return cloneTypedArray(object,isDeep);case mapTag:return new Ctor();case numberTag:case stringTag:return new Ctor(object);case regexpTag:return cloneRegExp(object);case setTag:return new Ctor();case symbolTag:return cloneSymbol(object);}}/**
+ * Inserts wrapper `details` in a comment at the top of the `source` body.
+ *
+ * @private
+ * @param {string} source The source to modify.
+ * @returns {Array} details The details to insert.
+ * @returns {string} Returns the modified source.
+ */function insertWrapDetails(source,details){var length=details.length;if(!length){return source;}var lastIndex=length-1;details[lastIndex]=(length>1?'& ':'')+details[lastIndex];details=details.join(length>2?', ':' ');return source.replace(reWrapComment,'{\n/* [wrapped with '+details+'] */\n');}/**
+ * Checks if `value` is a flattenable `arguments` object or array.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
+ */function isFlattenable(value){return isArray(value)||isArguments(value)||!!(spreadableSymbol&&value&&value[spreadableSymbol]);}/**
+ * Checks if `value` is a valid array-like index.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
+ * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
+ */function isIndex(value,length){var type=typeof value;length=length==null?MAX_SAFE_INTEGER:length;return !!length&&(type=='number'||type!='symbol'&&reIsUint.test(value))&&value>-1&&value%1==0&&value<length;}/**
+ * Checks if the given arguments are from an iteratee call.
+ *
+ * @private
+ * @param {*} value The potential iteratee value argument.
+ * @param {*} index The potential iteratee index or key argument.
+ * @param {*} object The potential iteratee object argument.
+ * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
+ * else `false`.
+ */function isIterateeCall(value,index,object){if(!isObject(object)){return false;}var type=typeof index;if(type=='number'?isArrayLike(object)&&isIndex(index,object.length):type=='string'&&index in object){return eq(object[index],value);}return false;}/**
+ * Checks if `value` is a property name and not a property path.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @param {Object} [object] The object to query keys on.
+ * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
+ */function isKey(value,object){if(isArray(value)){return false;}var type=typeof value;if(type=='number'||type=='symbol'||type=='boolean'||value==null||isSymbol(value)){return true;}return reIsPlainProp.test(value)||!reIsDeepProp.test(value)||object!=null&&value in Object(object);}/**
+ * Checks if `value` is suitable for use as unique object key.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
+ */function isKeyable(value){var type=typeof value;return type=='string'||type=='number'||type=='symbol'||type=='boolean'?value!=='__proto__':value===null;}/**
+ * Checks if `func` has a lazy counterpart.
+ *
+ * @private
+ * @param {Function} func The function to check.
+ * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
+ * else `false`.
+ */function isLaziable(func){var funcName=getFuncName(func),other=lodash[funcName];if(typeof other!='function'||!(funcName in LazyWrapper.prototype)){return false;}if(func===other){return true;}var data=getData(other);return !!data&&func===data[0];}/**
+ * Checks if `func` has its source masked.
+ *
+ * @private
+ * @param {Function} func The function to check.
+ * @returns {boolean} Returns `true` if `func` is masked, else `false`.
+ */function isMasked(func){return !!maskSrcKey&&maskSrcKey in func;}/**
+ * Checks if `func` is capable of being masked.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
+ */var isMaskable=coreJsData?isFunction:stubFalse;/**
+ * Checks if `value` is likely a prototype object.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
+ */function isPrototype(value){var Ctor=value&&value.constructor,proto=typeof Ctor=='function'&&Ctor.prototype||objectProto;return value===proto;}/**
+ * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` if suitable for strict
+ * equality comparisons, else `false`.
+ */function isStrictComparable(value){return value===value&&!isObject(value);}/**
+ * A specialized version of `matchesProperty` for source values suitable
+ * for strict equality comparisons, i.e. `===`.
+ *
+ * @private
+ * @param {string} key The key of the property to get.
+ * @param {*} srcValue The value to match.
+ * @returns {Function} Returns the new spec function.
+ */function matchesStrictComparable(key,srcValue){return function(object){if(object==null){return false;}return object[key]===srcValue&&(srcValue!==undefined$1||key in Object(object));};}/**
+ * A specialized version of `_.memoize` which clears the memoized function's
+ * cache when it exceeds `MAX_MEMOIZE_SIZE`.
+ *
+ * @private
+ * @param {Function} func The function to have its output memoized.
+ * @returns {Function} Returns the new memoized function.
+ */function memoizeCapped(func){var result=memoize(func,function(key){if(cache.size===MAX_MEMOIZE_SIZE){cache.clear();}return key;});var cache=result.cache;return result;}/**
+ * Merges the function metadata of `source` into `data`.
+ *
+ * Merging metadata reduces the number of wrappers used to invoke a function.
+ * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
+ * may be applied regardless of execution order. Methods like `_.ary` and
+ * `_.rearg` modify function arguments, making the order in which they are
+ * executed important, preventing the merging of metadata. However, we make
+ * an exception for a safe combined case where curried functions have `_.ary`
+ * and or `_.rearg` applied.
+ *
+ * @private
+ * @param {Array} data The destination metadata.
+ * @param {Array} source The source metadata.
+ * @returns {Array} Returns `data`.
+ */function mergeData(data,source){var bitmask=data[1],srcBitmask=source[1],newBitmask=bitmask|srcBitmask,isCommon=newBitmask<(WRAP_BIND_FLAG|WRAP_BIND_KEY_FLAG|WRAP_ARY_FLAG);var isCombo=srcBitmask==WRAP_ARY_FLAG&&bitmask==WRAP_CURRY_FLAG||srcBitmask==WRAP_ARY_FLAG&&bitmask==WRAP_REARG_FLAG&&data[7].length<=source[8]||srcBitmask==(WRAP_ARY_FLAG|WRAP_REARG_FLAG)&&source[7].length<=source[8]&&bitmask==WRAP_CURRY_FLAG;// Exit early if metadata can't be merged.
+if(!(isCommon||isCombo)){return data;}// Use source `thisArg` if available.
+if(srcBitmask&WRAP_BIND_FLAG){data[2]=source[2];// Set when currying a bound function.
+newBitmask|=bitmask&WRAP_BIND_FLAG?0:WRAP_CURRY_BOUND_FLAG;}// Compose partial arguments.
+var value=source[3];if(value){var partials=data[3];data[3]=partials?composeArgs(partials,value,source[4]):value;data[4]=partials?replaceHolders(data[3],PLACEHOLDER):source[4];}// Compose partial right arguments.
+value=source[5];if(value){partials=data[5];data[5]=partials?composeArgsRight(partials,value,source[6]):value;data[6]=partials?replaceHolders(data[5],PLACEHOLDER):source[6];}// Use source `argPos` if available.
+value=source[7];if(value){data[7]=value;}// Use source `ary` if it's smaller.
+if(srcBitmask&WRAP_ARY_FLAG){data[8]=data[8]==null?source[8]:nativeMin(data[8],source[8]);}// Use source `arity` if one is not provided.
+if(data[9]==null){data[9]=source[9];}// Use source `func` and merge bitmasks.
+data[0]=source[0];data[1]=newBitmask;return data;}/**
+ * This function is like
+ * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
+ * except that it includes inherited enumerable properties.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */function nativeKeysIn(object){var result=[];if(object!=null){for(var key in Object(object)){result.push(key);}}return result;}/**
+ * Converts `value` to a string using `Object.prototype.toString`.
+ *
+ * @private
+ * @param {*} value The value to convert.
+ * @returns {string} Returns the converted string.
+ */function objectToString(value){return nativeObjectToString.call(value);}/**
+ * A specialized version of `baseRest` which transforms the rest array.
+ *
+ * @private
+ * @param {Function} func The function to apply a rest parameter to.
+ * @param {number} [start=func.length-1] The start position of the rest parameter.
+ * @param {Function} transform The rest array transform.
+ * @returns {Function} Returns the new function.
+ */function overRest(func,start,transform){start=nativeMax(start===undefined$1?func.length-1:start,0);return function(){var args=arguments,index=-1,length=nativeMax(args.length-start,0),array=Array(length);while(++index<length){array[index]=args[start+index];}index=-1;var otherArgs=Array(start+1);while(++index<start){otherArgs[index]=args[index];}otherArgs[start]=transform(array);return apply(func,this,otherArgs);};}/**
+ * Gets the parent value at `path` of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array} path The path to get the parent value of.
+ * @returns {*} Returns the parent value.
+ */function parent(object,path){return path.length<2?object:baseGet(object,baseSlice(path,0,-1));}/**
+ * Reorder `array` according to the specified indexes where the element at
+ * the first index is assigned as the first element, the element at
+ * the second index is assigned as the second element, and so on.
+ *
+ * @private
+ * @param {Array} array The array to reorder.
+ * @param {Array} indexes The arranged array indexes.
+ * @returns {Array} Returns `array`.
+ */function reorder(array,indexes){var arrLength=array.length,length=nativeMin(indexes.length,arrLength),oldArray=copyArray(array);while(length--){var index=indexes[length];array[length]=isIndex(index,arrLength)?oldArray[index]:undefined$1;}return array;}/**
+ * Gets the value at `key`, unless `key` is "__proto__" or "constructor".
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {string} key The key of the property to get.
+ * @returns {*} Returns the property value.
+ */function safeGet(object,key){if(key==='constructor'&&typeof object[key]==='function'){return;}if(key=='__proto__'){return;}return object[key];}/**
+ * Sets metadata for `func`.
+ *
+ * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
+ * period of time, it will trip its breaker and transition to an identity
+ * function to avoid garbage collection pauses in V8. See
+ * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
+ * for more details.
+ *
+ * @private
+ * @param {Function} func The function to associate metadata with.
+ * @param {*} data The metadata.
+ * @returns {Function} Returns `func`.
+ */var setData=shortOut(baseSetData);/**
+ * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
+ *
+ * @private
+ * @param {Function} func The function to delay.
+ * @param {number} wait The number of milliseconds to delay invocation.
+ * @returns {number|Object} Returns the timer id or timeout object.
+ */var setTimeout=ctxSetTimeout||function(func,wait){return root.setTimeout(func,wait);};/**
+ * Sets the `toString` method of `func` to return `string`.
+ *
+ * @private
+ * @param {Function} func The function to modify.
+ * @param {Function} string The `toString` result.
+ * @returns {Function} Returns `func`.
+ */var setToString=shortOut(baseSetToString);/**
+ * Sets the `toString` method of `wrapper` to mimic the source of `reference`
+ * with wrapper details in a comment at the top of the source body.
+ *
+ * @private
+ * @param {Function} wrapper The function to modify.
+ * @param {Function} reference The reference function.
+ * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+ * @returns {Function} Returns `wrapper`.
+ */function setWrapToString(wrapper,reference,bitmask){var source=reference+'';return setToString(wrapper,insertWrapDetails(source,updateWrapDetails(getWrapDetails(source),bitmask)));}/**
+ * Creates a function that'll short out and invoke `identity` instead
+ * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
+ * milliseconds.
+ *
+ * @private
+ * @param {Function} func The function to restrict.
+ * @returns {Function} Returns the new shortable function.
+ */function shortOut(func){var count=0,lastCalled=0;return function(){var stamp=nativeNow(),remaining=HOT_SPAN-(stamp-lastCalled);lastCalled=stamp;if(remaining>0){if(++count>=HOT_COUNT){return arguments[0];}}else {count=0;}return func.apply(undefined$1,arguments);};}/**
+ * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
+ *
+ * @private
+ * @param {Array} array The array to shuffle.
+ * @param {number} [size=array.length] The size of `array`.
+ * @returns {Array} Returns `array`.
+ */function shuffleSelf(array,size){var index=-1,length=array.length,lastIndex=length-1;size=size===undefined$1?length:size;while(++index<size){var rand=baseRandom(index,lastIndex),value=array[rand];array[rand]=array[index];array[index]=value;}array.length=size;return array;}/**
+ * Converts `string` to a property path array.
+ *
+ * @private
+ * @param {string} string The string to convert.
+ * @returns {Array} Returns the property path array.
+ */var stringToPath=memoizeCapped(function(string){var result=[];if(string.charCodeAt(0)===46/* . */){result.push('');}string.replace(rePropName,function(match,number,quote,subString){result.push(quote?subString.replace(reEscapeChar,'$1'):number||match);});return result;});/**
+ * Converts `value` to a string key if it's not a string or symbol.
+ *
+ * @private
+ * @param {*} value The value to inspect.
+ * @returns {string|symbol} Returns the key.
+ */function toKey(value){if(typeof value=='string'||isSymbol(value)){return value;}var result=value+'';return result=='0'&&1/value==-INFINITY?'-0':result;}/**
+ * Converts `func` to its source code.
+ *
+ * @private
+ * @param {Function} func The function to convert.
+ * @returns {string} Returns the source code.
+ */function toSource(func){if(func!=null){try{return funcToString.call(func);}catch(e){}try{return func+'';}catch(e){}}return '';}/**
+ * Updates wrapper `details` based on `bitmask` flags.
+ *
+ * @private
+ * @returns {Array} details The details to modify.
+ * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+ * @returns {Array} Returns `details`.
+ */function updateWrapDetails(details,bitmask){arrayEach(wrapFlags,function(pair){var value='_.'+pair[0];if(bitmask&pair[1]&&!arrayIncludes(details,value)){details.push(value);}});return details.sort();}/**
+ * Creates a clone of `wrapper`.
+ *
+ * @private
+ * @param {Object} wrapper The wrapper to clone.
+ * @returns {Object} Returns the cloned wrapper.
+ */function wrapperClone(wrapper){if(wrapper instanceof LazyWrapper){return wrapper.clone();}var result=new LodashWrapper(wrapper.__wrapped__,wrapper.__chain__);result.__actions__=copyArray(wrapper.__actions__);result.__index__=wrapper.__index__;result.__values__=wrapper.__values__;return result;}/*------------------------------------------------------------------------*/ /**
+ * Creates an array of elements split into groups the length of `size`.
+ * If `array` can't be split evenly, the final chunk will be the remaining
+ * elements.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to process.
+ * @param {number} [size=1] The length of each chunk
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Array} Returns the new array of chunks.
+ * @example
+ *
+ * _.chunk(['a', 'b', 'c', 'd'], 2);
+ * // => [['a', 'b'], ['c', 'd']]
+ *
+ * _.chunk(['a', 'b', 'c', 'd'], 3);
+ * // => [['a', 'b', 'c'], ['d']]
+ */function chunk(array,size,guard){if(guard?isIterateeCall(array,size,guard):size===undefined$1){size=1;}else {size=nativeMax(toInteger(size),0);}var length=array==null?0:array.length;if(!length||size<1){return [];}var index=0,resIndex=0,result=Array(nativeCeil(length/size));while(index<length){result[resIndex++]=baseSlice(array,index,index+=size);}return result;}/**
+ * Creates an array with all falsey values removed. The values `false`, `null`,
+ * `0`, `""`, `undefined`, and `NaN` are falsey.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to compact.
+ * @returns {Array} Returns the new array of filtered values.
+ * @example
+ *
+ * _.compact([0, 1, false, 2, '', 3]);
+ * // => [1, 2, 3]
+ */function compact(array){var index=-1,length=array==null?0:array.length,resIndex=0,result=[];while(++index<length){var value=array[index];if(value){result[resIndex++]=value;}}return result;}/**
+ * Creates a new array concatenating `array` with any additional arrays
+ * and/or values.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to concatenate.
+ * @param {...*} [values] The values to concatenate.
+ * @returns {Array} Returns the new concatenated array.
+ * @example
+ *
+ * var array = [1];
+ * var other = _.concat(array, 2, [3], [[4]]);
+ *
+ * console.log(other);
+ * // => [1, 2, 3, [4]]
+ *
+ * console.log(array);
+ * // => [1]
+ */function concat(){var length=arguments.length;if(!length){return [];}var args=Array(length-1),array=arguments[0],index=length;while(index--){args[index-1]=arguments[index];}return arrayPush(isArray(array)?copyArray(array):[array],baseFlatten(args,1));}/**
+ * Creates an array of `array` values not included in the other given arrays
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons. The order and references of result values are
+ * determined by the first array.
+ *
+ * **Note:** Unlike `_.pullAll`, this method returns a new array.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {...Array} [values] The values to exclude.
+ * @returns {Array} Returns the new array of filtered values.
+ * @see _.without, _.xor
+ * @example
+ *
+ * _.difference([2, 1], [2, 3]);
+ * // => [1]
+ */var difference=baseRest(function(array,values){return isArrayLikeObject(array)?baseDifference(array,baseFlatten(values,1,isArrayLikeObject,true)):[];});/**
+ * This method is like `_.difference` except that it accepts `iteratee` which
+ * is invoked for each element of `array` and `values` to generate the criterion
+ * by which they're compared. The order and references of result values are
+ * determined by the first array. The iteratee is invoked with one argument:
+ * (value).
+ *
+ * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {...Array} [values] The values to exclude.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new array of filtered values.
+ * @example
+ *
+ * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
+ * // => [1.2]
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
+ * // => [{ 'x': 2 }]
+ */var differenceBy=baseRest(function(array,values){var iteratee=last(values);if(isArrayLikeObject(iteratee)){iteratee=undefined$1;}return isArrayLikeObject(array)?baseDifference(array,baseFlatten(values,1,isArrayLikeObject,true),getIteratee(iteratee,2)):[];});/**
+ * This method is like `_.difference` except that it accepts `comparator`
+ * which is invoked to compare elements of `array` to `values`. The order and
+ * references of result values are determined by the first array. The comparator
+ * is invoked with two arguments: (arrVal, othVal).
+ *
+ * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {...Array} [values] The values to exclude.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of filtered values.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+ *
+ * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
+ * // => [{ 'x': 2, 'y': 1 }]
+ */var differenceWith=baseRest(function(array,values){var comparator=last(values);if(isArrayLikeObject(comparator)){comparator=undefined$1;}return isArrayLikeObject(array)?baseDifference(array,baseFlatten(values,1,isArrayLikeObject,true),undefined$1,comparator):[];});/**
+ * Creates a slice of `array` with `n` elements dropped from the beginning.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.5.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {number} [n=1] The number of elements to drop.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * _.drop([1, 2, 3]);
+ * // => [2, 3]
+ *
+ * _.drop([1, 2, 3], 2);
+ * // => [3]
+ *
+ * _.drop([1, 2, 3], 5);
+ * // => []
+ *
+ * _.drop([1, 2, 3], 0);
+ * // => [1, 2, 3]
+ */function drop(array,n,guard){var length=array==null?0:array.length;if(!length){return [];}n=guard||n===undefined$1?1:toInteger(n);return baseSlice(array,n<0?0:n,length);}/**
+ * Creates a slice of `array` with `n` elements dropped from the end.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {number} [n=1] The number of elements to drop.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * _.dropRight([1, 2, 3]);
+ * // => [1, 2]
+ *
+ * _.dropRight([1, 2, 3], 2);
+ * // => [1]
+ *
+ * _.dropRight([1, 2, 3], 5);
+ * // => []
+ *
+ * _.dropRight([1, 2, 3], 0);
+ * // => [1, 2, 3]
+ */function dropRight(array,n,guard){var length=array==null?0:array.length;if(!length){return [];}n=guard||n===undefined$1?1:toInteger(n);n=length-n;return baseSlice(array,0,n<0?0:n);}/**
+ * Creates a slice of `array` excluding elements dropped from the end.
+ * Elements are dropped until `predicate` returns falsey. The predicate is
+ * invoked with three arguments: (value, index, array).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': true },
+ * { 'user': 'fred', 'active': false },
+ * { 'user': 'pebbles', 'active': false }
+ * ];
+ *
+ * _.dropRightWhile(users, function(o) { return !o.active; });
+ * // => objects for ['barney']
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
+ * // => objects for ['barney', 'fred']
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.dropRightWhile(users, ['active', false]);
+ * // => objects for ['barney']
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.dropRightWhile(users, 'active');
+ * // => objects for ['barney', 'fred', 'pebbles']
+ */function dropRightWhile(array,predicate){return array&&array.length?baseWhile(array,getIteratee(predicate,3),true,true):[];}/**
+ * Creates a slice of `array` excluding elements dropped from the beginning.
+ * Elements are dropped until `predicate` returns falsey. The predicate is
+ * invoked with three arguments: (value, index, array).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': false },
+ * { 'user': 'fred', 'active': false },
+ * { 'user': 'pebbles', 'active': true }
+ * ];
+ *
+ * _.dropWhile(users, function(o) { return !o.active; });
+ * // => objects for ['pebbles']
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.dropWhile(users, { 'user': 'barney', 'active': false });
+ * // => objects for ['fred', 'pebbles']
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.dropWhile(users, ['active', false]);
+ * // => objects for ['pebbles']
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.dropWhile(users, 'active');
+ * // => objects for ['barney', 'fred', 'pebbles']
+ */function dropWhile(array,predicate){return array&&array.length?baseWhile(array,getIteratee(predicate,3),true):[];}/**
+ * Fills elements of `array` with `value` from `start` up to, but not
+ * including, `end`.
+ *
+ * **Note:** This method mutates `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.2.0
+ * @category Array
+ * @param {Array} array The array to fill.
+ * @param {*} value The value to fill `array` with.
+ * @param {number} [start=0] The start position.
+ * @param {number} [end=array.length] The end position.
+ * @returns {Array} Returns `array`.
+ * @example
+ *
+ * var array = [1, 2, 3];
+ *
+ * _.fill(array, 'a');
+ * console.log(array);
+ * // => ['a', 'a', 'a']
+ *
+ * _.fill(Array(3), 2);
+ * // => [2, 2, 2]
+ *
+ * _.fill([4, 6, 8, 10], '*', 1, 3);
+ * // => [4, '*', '*', 10]
+ */function fill(array,value,start,end){var length=array==null?0:array.length;if(!length){return [];}if(start&&typeof start!='number'&&isIterateeCall(array,value,start)){start=0;end=length;}return baseFill(array,value,start,end);}/**
+ * This method is like `_.find` except that it returns the index of the first
+ * element `predicate` returns truthy for instead of the element itself.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.1.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @param {number} [fromIndex=0] The index to search from.
+ * @returns {number} Returns the index of the found element, else `-1`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': false },
+ * { 'user': 'fred', 'active': false },
+ * { 'user': 'pebbles', 'active': true }
+ * ];
+ *
+ * _.findIndex(users, function(o) { return o.user == 'barney'; });
+ * // => 0
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.findIndex(users, { 'user': 'fred', 'active': false });
+ * // => 1
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.findIndex(users, ['active', false]);
+ * // => 0
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.findIndex(users, 'active');
+ * // => 2
+ */function findIndex(array,predicate,fromIndex){var length=array==null?0:array.length;if(!length){return -1;}var index=fromIndex==null?0:toInteger(fromIndex);if(index<0){index=nativeMax(length+index,0);}return baseFindIndex(array,getIteratee(predicate,3),index);}/**
+ * This method is like `_.findIndex` except that it iterates over elements
+ * of `collection` from right to left.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @param {number} [fromIndex=array.length-1] The index to search from.
+ * @returns {number} Returns the index of the found element, else `-1`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': true },
+ * { 'user': 'fred', 'active': false },
+ * { 'user': 'pebbles', 'active': false }
+ * ];
+ *
+ * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
+ * // => 2
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.findLastIndex(users, { 'user': 'barney', 'active': true });
+ * // => 0
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.findLastIndex(users, ['active', false]);
+ * // => 2
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.findLastIndex(users, 'active');
+ * // => 0
+ */function findLastIndex(array,predicate,fromIndex){var length=array==null?0:array.length;if(!length){return -1;}var index=length-1;if(fromIndex!==undefined$1){index=toInteger(fromIndex);index=fromIndex<0?nativeMax(length+index,0):nativeMin(index,length-1);}return baseFindIndex(array,getIteratee(predicate,3),index,true);}/**
+ * Flattens `array` a single level deep.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to flatten.
+ * @returns {Array} Returns the new flattened array.
+ * @example
+ *
+ * _.flatten([1, [2, [3, [4]], 5]]);
+ * // => [1, 2, [3, [4]], 5]
+ */function flatten(array){var length=array==null?0:array.length;return length?baseFlatten(array,1):[];}/**
+ * Recursively flattens `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to flatten.
+ * @returns {Array} Returns the new flattened array.
+ * @example
+ *
+ * _.flattenDeep([1, [2, [3, [4]], 5]]);
+ * // => [1, 2, 3, 4, 5]
+ */function flattenDeep(array){var length=array==null?0:array.length;return length?baseFlatten(array,INFINITY):[];}/**
+ * Recursively flatten `array` up to `depth` times.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.4.0
+ * @category Array
+ * @param {Array} array The array to flatten.
+ * @param {number} [depth=1] The maximum recursion depth.
+ * @returns {Array} Returns the new flattened array.
+ * @example
+ *
+ * var array = [1, [2, [3, [4]], 5]];
+ *
+ * _.flattenDepth(array, 1);
+ * // => [1, 2, [3, [4]], 5]
+ *
+ * _.flattenDepth(array, 2);
+ * // => [1, 2, 3, [4], 5]
+ */function flattenDepth(array,depth){var length=array==null?0:array.length;if(!length){return [];}depth=depth===undefined$1?1:toInteger(depth);return baseFlatten(array,depth);}/**
+ * The inverse of `_.toPairs`; this method returns an object composed
+ * from key-value `pairs`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} pairs The key-value pairs.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * _.fromPairs([['a', 1], ['b', 2]]);
+ * // => { 'a': 1, 'b': 2 }
+ */function fromPairs(pairs){var index=-1,length=pairs==null?0:pairs.length,result={};while(++index<length){var pair=pairs[index];result[pair[0]]=pair[1];}return result;}/**
+ * Gets the first element of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @alias first
+ * @category Array
+ * @param {Array} array The array to query.
+ * @returns {*} Returns the first element of `array`.
+ * @example
+ *
+ * _.head([1, 2, 3]);
+ * // => 1
+ *
+ * _.head([]);
+ * // => undefined
+ */function head(array){return array&&array.length?array[0]:undefined$1;}/**
+ * Gets the index at which the first occurrence of `value` is found in `array`
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons. If `fromIndex` is negative, it's used as the
+ * offset from the end of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {*} value The value to search for.
+ * @param {number} [fromIndex=0] The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ * @example
+ *
+ * _.indexOf([1, 2, 1, 2], 2);
+ * // => 1
+ *
+ * // Search from the `fromIndex`.
+ * _.indexOf([1, 2, 1, 2], 2, 2);
+ * // => 3
+ */function indexOf(array,value,fromIndex){var length=array==null?0:array.length;if(!length){return -1;}var index=fromIndex==null?0:toInteger(fromIndex);if(index<0){index=nativeMax(length+index,0);}return baseIndexOf(array,value,index);}/**
+ * Gets all but the last element of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * _.initial([1, 2, 3]);
+ * // => [1, 2]
+ */function initial(array){var length=array==null?0:array.length;return length?baseSlice(array,0,-1):[];}/**
+ * Creates an array of unique values that are included in all given arrays
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons. The order and references of result values are
+ * determined by the first array.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @returns {Array} Returns the new array of intersecting values.
+ * @example
+ *
+ * _.intersection([2, 1], [2, 3]);
+ * // => [2]
+ */var intersection=baseRest(function(arrays){var mapped=arrayMap(arrays,castArrayLikeObject);return mapped.length&&mapped[0]===arrays[0]?baseIntersection(mapped):[];});/**
+ * This method is like `_.intersection` except that it accepts `iteratee`
+ * which is invoked for each element of each `arrays` to generate the criterion
+ * by which they're compared. The order and references of result values are
+ * determined by the first array. The iteratee is invoked with one argument:
+ * (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new array of intersecting values.
+ * @example
+ *
+ * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
+ * // => [2.1]
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+ * // => [{ 'x': 1 }]
+ */var intersectionBy=baseRest(function(arrays){var iteratee=last(arrays),mapped=arrayMap(arrays,castArrayLikeObject);if(iteratee===last(mapped)){iteratee=undefined$1;}else {mapped.pop();}return mapped.length&&mapped[0]===arrays[0]?baseIntersection(mapped,getIteratee(iteratee,2)):[];});/**
+ * This method is like `_.intersection` except that it accepts `comparator`
+ * which is invoked to compare elements of `arrays`. The order and references
+ * of result values are determined by the first array. The comparator is
+ * invoked with two arguments: (arrVal, othVal).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of intersecting values.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+ * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
+ *
+ * _.intersectionWith(objects, others, _.isEqual);
+ * // => [{ 'x': 1, 'y': 2 }]
+ */var intersectionWith=baseRest(function(arrays){var comparator=last(arrays),mapped=arrayMap(arrays,castArrayLikeObject);comparator=typeof comparator=='function'?comparator:undefined$1;if(comparator){mapped.pop();}return mapped.length&&mapped[0]===arrays[0]?baseIntersection(mapped,undefined$1,comparator):[];});/**
+ * Converts all elements in `array` into a string separated by `separator`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to convert.
+ * @param {string} [separator=','] The element separator.
+ * @returns {string} Returns the joined string.
+ * @example
+ *
+ * _.join(['a', 'b', 'c'], '~');
+ * // => 'a~b~c'
+ */function join(array,separator){return array==null?'':nativeJoin.call(array,separator);}/**
+ * Gets the last element of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @returns {*} Returns the last element of `array`.
+ * @example
+ *
+ * _.last([1, 2, 3]);
+ * // => 3
+ */function last(array){var length=array==null?0:array.length;return length?array[length-1]:undefined$1;}/**
+ * This method is like `_.indexOf` except that it iterates over elements of
+ * `array` from right to left.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {*} value The value to search for.
+ * @param {number} [fromIndex=array.length-1] The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ * @example
+ *
+ * _.lastIndexOf([1, 2, 1, 2], 2);
+ * // => 3
+ *
+ * // Search from the `fromIndex`.
+ * _.lastIndexOf([1, 2, 1, 2], 2, 2);
+ * // => 1
+ */function lastIndexOf(array,value,fromIndex){var length=array==null?0:array.length;if(!length){return -1;}var index=length;if(fromIndex!==undefined$1){index=toInteger(fromIndex);index=index<0?nativeMax(length+index,0):nativeMin(index,length-1);}return value===value?strictLastIndexOf(array,value,index):baseFindIndex(array,baseIsNaN,index,true);}/**
+ * Gets the element at index `n` of `array`. If `n` is negative, the nth
+ * element from the end is returned.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.11.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {number} [n=0] The index of the element to return.
+ * @returns {*} Returns the nth element of `array`.
+ * @example
+ *
+ * var array = ['a', 'b', 'c', 'd'];
+ *
+ * _.nth(array, 1);
+ * // => 'b'
+ *
+ * _.nth(array, -2);
+ * // => 'c';
+ */function nth(array,n){return array&&array.length?baseNth(array,toInteger(n)):undefined$1;}/**
+ * Removes all given values from `array` using
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons.
+ *
+ * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
+ * to remove elements from an array by predicate.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @param {...*} [values] The values to remove.
+ * @returns {Array} Returns `array`.
+ * @example
+ *
+ * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
+ *
+ * _.pull(array, 'a', 'c');
+ * console.log(array);
+ * // => ['b', 'b']
+ */var pull=baseRest(pullAll);/**
+ * This method is like `_.pull` except that it accepts an array of values to remove.
+ *
+ * **Note:** Unlike `_.difference`, this method mutates `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to remove.
+ * @returns {Array} Returns `array`.
+ * @example
+ *
+ * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
+ *
+ * _.pullAll(array, ['a', 'c']);
+ * console.log(array);
+ * // => ['b', 'b']
+ */function pullAll(array,values){return array&&array.length&&values&&values.length?basePullAll(array,values):array;}/**
+ * This method is like `_.pullAll` except that it accepts `iteratee` which is
+ * invoked for each element of `array` and `values` to generate the criterion
+ * by which they're compared. The iteratee is invoked with one argument: (value).
+ *
+ * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to remove.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns `array`.
+ * @example
+ *
+ * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
+ *
+ * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
+ * console.log(array);
+ * // => [{ 'x': 2 }]
+ */function pullAllBy(array,values,iteratee){return array&&array.length&&values&&values.length?basePullAll(array,values,getIteratee(iteratee,2)):array;}/**
+ * This method is like `_.pullAll` except that it accepts `comparator` which
+ * is invoked to compare elements of `array` to `values`. The comparator is
+ * invoked with two arguments: (arrVal, othVal).
+ *
+ * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.6.0
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to remove.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns `array`.
+ * @example
+ *
+ * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
+ *
+ * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
+ * console.log(array);
+ * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
+ */function pullAllWith(array,values,comparator){return array&&array.length&&values&&values.length?basePullAll(array,values,undefined$1,comparator):array;}/**
+ * Removes elements from `array` corresponding to `indexes` and returns an
+ * array of removed elements.
+ *
+ * **Note:** Unlike `_.at`, this method mutates `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @param {...(number|number[])} [indexes] The indexes of elements to remove.
+ * @returns {Array} Returns the new array of removed elements.
+ * @example
+ *
+ * var array = ['a', 'b', 'c', 'd'];
+ * var pulled = _.pullAt(array, [1, 3]);
+ *
+ * console.log(array);
+ * // => ['a', 'c']
+ *
+ * console.log(pulled);
+ * // => ['b', 'd']
+ */var pullAt=flatRest(function(array,indexes){var length=array==null?0:array.length,result=baseAt(array,indexes);basePullAt(array,arrayMap(indexes,function(index){return isIndex(index,length)?+index:index;}).sort(compareAscending));return result;});/**
+ * Removes all elements from `array` that `predicate` returns truthy for
+ * and returns an array of the removed elements. The predicate is invoked
+ * with three arguments: (value, index, array).
+ *
+ * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
+ * to pull elements from an array by value.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the new array of removed elements.
+ * @example
+ *
+ * var array = [1, 2, 3, 4];
+ * var evens = _.remove(array, function(n) {
+ * return n % 2 == 0;
+ * });
+ *
+ * console.log(array);
+ * // => [1, 3]
+ *
+ * console.log(evens);
+ * // => [2, 4]
+ */function remove(array,predicate){var result=[];if(!(array&&array.length)){return result;}var index=-1,indexes=[],length=array.length;predicate=getIteratee(predicate,3);while(++index<length){var value=array[index];if(predicate(value,index,array)){result.push(value);indexes.push(index);}}basePullAt(array,indexes);return result;}/**
+ * Reverses `array` so that the first element becomes the last, the second
+ * element becomes the second to last, and so on.
+ *
+ * **Note:** This method mutates `array` and is based on
+ * [`Array#reverse`](https://mdn.io/Array/reverse).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @returns {Array} Returns `array`.
+ * @example
+ *
+ * var array = [1, 2, 3];
+ *
+ * _.reverse(array);
+ * // => [3, 2, 1]
+ *
+ * console.log(array);
+ * // => [3, 2, 1]
+ */function reverse(array){return array==null?array:nativeReverse.call(array);}/**
+ * Creates a slice of `array` from `start` up to, but not including, `end`.
+ *
+ * **Note:** This method is used instead of
+ * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
+ * returned.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to slice.
+ * @param {number} [start=0] The start position.
+ * @param {number} [end=array.length] The end position.
+ * @returns {Array} Returns the slice of `array`.
+ */function slice(array,start,end){var length=array==null?0:array.length;if(!length){return [];}if(end&&typeof end!='number'&&isIterateeCall(array,start,end)){start=0;end=length;}else {start=start==null?0:toInteger(start);end=end===undefined$1?length:toInteger(end);}return baseSlice(array,start,end);}/**
+ * Uses a binary search to determine the lowest index at which `value`
+ * should be inserted into `array` in order to maintain its sort order.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @returns {number} Returns the index at which `value` should be inserted
+ * into `array`.
+ * @example
+ *
+ * _.sortedIndex([30, 50], 40);
+ * // => 1
+ */function sortedIndex(array,value){return baseSortedIndex(array,value);}/**
+ * This method is like `_.sortedIndex` except that it accepts `iteratee`
+ * which is invoked for `value` and each element of `array` to compute their
+ * sort ranking. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {number} Returns the index at which `value` should be inserted
+ * into `array`.
+ * @example
+ *
+ * var objects = [{ 'x': 4 }, { 'x': 5 }];
+ *
+ * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
+ * // => 0
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
+ * // => 0
+ */function sortedIndexBy(array,value,iteratee){return baseSortedIndexBy(array,value,getIteratee(iteratee,2));}/**
+ * This method is like `_.indexOf` except that it performs a binary
+ * search on a sorted `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {*} value The value to search for.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ * @example
+ *
+ * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
+ * // => 1
+ */function sortedIndexOf(array,value){var length=array==null?0:array.length;if(length){var index=baseSortedIndex(array,value);if(index<length&&eq(array[index],value)){return index;}}return -1;}/**
+ * This method is like `_.sortedIndex` except that it returns the highest
+ * index at which `value` should be inserted into `array` in order to
+ * maintain its sort order.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @returns {number} Returns the index at which `value` should be inserted
+ * into `array`.
+ * @example
+ *
+ * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
+ * // => 4
+ */function sortedLastIndex(array,value){return baseSortedIndex(array,value,true);}/**
+ * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
+ * which is invoked for `value` and each element of `array` to compute their
+ * sort ranking. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {number} Returns the index at which `value` should be inserted
+ * into `array`.
+ * @example
+ *
+ * var objects = [{ 'x': 4 }, { 'x': 5 }];
+ *
+ * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
+ * // => 1
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
+ * // => 1
+ */function sortedLastIndexBy(array,value,iteratee){return baseSortedIndexBy(array,value,getIteratee(iteratee,2),true);}/**
+ * This method is like `_.lastIndexOf` except that it performs a binary
+ * search on a sorted `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {*} value The value to search for.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ * @example
+ *
+ * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
+ * // => 3
+ */function sortedLastIndexOf(array,value){var length=array==null?0:array.length;if(length){var index=baseSortedIndex(array,value,true)-1;if(eq(array[index],value)){return index;}}return -1;}/**
+ * This method is like `_.uniq` except that it's designed and optimized
+ * for sorted arrays.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
+ *
+ * _.sortedUniq([1, 1, 2]);
+ * // => [1, 2]
+ */function sortedUniq(array){return array&&array.length?baseSortedUniq(array):[];}/**
+ * This method is like `_.uniqBy` except that it's designed and optimized
+ * for sorted arrays.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
+ *
+ * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
+ * // => [1.1, 2.3]
+ */function sortedUniqBy(array,iteratee){return array&&array.length?baseSortedUniq(array,getIteratee(iteratee,2)):[];}/**
+ * Gets all but the first element of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * _.tail([1, 2, 3]);
+ * // => [2, 3]
+ */function tail(array){var length=array==null?0:array.length;return length?baseSlice(array,1,length):[];}/**
+ * Creates a slice of `array` with `n` elements taken from the beginning.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {number} [n=1] The number of elements to take.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * _.take([1, 2, 3]);
+ * // => [1]
+ *
+ * _.take([1, 2, 3], 2);
+ * // => [1, 2]
+ *
+ * _.take([1, 2, 3], 5);
+ * // => [1, 2, 3]
+ *
+ * _.take([1, 2, 3], 0);
+ * // => []
+ */function take(array,n,guard){if(!(array&&array.length)){return [];}n=guard||n===undefined$1?1:toInteger(n);return baseSlice(array,0,n<0?0:n);}/**
+ * Creates a slice of `array` with `n` elements taken from the end.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {number} [n=1] The number of elements to take.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * _.takeRight([1, 2, 3]);
+ * // => [3]
+ *
+ * _.takeRight([1, 2, 3], 2);
+ * // => [2, 3]
+ *
+ * _.takeRight([1, 2, 3], 5);
+ * // => [1, 2, 3]
+ *
+ * _.takeRight([1, 2, 3], 0);
+ * // => []
+ */function takeRight(array,n,guard){var length=array==null?0:array.length;if(!length){return [];}n=guard||n===undefined$1?1:toInteger(n);n=length-n;return baseSlice(array,n<0?0:n,length);}/**
+ * Creates a slice of `array` with elements taken from the end. Elements are
+ * taken until `predicate` returns falsey. The predicate is invoked with
+ * three arguments: (value, index, array).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': true },
+ * { 'user': 'fred', 'active': false },
+ * { 'user': 'pebbles', 'active': false }
+ * ];
+ *
+ * _.takeRightWhile(users, function(o) { return !o.active; });
+ * // => objects for ['fred', 'pebbles']
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
+ * // => objects for ['pebbles']
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.takeRightWhile(users, ['active', false]);
+ * // => objects for ['fred', 'pebbles']
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.takeRightWhile(users, 'active');
+ * // => []
+ */function takeRightWhile(array,predicate){return array&&array.length?baseWhile(array,getIteratee(predicate,3),false,true):[];}/**
+ * Creates a slice of `array` with elements taken from the beginning. Elements
+ * are taken until `predicate` returns falsey. The predicate is invoked with
+ * three arguments: (value, index, array).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': false },
+ * { 'user': 'fred', 'active': false },
+ * { 'user': 'pebbles', 'active': true }
+ * ];
+ *
+ * _.takeWhile(users, function(o) { return !o.active; });
+ * // => objects for ['barney', 'fred']
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.takeWhile(users, { 'user': 'barney', 'active': false });
+ * // => objects for ['barney']
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.takeWhile(users, ['active', false]);
+ * // => objects for ['barney', 'fred']
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.takeWhile(users, 'active');
+ * // => []
+ */function takeWhile(array,predicate){return array&&array.length?baseWhile(array,getIteratee(predicate,3)):[];}/**
+ * Creates an array of unique values, in order, from all given arrays using
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @returns {Array} Returns the new array of combined values.
+ * @example
+ *
+ * _.union([2], [1, 2]);
+ * // => [2, 1]
+ */var union=baseRest(function(arrays){return baseUniq(baseFlatten(arrays,1,isArrayLikeObject,true));});/**
+ * This method is like `_.union` except that it accepts `iteratee` which is
+ * invoked for each element of each `arrays` to generate the criterion by
+ * which uniqueness is computed. Result values are chosen from the first
+ * array in which the value occurs. The iteratee is invoked with one argument:
+ * (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new array of combined values.
+ * @example
+ *
+ * _.unionBy([2.1], [1.2, 2.3], Math.floor);
+ * // => [2.1, 1.2]
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+ * // => [{ 'x': 1 }, { 'x': 2 }]
+ */var unionBy=baseRest(function(arrays){var iteratee=last(arrays);if(isArrayLikeObject(iteratee)){iteratee=undefined$1;}return baseUniq(baseFlatten(arrays,1,isArrayLikeObject,true),getIteratee(iteratee,2));});/**
+ * This method is like `_.union` except that it accepts `comparator` which
+ * is invoked to compare elements of `arrays`. Result values are chosen from
+ * the first array in which the value occurs. The comparator is invoked
+ * with two arguments: (arrVal, othVal).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of combined values.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+ * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
+ *
+ * _.unionWith(objects, others, _.isEqual);
+ * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
+ */var unionWith=baseRest(function(arrays){var comparator=last(arrays);comparator=typeof comparator=='function'?comparator:undefined$1;return baseUniq(baseFlatten(arrays,1,isArrayLikeObject,true),undefined$1,comparator);});/**
+ * Creates a duplicate-free version of an array, using
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons, in which only the first occurrence of each element
+ * is kept. The order of result values is determined by the order they occur
+ * in the array.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
+ *
+ * _.uniq([2, 1, 2]);
+ * // => [2, 1]
+ */function uniq(array){return array&&array.length?baseUniq(array):[];}/**
+ * This method is like `_.uniq` except that it accepts `iteratee` which is
+ * invoked for each element in `array` to generate the criterion by which
+ * uniqueness is computed. The order of result values is determined by the
+ * order they occur in the array. The iteratee is invoked with one argument:
+ * (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
+ *
+ * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
+ * // => [2.1, 1.2]
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
+ * // => [{ 'x': 1 }, { 'x': 2 }]
+ */function uniqBy(array,iteratee){return array&&array.length?baseUniq(array,getIteratee(iteratee,2)):[];}/**
+ * This method is like `_.uniq` except that it accepts `comparator` which
+ * is invoked to compare elements of `array`. The order of result values is
+ * determined by the order they occur in the array.The comparator is invoked
+ * with two arguments: (arrVal, othVal).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
+ *
+ * _.uniqWith(objects, _.isEqual);
+ * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
+ */function uniqWith(array,comparator){comparator=typeof comparator=='function'?comparator:undefined$1;return array&&array.length?baseUniq(array,undefined$1,comparator):[];}/**
+ * This method is like `_.zip` except that it accepts an array of grouped
+ * elements and creates an array regrouping the elements to their pre-zip
+ * configuration.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.2.0
+ * @category Array
+ * @param {Array} array The array of grouped elements to process.
+ * @returns {Array} Returns the new array of regrouped elements.
+ * @example
+ *
+ * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
+ * // => [['a', 1, true], ['b', 2, false]]
+ *
+ * _.unzip(zipped);
+ * // => [['a', 'b'], [1, 2], [true, false]]
+ */function unzip(array){if(!(array&&array.length)){return [];}var length=0;array=arrayFilter(array,function(group){if(isArrayLikeObject(group)){length=nativeMax(group.length,length);return true;}});return baseTimes(length,function(index){return arrayMap(array,baseProperty(index));});}/**
+ * This method is like `_.unzip` except that it accepts `iteratee` to specify
+ * how regrouped values should be combined. The iteratee is invoked with the
+ * elements of each group: (...group).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.8.0
+ * @category Array
+ * @param {Array} array The array of grouped elements to process.
+ * @param {Function} [iteratee=_.identity] The function to combine
+ * regrouped values.
+ * @returns {Array} Returns the new array of regrouped elements.
+ * @example
+ *
+ * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
+ * // => [[1, 10, 100], [2, 20, 200]]
+ *
+ * _.unzipWith(zipped, _.add);
+ * // => [3, 30, 300]
+ */function unzipWith(array,iteratee){if(!(array&&array.length)){return [];}var result=unzip(array);if(iteratee==null){return result;}return arrayMap(result,function(group){return apply(iteratee,undefined$1,group);});}/**
+ * Creates an array excluding all given values using
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons.
+ *
+ * **Note:** Unlike `_.pull`, this method returns a new array.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {...*} [values] The values to exclude.
+ * @returns {Array} Returns the new array of filtered values.
+ * @see _.difference, _.xor
+ * @example
+ *
+ * _.without([2, 1, 2, 3], 1, 2);
+ * // => [3]
+ */var without=baseRest(function(array,values){return isArrayLikeObject(array)?baseDifference(array,values):[];});/**
+ * Creates an array of unique values that is the
+ * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
+ * of the given arrays. The order of result values is determined by the order
+ * they occur in the arrays.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.4.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @returns {Array} Returns the new array of filtered values.
+ * @see _.difference, _.without
+ * @example
+ *
+ * _.xor([2, 1], [2, 3]);
+ * // => [1, 3]
+ */var xor=baseRest(function(arrays){return baseXor(arrayFilter(arrays,isArrayLikeObject));});/**
+ * This method is like `_.xor` except that it accepts `iteratee` which is
+ * invoked for each element of each `arrays` to generate the criterion by
+ * which by which they're compared. The order of result values is determined
+ * by the order they occur in the arrays. The iteratee is invoked with one
+ * argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new array of filtered values.
+ * @example
+ *
+ * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
+ * // => [1.2, 3.4]
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+ * // => [{ 'x': 2 }]
+ */var xorBy=baseRest(function(arrays){var iteratee=last(arrays);if(isArrayLikeObject(iteratee)){iteratee=undefined$1;}return baseXor(arrayFilter(arrays,isArrayLikeObject),getIteratee(iteratee,2));});/**
+ * This method is like `_.xor` except that it accepts `comparator` which is
+ * invoked to compare elements of `arrays`. The order of result values is
+ * determined by the order they occur in the arrays. The comparator is invoked
+ * with two arguments: (arrVal, othVal).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of filtered values.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+ * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
+ *
+ * _.xorWith(objects, others, _.isEqual);
+ * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
+ */var xorWith=baseRest(function(arrays){var comparator=last(arrays);comparator=typeof comparator=='function'?comparator:undefined$1;return baseXor(arrayFilter(arrays,isArrayLikeObject),undefined$1,comparator);});/**
+ * Creates an array of grouped elements, the first of which contains the
+ * first elements of the given arrays, the second of which contains the
+ * second elements of the given arrays, and so on.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to process.
+ * @returns {Array} Returns the new array of grouped elements.
+ * @example
+ *
+ * _.zip(['a', 'b'], [1, 2], [true, false]);
+ * // => [['a', 1, true], ['b', 2, false]]
+ */var zip=baseRest(unzip);/**
+ * This method is like `_.fromPairs` except that it accepts two arrays,
+ * one of property identifiers and one of corresponding values.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.4.0
+ * @category Array
+ * @param {Array} [props=[]] The property identifiers.
+ * @param {Array} [values=[]] The property values.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * _.zipObject(['a', 'b'], [1, 2]);
+ * // => { 'a': 1, 'b': 2 }
+ */function zipObject(props,values){return baseZipObject(props||[],values||[],assignValue);}/**
+ * This method is like `_.zipObject` except that it supports property paths.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.1.0
+ * @category Array
+ * @param {Array} [props=[]] The property identifiers.
+ * @param {Array} [values=[]] The property values.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
+ * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
+ */function zipObjectDeep(props,values){return baseZipObject(props||[],values||[],baseSet);}/**
+ * This method is like `_.zip` except that it accepts `iteratee` to specify
+ * how grouped values should be combined. The iteratee is invoked with the
+ * elements of each group: (...group).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.8.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to process.
+ * @param {Function} [iteratee=_.identity] The function to combine
+ * grouped values.
+ * @returns {Array} Returns the new array of grouped elements.
+ * @example
+ *
+ * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
+ * return a + b + c;
+ * });
+ * // => [111, 222]
+ */var zipWith=baseRest(function(arrays){var length=arrays.length,iteratee=length>1?arrays[length-1]:undefined$1;iteratee=typeof iteratee=='function'?(arrays.pop(),iteratee):undefined$1;return unzipWith(arrays,iteratee);});/*------------------------------------------------------------------------*/ /**
+ * Creates a `lodash` wrapper instance that wraps `value` with explicit method
+ * chain sequences enabled. The result of such sequences must be unwrapped
+ * with `_#value`.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.3.0
+ * @category Seq
+ * @param {*} value The value to wrap.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36 },
+ * { 'user': 'fred', 'age': 40 },
+ * { 'user': 'pebbles', 'age': 1 }
+ * ];
+ *
+ * var youngest = _
+ * .chain(users)
+ * .sortBy('age')
+ * .map(function(o) {
+ * return o.user + ' is ' + o.age;
+ * })
+ * .head()
+ * .value();
+ * // => 'pebbles is 1'
+ */function chain(value){var result=lodash(value);result.__chain__=true;return result;}/**
+ * This method invokes `interceptor` and returns `value`. The interceptor
+ * is invoked with one argument; (value). The purpose of this method is to
+ * "tap into" a method chain sequence in order to modify intermediate results.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Seq
+ * @param {*} value The value to provide to `interceptor`.
+ * @param {Function} interceptor The function to invoke.
+ * @returns {*} Returns `value`.
+ * @example
+ *
+ * _([1, 2, 3])
+ * .tap(function(array) {
+ * // Mutate input array.
+ * array.pop();
+ * })
+ * .reverse()
+ * .value();
+ * // => [2, 1]
+ */function tap(value,interceptor){interceptor(value);return value;}/**
+ * This method is like `_.tap` except that it returns the result of `interceptor`.
+ * The purpose of this method is to "pass thru" values replacing intermediate
+ * results in a method chain sequence.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Seq
+ * @param {*} value The value to provide to `interceptor`.
+ * @param {Function} interceptor The function to invoke.
+ * @returns {*} Returns the result of `interceptor`.
+ * @example
+ *
+ * _(' abc ')
+ * .chain()
+ * .trim()
+ * .thru(function(value) {
+ * return [value];
+ * })
+ * .value();
+ * // => ['abc']
+ */function thru(value,interceptor){return interceptor(value);}/**
+ * This method is the wrapper version of `_.at`.
+ *
+ * @name at
+ * @memberOf _
+ * @since 1.0.0
+ * @category Seq
+ * @param {...(string|string[])} [paths] The property paths to pick.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
+ *
+ * _(object).at(['a[0].b.c', 'a[1]']).value();
+ * // => [3, 4]
+ */var wrapperAt=flatRest(function(paths){var length=paths.length,start=length?paths[0]:0,value=this.__wrapped__,interceptor=function(object){return baseAt(object,paths);};if(length>1||this.__actions__.length||!(value instanceof LazyWrapper)||!isIndex(start)){return this.thru(interceptor);}value=value.slice(start,+start+(length?1:0));value.__actions__.push({'func':thru,'args':[interceptor],'thisArg':undefined$1});return new LodashWrapper(value,this.__chain__).thru(function(array){if(length&&!array.length){array.push(undefined$1);}return array;});});/**
+ * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
+ *
+ * @name chain
+ * @memberOf _
+ * @since 0.1.0
+ * @category Seq
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36 },
+ * { 'user': 'fred', 'age': 40 }
+ * ];
+ *
+ * // A sequence without explicit chaining.
+ * _(users).head();
+ * // => { 'user': 'barney', 'age': 36 }
+ *
+ * // A sequence with explicit chaining.
+ * _(users)
+ * .chain()
+ * .head()
+ * .pick('user')
+ * .value();
+ * // => { 'user': 'barney' }
+ */function wrapperChain(){return chain(this);}/**
+ * Executes the chain sequence and returns the wrapped result.
+ *
+ * @name commit
+ * @memberOf _
+ * @since 3.2.0
+ * @category Seq
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * var array = [1, 2];
+ * var wrapped = _(array).push(3);
+ *
+ * console.log(array);
+ * // => [1, 2]
+ *
+ * wrapped = wrapped.commit();
+ * console.log(array);
+ * // => [1, 2, 3]
+ *
+ * wrapped.last();
+ * // => 3
+ *
+ * console.log(array);
+ * // => [1, 2, 3]
+ */function wrapperCommit(){return new LodashWrapper(this.value(),this.__chain__);}/**
+ * Gets the next value on a wrapped object following the
+ * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
+ *
+ * @name next
+ * @memberOf _
+ * @since 4.0.0
+ * @category Seq
+ * @returns {Object} Returns the next iterator value.
+ * @example
+ *
+ * var wrapped = _([1, 2]);
+ *
+ * wrapped.next();
+ * // => { 'done': false, 'value': 1 }
+ *
+ * wrapped.next();
+ * // => { 'done': false, 'value': 2 }
+ *
+ * wrapped.next();
+ * // => { 'done': true, 'value': undefined }
+ */function wrapperNext(){if(this.__values__===undefined$1){this.__values__=toArray(this.value());}var done=this.__index__>=this.__values__.length,value=done?undefined$1:this.__values__[this.__index__++];return {'done':done,'value':value};}/**
+ * Enables the wrapper to be iterable.
+ *
+ * @name Symbol.iterator
+ * @memberOf _
+ * @since 4.0.0
+ * @category Seq
+ * @returns {Object} Returns the wrapper object.
+ * @example
+ *
+ * var wrapped = _([1, 2]);
+ *
+ * wrapped[Symbol.iterator]() === wrapped;
+ * // => true
+ *
+ * Array.from(wrapped);
+ * // => [1, 2]
+ */function wrapperToIterator(){return this;}/**
+ * Creates a clone of the chain sequence planting `value` as the wrapped value.
+ *
+ * @name plant
+ * @memberOf _
+ * @since 3.2.0
+ * @category Seq
+ * @param {*} value The value to plant.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * var wrapped = _([1, 2]).map(square);
+ * var other = wrapped.plant([3, 4]);
+ *
+ * other.value();
+ * // => [9, 16]
+ *
+ * wrapped.value();
+ * // => [1, 4]
+ */function wrapperPlant(value){var result,parent=this;while(parent instanceof baseLodash){var clone=wrapperClone(parent);clone.__index__=0;clone.__values__=undefined$1;if(result){previous.__wrapped__=clone;}else {result=clone;}var previous=clone;parent=parent.__wrapped__;}previous.__wrapped__=value;return result;}/**
+ * This method is the wrapper version of `_.reverse`.
+ *
+ * **Note:** This method mutates the wrapped array.
+ *
+ * @name reverse
+ * @memberOf _
+ * @since 0.1.0
+ * @category Seq
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * var array = [1, 2, 3];
+ *
+ * _(array).reverse().value()
+ * // => [3, 2, 1]
+ *
+ * console.log(array);
+ * // => [3, 2, 1]
+ */function wrapperReverse(){var value=this.__wrapped__;if(value instanceof LazyWrapper){var wrapped=value;if(this.__actions__.length){wrapped=new LazyWrapper(this);}wrapped=wrapped.reverse();wrapped.__actions__.push({'func':thru,'args':[reverse],'thisArg':undefined$1});return new LodashWrapper(wrapped,this.__chain__);}return this.thru(reverse);}/**
+ * Executes the chain sequence to resolve the unwrapped value.
+ *
+ * @name value
+ * @memberOf _
+ * @since 0.1.0
+ * @alias toJSON, valueOf
+ * @category Seq
+ * @returns {*} Returns the resolved unwrapped value.
+ * @example
+ *
+ * _([1, 2, 3]).value();
+ * // => [1, 2, 3]
+ */function wrapperValue(){return baseWrapperValue(this.__wrapped__,this.__actions__);}/*------------------------------------------------------------------------*/ /**
+ * Creates an object composed of keys generated from the results of running
+ * each element of `collection` thru `iteratee`. The corresponding value of
+ * each key is the number of times the key was returned by `iteratee`. The
+ * iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 0.5.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
+ * @returns {Object} Returns the composed aggregate object.
+ * @example
+ *
+ * _.countBy([6.1, 4.2, 6.3], Math.floor);
+ * // => { '4': 1, '6': 2 }
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.countBy(['one', 'two', 'three'], 'length');
+ * // => { '3': 2, '5': 1 }
+ */var countBy=createAggregator(function(result,value,key){if(hasOwnProperty.call(result,key)){++result[key];}else {baseAssignValue(result,key,1);}});/**
+ * Checks if `predicate` returns truthy for **all** elements of `collection`.
+ * Iteration is stopped once `predicate` returns falsey. The predicate is
+ * invoked with three arguments: (value, index|key, collection).
+ *
+ * **Note:** This method returns `true` for
+ * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
+ * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
+ * elements of empty collections.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {boolean} Returns `true` if all elements pass the predicate check,
+ * else `false`.
+ * @example
+ *
+ * _.every([true, 1, null, 'yes'], Boolean);
+ * // => false
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36, 'active': false },
+ * { 'user': 'fred', 'age': 40, 'active': false }
+ * ];
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.every(users, { 'user': 'barney', 'active': false });
+ * // => false
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.every(users, ['active', false]);
+ * // => true
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.every(users, 'active');
+ * // => false
+ */function every(collection,predicate,guard){var func=isArray(collection)?arrayEvery:baseEvery;if(guard&&isIterateeCall(collection,predicate,guard)){predicate=undefined$1;}return func(collection,getIteratee(predicate,3));}/**
+ * Iterates over elements of `collection`, returning an array of all elements
+ * `predicate` returns truthy for. The predicate is invoked with three
+ * arguments: (value, index|key, collection).
+ *
+ * **Note:** Unlike `_.remove`, this method returns a new array.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the new filtered array.
+ * @see _.reject
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36, 'active': true },
+ * { 'user': 'fred', 'age': 40, 'active': false }
+ * ];
+ *
+ * _.filter(users, function(o) { return !o.active; });
+ * // => objects for ['fred']
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.filter(users, { 'age': 36, 'active': true });
+ * // => objects for ['barney']
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.filter(users, ['active', false]);
+ * // => objects for ['fred']
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.filter(users, 'active');
+ * // => objects for ['barney']
+ *
+ * // Combining several predicates using `_.overEvery` or `_.overSome`.
+ * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]]));
+ * // => objects for ['fred', 'barney']
+ */function filter(collection,predicate){var func=isArray(collection)?arrayFilter:baseFilter;return func(collection,getIteratee(predicate,3));}/**
+ * Iterates over elements of `collection`, returning the first element
+ * `predicate` returns truthy for. The predicate is invoked with three
+ * arguments: (value, index|key, collection).
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to inspect.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @param {number} [fromIndex=0] The index to search from.
+ * @returns {*} Returns the matched element, else `undefined`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36, 'active': true },
+ * { 'user': 'fred', 'age': 40, 'active': false },
+ * { 'user': 'pebbles', 'age': 1, 'active': true }
+ * ];
+ *
+ * _.find(users, function(o) { return o.age < 40; });
+ * // => object for 'barney'
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.find(users, { 'age': 1, 'active': true });
+ * // => object for 'pebbles'
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.find(users, ['active', false]);
+ * // => object for 'fred'
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.find(users, 'active');
+ * // => object for 'barney'
+ */var find=createFind(findIndex);/**
+ * This method is like `_.find` except that it iterates over elements of
+ * `collection` from right to left.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to inspect.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @param {number} [fromIndex=collection.length-1] The index to search from.
+ * @returns {*} Returns the matched element, else `undefined`.
+ * @example
+ *
+ * _.findLast([1, 2, 3, 4], function(n) {
+ * return n % 2 == 1;
+ * });
+ * // => 3
+ */var findLast=createFind(findLastIndex);/**
+ * Creates a flattened array of values by running each element in `collection`
+ * thru `iteratee` and flattening the mapped results. The iteratee is invoked
+ * with three arguments: (value, index|key, collection).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the new flattened array.
+ * @example
+ *
+ * function duplicate(n) {
+ * return [n, n];
+ * }
+ *
+ * _.flatMap([1, 2], duplicate);
+ * // => [1, 1, 2, 2]
+ */function flatMap(collection,iteratee){return baseFlatten(map(collection,iteratee),1);}/**
+ * This method is like `_.flatMap` except that it recursively flattens the
+ * mapped results.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.7.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the new flattened array.
+ * @example
+ *
+ * function duplicate(n) {
+ * return [[[n, n]]];
+ * }
+ *
+ * _.flatMapDeep([1, 2], duplicate);
+ * // => [1, 1, 2, 2]
+ */function flatMapDeep(collection,iteratee){return baseFlatten(map(collection,iteratee),INFINITY);}/**
+ * This method is like `_.flatMap` except that it recursively flattens the
+ * mapped results up to `depth` times.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.7.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @param {number} [depth=1] The maximum recursion depth.
+ * @returns {Array} Returns the new flattened array.
+ * @example
+ *
+ * function duplicate(n) {
+ * return [[[n, n]]];
+ * }
+ *
+ * _.flatMapDepth([1, 2], duplicate, 2);
+ * // => [[1, 1], [2, 2]]
+ */function flatMapDepth(collection,iteratee,depth){depth=depth===undefined$1?1:toInteger(depth);return baseFlatten(map(collection,iteratee),depth);}/**
+ * Iterates over elements of `collection` and invokes `iteratee` for each element.
+ * The iteratee is invoked with three arguments: (value, index|key, collection).
+ * Iteratee functions may exit iteration early by explicitly returning `false`.
+ *
+ * **Note:** As with other "Collections" methods, objects with a "length"
+ * property are iterated like arrays. To avoid this behavior use `_.forIn`
+ * or `_.forOwn` for object iteration.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @alias each
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array|Object} Returns `collection`.
+ * @see _.forEachRight
+ * @example
+ *
+ * _.forEach([1, 2], function(value) {
+ * console.log(value);
+ * });
+ * // => Logs `1` then `2`.
+ *
+ * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
+ * console.log(key);
+ * });
+ * // => Logs 'a' then 'b' (iteration order is not guaranteed).
+ */function forEach(collection,iteratee){var func=isArray(collection)?arrayEach:baseEach;return func(collection,getIteratee(iteratee,3));}/**
+ * This method is like `_.forEach` except that it iterates over elements of
+ * `collection` from right to left.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @alias eachRight
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array|Object} Returns `collection`.
+ * @see _.forEach
+ * @example
+ *
+ * _.forEachRight([1, 2], function(value) {
+ * console.log(value);
+ * });
+ * // => Logs `2` then `1`.
+ */function forEachRight(collection,iteratee){var func=isArray(collection)?arrayEachRight:baseEachRight;return func(collection,getIteratee(iteratee,3));}/**
+ * Creates an object composed of keys generated from the results of running
+ * each element of `collection` thru `iteratee`. The order of grouped values
+ * is determined by the order they occur in `collection`. The corresponding
+ * value of each key is an array of elements responsible for generating the
+ * key. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
+ * @returns {Object} Returns the composed aggregate object.
+ * @example
+ *
+ * _.groupBy([6.1, 4.2, 6.3], Math.floor);
+ * // => { '4': [4.2], '6': [6.1, 6.3] }
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.groupBy(['one', 'two', 'three'], 'length');
+ * // => { '3': ['one', 'two'], '5': ['three'] }
+ */var groupBy=createAggregator(function(result,value,key){if(hasOwnProperty.call(result,key)){result[key].push(value);}else {baseAssignValue(result,key,[value]);}});/**
+ * Checks if `value` is in `collection`. If `collection` is a string, it's
+ * checked for a substring of `value`, otherwise
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * is used for equality comparisons. If `fromIndex` is negative, it's used as
+ * the offset from the end of `collection`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object|string} collection The collection to inspect.
+ * @param {*} value The value to search for.
+ * @param {number} [fromIndex=0] The index to search from.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
+ * @returns {boolean} Returns `true` if `value` is found, else `false`.
+ * @example
+ *
+ * _.includes([1, 2, 3], 1);
+ * // => true
+ *
+ * _.includes([1, 2, 3], 1, 2);
+ * // => false
+ *
+ * _.includes({ 'a': 1, 'b': 2 }, 1);
+ * // => true
+ *
+ * _.includes('abcd', 'bc');
+ * // => true
+ */function includes(collection,value,fromIndex,guard){collection=isArrayLike(collection)?collection:values(collection);fromIndex=fromIndex&&!guard?toInteger(fromIndex):0;var length=collection.length;if(fromIndex<0){fromIndex=nativeMax(length+fromIndex,0);}return isString(collection)?fromIndex<=length&&collection.indexOf(value,fromIndex)>-1:!!length&&baseIndexOf(collection,value,fromIndex)>-1;}/**
+ * Invokes the method at `path` of each element in `collection`, returning
+ * an array of the results of each invoked method. Any additional arguments
+ * are provided to each invoked method. If `path` is a function, it's invoked
+ * for, and `this` bound to, each element in `collection`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Array|Function|string} path The path of the method to invoke or
+ * the function invoked per iteration.
+ * @param {...*} [args] The arguments to invoke each method with.
+ * @returns {Array} Returns the array of results.
+ * @example
+ *
+ * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
+ * // => [[1, 5, 7], [1, 2, 3]]
+ *
+ * _.invokeMap([123, 456], String.prototype.split, '');
+ * // => [['1', '2', '3'], ['4', '5', '6']]
+ */var invokeMap=baseRest(function(collection,path,args){var index=-1,isFunc=typeof path=='function',result=isArrayLike(collection)?Array(collection.length):[];baseEach(collection,function(value){result[++index]=isFunc?apply(path,value,args):baseInvoke(value,path,args);});return result;});/**
+ * Creates an object composed of keys generated from the results of running
+ * each element of `collection` thru `iteratee`. The corresponding value of
+ * each key is the last element responsible for generating the key. The
+ * iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
+ * @returns {Object} Returns the composed aggregate object.
+ * @example
+ *
+ * var array = [
+ * { 'dir': 'left', 'code': 97 },
+ * { 'dir': 'right', 'code': 100 }
+ * ];
+ *
+ * _.keyBy(array, function(o) {
+ * return String.fromCharCode(o.code);
+ * });
+ * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
+ *
+ * _.keyBy(array, 'dir');
+ * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
+ */var keyBy=createAggregator(function(result,value,key){baseAssignValue(result,key,value);});/**
+ * Creates an array of values by running each element in `collection` thru
+ * `iteratee`. The iteratee is invoked with three arguments:
+ * (value, index|key, collection).
+ *
+ * Many lodash methods are guarded to work as iteratees for methods like
+ * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
+ *
+ * The guarded methods are:
+ * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
+ * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
+ * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
+ * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the new mapped array.
+ * @example
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * _.map([4, 8], square);
+ * // => [16, 64]
+ *
+ * _.map({ 'a': 4, 'b': 8 }, square);
+ * // => [16, 64] (iteration order is not guaranteed)
+ *
+ * var users = [
+ * { 'user': 'barney' },
+ * { 'user': 'fred' }
+ * ];
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.map(users, 'user');
+ * // => ['barney', 'fred']
+ */function map(collection,iteratee){var func=isArray(collection)?arrayMap:baseMap;return func(collection,getIteratee(iteratee,3));}/**
+ * This method is like `_.sortBy` except that it allows specifying the sort
+ * orders of the iteratees to sort by. If `orders` is unspecified, all values
+ * are sorted in ascending order. Otherwise, specify an order of "desc" for
+ * descending or "asc" for ascending sort order of corresponding values.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
+ * The iteratees to sort by.
+ * @param {string[]} [orders] The sort orders of `iteratees`.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
+ * @returns {Array} Returns the new sorted array.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'fred', 'age': 48 },
+ * { 'user': 'barney', 'age': 34 },
+ * { 'user': 'fred', 'age': 40 },
+ * { 'user': 'barney', 'age': 36 }
+ * ];
+ *
+ * // Sort by `user` in ascending order and by `age` in descending order.
+ * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
+ * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
+ */function orderBy(collection,iteratees,orders,guard){if(collection==null){return [];}if(!isArray(iteratees)){iteratees=iteratees==null?[]:[iteratees];}orders=guard?undefined$1:orders;if(!isArray(orders)){orders=orders==null?[]:[orders];}return baseOrderBy(collection,iteratees,orders);}/**
+ * Creates an array of elements split into two groups, the first of which
+ * contains elements `predicate` returns truthy for, the second of which
+ * contains elements `predicate` returns falsey for. The predicate is
+ * invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the array of grouped elements.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36, 'active': false },
+ * { 'user': 'fred', 'age': 40, 'active': true },
+ * { 'user': 'pebbles', 'age': 1, 'active': false }
+ * ];
+ *
+ * _.partition(users, function(o) { return o.active; });
+ * // => objects for [['fred'], ['barney', 'pebbles']]
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.partition(users, { 'age': 1, 'active': false });
+ * // => objects for [['pebbles'], ['barney', 'fred']]
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.partition(users, ['active', false]);
+ * // => objects for [['barney', 'pebbles'], ['fred']]
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.partition(users, 'active');
+ * // => objects for [['fred'], ['barney', 'pebbles']]
+ */var partition=createAggregator(function(result,value,key){result[key?0:1].push(value);},function(){return [[],[]];});/**
+ * Reduces `collection` to a value which is the accumulated result of running
+ * each element in `collection` thru `iteratee`, where each successive
+ * invocation is supplied the return value of the previous. If `accumulator`
+ * is not given, the first element of `collection` is used as the initial
+ * value. The iteratee is invoked with four arguments:
+ * (accumulator, value, index|key, collection).
+ *
+ * Many lodash methods are guarded to work as iteratees for methods like
+ * `_.reduce`, `_.reduceRight`, and `_.transform`.
+ *
+ * The guarded methods are:
+ * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
+ * and `sortBy`
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @param {*} [accumulator] The initial value.
+ * @returns {*} Returns the accumulated value.
+ * @see _.reduceRight
+ * @example
+ *
+ * _.reduce([1, 2], function(sum, n) {
+ * return sum + n;
+ * }, 0);
+ * // => 3
+ *
+ * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
+ * (result[value] || (result[value] = [])).push(key);
+ * return result;
+ * }, {});
+ * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
+ */function reduce(collection,iteratee,accumulator){var func=isArray(collection)?arrayReduce:baseReduce,initAccum=arguments.length<3;return func(collection,getIteratee(iteratee,4),accumulator,initAccum,baseEach);}/**
+ * This method is like `_.reduce` except that it iterates over elements of
+ * `collection` from right to left.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @param {*} [accumulator] The initial value.
+ * @returns {*} Returns the accumulated value.
+ * @see _.reduce
+ * @example
+ *
+ * var array = [[0, 1], [2, 3], [4, 5]];
+ *
+ * _.reduceRight(array, function(flattened, other) {
+ * return flattened.concat(other);
+ * }, []);
+ * // => [4, 5, 2, 3, 0, 1]
+ */function reduceRight(collection,iteratee,accumulator){var func=isArray(collection)?arrayReduceRight:baseReduce,initAccum=arguments.length<3;return func(collection,getIteratee(iteratee,4),accumulator,initAccum,baseEachRight);}/**
+ * The opposite of `_.filter`; this method returns the elements of `collection`
+ * that `predicate` does **not** return truthy for.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the new filtered array.
+ * @see _.filter
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36, 'active': false },
+ * { 'user': 'fred', 'age': 40, 'active': true }
+ * ];
+ *
+ * _.reject(users, function(o) { return !o.active; });
+ * // => objects for ['fred']
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.reject(users, { 'age': 40, 'active': true });
+ * // => objects for ['barney']
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.reject(users, ['active', false]);
+ * // => objects for ['fred']
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.reject(users, 'active');
+ * // => objects for ['barney']
+ */function reject(collection,predicate){var func=isArray(collection)?arrayFilter:baseFilter;return func(collection,negate(getIteratee(predicate,3)));}/**
+ * Gets a random element from `collection`.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to sample.
+ * @returns {*} Returns the random element.
+ * @example
+ *
+ * _.sample([1, 2, 3, 4]);
+ * // => 2
+ */function sample(collection){var func=isArray(collection)?arraySample:baseSample;return func(collection);}/**
+ * Gets `n` random elements at unique keys from `collection` up to the
+ * size of `collection`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to sample.
+ * @param {number} [n=1] The number of elements to sample.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Array} Returns the random elements.
+ * @example
+ *
+ * _.sampleSize([1, 2, 3], 2);
+ * // => [3, 1]
+ *
+ * _.sampleSize([1, 2, 3], 4);
+ * // => [2, 3, 1]
+ */function sampleSize(collection,n,guard){if(guard?isIterateeCall(collection,n,guard):n===undefined$1){n=1;}else {n=toInteger(n);}var func=isArray(collection)?arraySampleSize:baseSampleSize;return func(collection,n);}/**
+ * Creates an array of shuffled values, using a version of the
+ * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to shuffle.
+ * @returns {Array} Returns the new shuffled array.
+ * @example
+ *
+ * _.shuffle([1, 2, 3, 4]);
+ * // => [4, 1, 3, 2]
+ */function shuffle(collection){var func=isArray(collection)?arrayShuffle:baseShuffle;return func(collection);}/**
+ * Gets the size of `collection` by returning its length for array-like
+ * values or the number of own enumerable string keyed properties for objects.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object|string} collection The collection to inspect.
+ * @returns {number} Returns the collection size.
+ * @example
+ *
+ * _.size([1, 2, 3]);
+ * // => 3
+ *
+ * _.size({ 'a': 1, 'b': 2 });
+ * // => 2
+ *
+ * _.size('pebbles');
+ * // => 7
+ */function size(collection){if(collection==null){return 0;}if(isArrayLike(collection)){return isString(collection)?stringSize(collection):collection.length;}var tag=getTag(collection);if(tag==mapTag||tag==setTag){return collection.size;}return baseKeys(collection).length;}/**
+ * Checks if `predicate` returns truthy for **any** element of `collection`.
+ * Iteration is stopped once `predicate` returns truthy. The predicate is
+ * invoked with three arguments: (value, index|key, collection).
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {boolean} Returns `true` if any element passes the predicate check,
+ * else `false`.
+ * @example
+ *
+ * _.some([null, 0, 'yes', false], Boolean);
+ * // => true
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': true },
+ * { 'user': 'fred', 'active': false }
+ * ];
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.some(users, { 'user': 'barney', 'active': false });
+ * // => false
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.some(users, ['active', false]);
+ * // => true
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.some(users, 'active');
+ * // => true
+ */function some(collection,predicate,guard){var func=isArray(collection)?arraySome:baseSome;if(guard&&isIterateeCall(collection,predicate,guard)){predicate=undefined$1;}return func(collection,getIteratee(predicate,3));}/**
+ * Creates an array of elements, sorted in ascending order by the results of
+ * running each element in a collection thru each iteratee. This method
+ * performs a stable sort, that is, it preserves the original sort order of
+ * equal elements. The iteratees are invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {...(Function|Function[])} [iteratees=[_.identity]]
+ * The iteratees to sort by.
+ * @returns {Array} Returns the new sorted array.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'fred', 'age': 48 },
+ * { 'user': 'barney', 'age': 36 },
+ * { 'user': 'fred', 'age': 30 },
+ * { 'user': 'barney', 'age': 34 }
+ * ];
+ *
+ * _.sortBy(users, [function(o) { return o.user; }]);
+ * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]]
+ *
+ * _.sortBy(users, ['user', 'age']);
+ * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]]
+ */var sortBy=baseRest(function(collection,iteratees){if(collection==null){return [];}var length=iteratees.length;if(length>1&&isIterateeCall(collection,iteratees[0],iteratees[1])){iteratees=[];}else if(length>2&&isIterateeCall(iteratees[0],iteratees[1],iteratees[2])){iteratees=[iteratees[0]];}return baseOrderBy(collection,baseFlatten(iteratees,1),[]);});/*------------------------------------------------------------------------*/ /**
+ * Gets the timestamp of the number of milliseconds that have elapsed since
+ * the Unix epoch (1 January 1970 00:00:00 UTC).
+ *
+ * @static
+ * @memberOf _
+ * @since 2.4.0
+ * @category Date
+ * @returns {number} Returns the timestamp.
+ * @example
+ *
+ * _.defer(function(stamp) {
+ * console.log(_.now() - stamp);
+ * }, _.now());
+ * // => Logs the number of milliseconds it took for the deferred invocation.
+ */var now=ctxNow||function(){return root.Date.now();};/*------------------------------------------------------------------------*/ /**
+ * The opposite of `_.before`; this method creates a function that invokes
+ * `func` once it's called `n` or more times.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Function
+ * @param {number} n The number of calls before `func` is invoked.
+ * @param {Function} func The function to restrict.
+ * @returns {Function} Returns the new restricted function.
+ * @example
+ *
+ * var saves = ['profile', 'settings'];
+ *
+ * var done = _.after(saves.length, function() {
+ * console.log('done saving!');
+ * });
+ *
+ * _.forEach(saves, function(type) {
+ * asyncSave({ 'type': type, 'complete': done });
+ * });
+ * // => Logs 'done saving!' after the two async saves have completed.
+ */function after(n,func){if(typeof func!='function'){throw new TypeError(FUNC_ERROR_TEXT);}n=toInteger(n);return function(){if(--n<1){return func.apply(this,arguments);}};}/**
+ * Creates a function that invokes `func`, with up to `n` arguments,
+ * ignoring any additional arguments.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Function
+ * @param {Function} func The function to cap arguments for.
+ * @param {number} [n=func.length] The arity cap.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Function} Returns the new capped function.
+ * @example
+ *
+ * _.map(['6', '8', '10'], _.ary(parseInt, 1));
+ * // => [6, 8, 10]
+ */function ary(func,n,guard){n=guard?undefined$1:n;n=func&&n==null?func.length:n;return createWrap(func,WRAP_ARY_FLAG,undefined$1,undefined$1,undefined$1,undefined$1,n);}/**
+ * Creates a function that invokes `func`, with the `this` binding and arguments
+ * of the created function, while it's called less than `n` times. Subsequent
+ * calls to the created function return the result of the last `func` invocation.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Function
+ * @param {number} n The number of calls at which `func` is no longer invoked.
+ * @param {Function} func The function to restrict.
+ * @returns {Function} Returns the new restricted function.
+ * @example
+ *
+ * jQuery(element).on('click', _.before(5, addContactToList));
+ * // => Allows adding up to 4 contacts to the list.
+ */function before(n,func){var result;if(typeof func!='function'){throw new TypeError(FUNC_ERROR_TEXT);}n=toInteger(n);return function(){if(--n>0){result=func.apply(this,arguments);}if(n<=1){func=undefined$1;}return result;};}/**
+ * Creates a function that invokes `func` with the `this` binding of `thisArg`
+ * and `partials` prepended to the arguments it receives.
+ *
+ * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
+ * may be used as a placeholder for partially applied arguments.
+ *
+ * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
+ * property of bound functions.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Function
+ * @param {Function} func The function to bind.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {...*} [partials] The arguments to be partially applied.
+ * @returns {Function} Returns the new bound function.
+ * @example
+ *
+ * function greet(greeting, punctuation) {
+ * return greeting + ' ' + this.user + punctuation;
+ * }
+ *
+ * var object = { 'user': 'fred' };
+ *
+ * var bound = _.bind(greet, object, 'hi');
+ * bound('!');
+ * // => 'hi fred!'
+ *
+ * // Bound with placeholders.
+ * var bound = _.bind(greet, object, _, '!');
+ * bound('hi');
+ * // => 'hi fred!'
+ */var bind=baseRest(function(func,thisArg,partials){var bitmask=WRAP_BIND_FLAG;if(partials.length){var holders=replaceHolders(partials,getHolder(bind));bitmask|=WRAP_PARTIAL_FLAG;}return createWrap(func,bitmask,thisArg,partials,holders);});/**
+ * Creates a function that invokes the method at `object[key]` with `partials`
+ * prepended to the arguments it receives.
+ *
+ * This method differs from `_.bind` by allowing bound functions to reference
+ * methods that may be redefined or don't yet exist. See
+ * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
+ * for more details.
+ *
+ * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
+ * builds, may be used as a placeholder for partially applied arguments.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.10.0
+ * @category Function
+ * @param {Object} object The object to invoke the method on.
+ * @param {string} key The key of the method.
+ * @param {...*} [partials] The arguments to be partially applied.
+ * @returns {Function} Returns the new bound function.
+ * @example
+ *
+ * var object = {
+ * 'user': 'fred',
+ * 'greet': function(greeting, punctuation) {
+ * return greeting + ' ' + this.user + punctuation;
+ * }
+ * };
+ *
+ * var bound = _.bindKey(object, 'greet', 'hi');
+ * bound('!');
+ * // => 'hi fred!'
+ *
+ * object.greet = function(greeting, punctuation) {
+ * return greeting + 'ya ' + this.user + punctuation;
+ * };
+ *
+ * bound('!');
+ * // => 'hiya fred!'
+ *
+ * // Bound with placeholders.
+ * var bound = _.bindKey(object, 'greet', _, '!');
+ * bound('hi');
+ * // => 'hiya fred!'
+ */var bindKey=baseRest(function(object,key,partials){var bitmask=WRAP_BIND_FLAG|WRAP_BIND_KEY_FLAG;if(partials.length){var holders=replaceHolders(partials,getHolder(bindKey));bitmask|=WRAP_PARTIAL_FLAG;}return createWrap(key,bitmask,object,partials,holders);});/**
+ * Creates a function that accepts arguments of `func` and either invokes
+ * `func` returning its result, if at least `arity` number of arguments have
+ * been provided, or returns a function that accepts the remaining `func`
+ * arguments, and so on. The arity of `func` may be specified if `func.length`
+ * is not sufficient.
+ *
+ * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
+ * may be used as a placeholder for provided arguments.
+ *
+ * **Note:** This method doesn't set the "length" property of curried functions.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @category Function
+ * @param {Function} func The function to curry.
+ * @param {number} [arity=func.length] The arity of `func`.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Function} Returns the new curried function.
+ * @example
+ *
+ * var abc = function(a, b, c) {
+ * return [a, b, c];
+ * };
+ *
+ * var curried = _.curry(abc);
+ *
+ * curried(1)(2)(3);
+ * // => [1, 2, 3]
+ *
+ * curried(1, 2)(3);
+ * // => [1, 2, 3]
+ *
+ * curried(1, 2, 3);
+ * // => [1, 2, 3]
+ *
+ * // Curried with placeholders.
+ * curried(1)(_, 3)(2);
+ * // => [1, 2, 3]
+ */function curry(func,arity,guard){arity=guard?undefined$1:arity;var result=createWrap(func,WRAP_CURRY_FLAG,undefined$1,undefined$1,undefined$1,undefined$1,undefined$1,arity);result.placeholder=curry.placeholder;return result;}/**
+ * This method is like `_.curry` except that arguments are applied to `func`
+ * in the manner of `_.partialRight` instead of `_.partial`.
+ *
+ * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
+ * builds, may be used as a placeholder for provided arguments.
+ *
+ * **Note:** This method doesn't set the "length" property of curried functions.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Function
+ * @param {Function} func The function to curry.
+ * @param {number} [arity=func.length] The arity of `func`.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Function} Returns the new curried function.
+ * @example
+ *
+ * var abc = function(a, b, c) {
+ * return [a, b, c];
+ * };
+ *
+ * var curried = _.curryRight(abc);
+ *
+ * curried(3)(2)(1);
+ * // => [1, 2, 3]
+ *
+ * curried(2, 3)(1);
+ * // => [1, 2, 3]
+ *
+ * curried(1, 2, 3);
+ * // => [1, 2, 3]
+ *
+ * // Curried with placeholders.
+ * curried(3)(1, _)(2);
+ * // => [1, 2, 3]
+ */function curryRight(func,arity,guard){arity=guard?undefined$1:arity;var result=createWrap(func,WRAP_CURRY_RIGHT_FLAG,undefined$1,undefined$1,undefined$1,undefined$1,undefined$1,arity);result.placeholder=curryRight.placeholder;return result;}/**
+ * Creates a debounced function that delays invoking `func` until after `wait`
+ * milliseconds have elapsed since the last time the debounced function was
+ * invoked. The debounced function comes with a `cancel` method to cancel
+ * delayed `func` invocations and a `flush` method to immediately invoke them.
+ * Provide `options` to indicate whether `func` should be invoked on the
+ * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
+ * with the last arguments provided to the debounced function. Subsequent
+ * calls to the debounced function return the result of the last `func`
+ * invocation.
+ *
+ * **Note:** If `leading` and `trailing` options are `true`, `func` is
+ * invoked on the trailing edge of the timeout only if the debounced function
+ * is invoked more than once during the `wait` timeout.
+ *
+ * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
+ * until to the next tick, similar to `setTimeout` with a timeout of `0`.
+ *
+ * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
+ * for details over the differences between `_.debounce` and `_.throttle`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Function
+ * @param {Function} func The function to debounce.
+ * @param {number} [wait=0] The number of milliseconds to delay.
+ * @param {Object} [options={}] The options object.
+ * @param {boolean} [options.leading=false]
+ * Specify invoking on the leading edge of the timeout.
+ * @param {number} [options.maxWait]
+ * The maximum time `func` is allowed to be delayed before it's invoked.
+ * @param {boolean} [options.trailing=true]
+ * Specify invoking on the trailing edge of the timeout.
+ * @returns {Function} Returns the new debounced function.
+ * @example
+ *
+ * // Avoid costly calculations while the window size is in flux.
+ * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
+ *
+ * // Invoke `sendMail` when clicked, debouncing subsequent calls.
+ * jQuery(element).on('click', _.debounce(sendMail, 300, {
+ * 'leading': true,
+ * 'trailing': false
+ * }));
+ *
+ * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
+ * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
+ * var source = new EventSource('/stream');
+ * jQuery(source).on('message', debounced);
+ *
+ * // Cancel the trailing debounced invocation.
+ * jQuery(window).on('popstate', debounced.cancel);
+ */function debounce(func,wait,options){var lastArgs,lastThis,maxWait,result,timerId,lastCallTime,lastInvokeTime=0,leading=false,maxing=false,trailing=true;if(typeof func!='function'){throw new TypeError(FUNC_ERROR_TEXT);}wait=toNumber(wait)||0;if(isObject(options)){leading=!!options.leading;maxing='maxWait'in options;maxWait=maxing?nativeMax(toNumber(options.maxWait)||0,wait):maxWait;trailing='trailing'in options?!!options.trailing:trailing;}function invokeFunc(time){var args=lastArgs,thisArg=lastThis;lastArgs=lastThis=undefined$1;lastInvokeTime=time;result=func.apply(thisArg,args);return result;}function leadingEdge(time){// Reset any `maxWait` timer.
+lastInvokeTime=time;// Start the timer for the trailing edge.
+timerId=setTimeout(timerExpired,wait);// Invoke the leading edge.
+return leading?invokeFunc(time):result;}function remainingWait(time){var timeSinceLastCall=time-lastCallTime,timeSinceLastInvoke=time-lastInvokeTime,timeWaiting=wait-timeSinceLastCall;return maxing?nativeMin(timeWaiting,maxWait-timeSinceLastInvoke):timeWaiting;}function shouldInvoke(time){var timeSinceLastCall=time-lastCallTime,timeSinceLastInvoke=time-lastInvokeTime;// Either this is the first call, activity has stopped and we're at the
+// trailing edge, the system time has gone backwards and we're treating
+// it as the trailing edge, or we've hit the `maxWait` limit.
+return lastCallTime===undefined$1||timeSinceLastCall>=wait||timeSinceLastCall<0||maxing&&timeSinceLastInvoke>=maxWait;}function timerExpired(){var time=now();if(shouldInvoke(time)){return trailingEdge(time);}// Restart the timer.
+timerId=setTimeout(timerExpired,remainingWait(time));}function trailingEdge(time){timerId=undefined$1;// Only invoke if we have `lastArgs` which means `func` has been
+// debounced at least once.
+if(trailing&&lastArgs){return invokeFunc(time);}lastArgs=lastThis=undefined$1;return result;}function cancel(){if(timerId!==undefined$1){clearTimeout(timerId);}lastInvokeTime=0;lastArgs=lastCallTime=lastThis=timerId=undefined$1;}function flush(){return timerId===undefined$1?result:trailingEdge(now());}function debounced(){var time=now(),isInvoking=shouldInvoke(time);lastArgs=arguments;lastThis=this;lastCallTime=time;if(isInvoking){if(timerId===undefined$1){return leadingEdge(lastCallTime);}if(maxing){// Handle invocations in a tight loop.
+clearTimeout(timerId);timerId=setTimeout(timerExpired,wait);return invokeFunc(lastCallTime);}}if(timerId===undefined$1){timerId=setTimeout(timerExpired,wait);}return result;}debounced.cancel=cancel;debounced.flush=flush;return debounced;}/**
+ * Defers invoking the `func` until the current call stack has cleared. Any
+ * additional arguments are provided to `func` when it's invoked.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Function
+ * @param {Function} func The function to defer.
+ * @param {...*} [args] The arguments to invoke `func` with.
+ * @returns {number} Returns the timer id.
+ * @example
+ *
+ * _.defer(function(text) {
+ * console.log(text);
+ * }, 'deferred');
+ * // => Logs 'deferred' after one millisecond.
+ */var defer=baseRest(function(func,args){return baseDelay(func,1,args);});/**
+ * Invokes `func` after `wait` milliseconds. Any additional arguments are
+ * provided to `func` when it's invoked.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Function
+ * @param {Function} func The function to delay.
+ * @param {number} wait The number of milliseconds to delay invocation.
+ * @param {...*} [args] The arguments to invoke `func` with.
+ * @returns {number} Returns the timer id.
+ * @example
+ *
+ * _.delay(function(text) {
+ * console.log(text);
+ * }, 1000, 'later');
+ * // => Logs 'later' after one second.
+ */var delay=baseRest(function(func,wait,args){return baseDelay(func,toNumber(wait)||0,args);});/**
+ * Creates a function that invokes `func` with arguments reversed.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Function
+ * @param {Function} func The function to flip arguments for.
+ * @returns {Function} Returns the new flipped function.
+ * @example
+ *
+ * var flipped = _.flip(function() {
+ * return _.toArray(arguments);
+ * });
+ *
+ * flipped('a', 'b', 'c', 'd');
+ * // => ['d', 'c', 'b', 'a']
+ */function flip(func){return createWrap(func,WRAP_FLIP_FLAG);}/**
+ * Creates a function that memoizes the result of `func`. If `resolver` is
+ * provided, it determines the cache key for storing the result based on the
+ * arguments provided to the memoized function. By default, the first argument
+ * provided to the memoized function is used as the map cache key. The `func`
+ * is invoked with the `this` binding of the memoized function.
+ *
+ * **Note:** The cache is exposed as the `cache` property on the memoized
+ * function. Its creation may be customized by replacing the `_.memoize.Cache`
+ * constructor with one whose instances implement the
+ * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
+ * method interface of `clear`, `delete`, `get`, `has`, and `set`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Function
+ * @param {Function} func The function to have its output memoized.
+ * @param {Function} [resolver] The function to resolve the cache key.
+ * @returns {Function} Returns the new memoized function.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': 2 };
+ * var other = { 'c': 3, 'd': 4 };
+ *
+ * var values = _.memoize(_.values);
+ * values(object);
+ * // => [1, 2]
+ *
+ * values(other);
+ * // => [3, 4]
+ *
+ * object.a = 2;
+ * values(object);
+ * // => [1, 2]
+ *
+ * // Modify the result cache.
+ * values.cache.set(object, ['a', 'b']);
+ * values(object);
+ * // => ['a', 'b']
+ *
+ * // Replace `_.memoize.Cache`.
+ * _.memoize.Cache = WeakMap;
+ */function memoize(func,resolver){if(typeof func!='function'||resolver!=null&&typeof resolver!='function'){throw new TypeError(FUNC_ERROR_TEXT);}var memoized=function(){var args=arguments,key=resolver?resolver.apply(this,args):args[0],cache=memoized.cache;if(cache.has(key)){return cache.get(key);}var result=func.apply(this,args);memoized.cache=cache.set(key,result)||cache;return result;};memoized.cache=new(memoize.Cache||MapCache)();return memoized;}// Expose `MapCache`.
+memoize.Cache=MapCache;/**
+ * Creates a function that negates the result of the predicate `func`. The
+ * `func` predicate is invoked with the `this` binding and arguments of the
+ * created function.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Function
+ * @param {Function} predicate The predicate to negate.
+ * @returns {Function} Returns the new negated function.
+ * @example
+ *
+ * function isEven(n) {
+ * return n % 2 == 0;
+ * }
+ *
+ * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
+ * // => [1, 3, 5]
+ */function negate(predicate){if(typeof predicate!='function'){throw new TypeError(FUNC_ERROR_TEXT);}return function(){var args=arguments;switch(args.length){case 0:return !predicate.call(this);case 1:return !predicate.call(this,args[0]);case 2:return !predicate.call(this,args[0],args[1]);case 3:return !predicate.call(this,args[0],args[1],args[2]);}return !predicate.apply(this,args);};}/**
+ * Creates a function that is restricted to invoking `func` once. Repeat calls
+ * to the function return the value of the first invocation. The `func` is
+ * invoked with the `this` binding and arguments of the created function.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Function
+ * @param {Function} func The function to restrict.
+ * @returns {Function} Returns the new restricted function.
+ * @example
+ *
+ * var initialize = _.once(createApplication);
+ * initialize();
+ * initialize();
+ * // => `createApplication` is invoked once
+ */function once(func){return before(2,func);}/**
+ * Creates a function that invokes `func` with its arguments transformed.
+ *
+ * @static
+ * @since 4.0.0
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to wrap.
+ * @param {...(Function|Function[])} [transforms=[_.identity]]
+ * The argument transforms.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * function doubled(n) {
+ * return n * 2;
+ * }
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * var func = _.overArgs(function(x, y) {
+ * return [x, y];
+ * }, [square, doubled]);
+ *
+ * func(9, 3);
+ * // => [81, 6]
+ *
+ * func(10, 5);
+ * // => [100, 10]
+ */var overArgs=castRest(function(func,transforms){transforms=transforms.length==1&&isArray(transforms[0])?arrayMap(transforms[0],baseUnary(getIteratee())):arrayMap(baseFlatten(transforms,1),baseUnary(getIteratee()));var funcsLength=transforms.length;return baseRest(function(args){var index=-1,length=nativeMin(args.length,funcsLength);while(++index<length){args[index]=transforms[index].call(this,args[index]);}return apply(func,this,args);});});/**
+ * Creates a function that invokes `func` with `partials` prepended to the
+ * arguments it receives. This method is like `_.bind` except it does **not**
+ * alter the `this` binding.
+ *
+ * The `_.partial.placeholder` value, which defaults to `_` in monolithic
+ * builds, may be used as a placeholder for partially applied arguments.
+ *
+ * **Note:** This method doesn't set the "length" property of partially
+ * applied functions.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.2.0
+ * @category Function
+ * @param {Function} func The function to partially apply arguments to.
+ * @param {...*} [partials] The arguments to be partially applied.
+ * @returns {Function} Returns the new partially applied function.
+ * @example
+ *
+ * function greet(greeting, name) {
+ * return greeting + ' ' + name;
+ * }
+ *
+ * var sayHelloTo = _.partial(greet, 'hello');
+ * sayHelloTo('fred');
+ * // => 'hello fred'
+ *
+ * // Partially applied with placeholders.
+ * var greetFred = _.partial(greet, _, 'fred');
+ * greetFred('hi');
+ * // => 'hi fred'
+ */var partial=baseRest(function(func,partials){var holders=replaceHolders(partials,getHolder(partial));return createWrap(func,WRAP_PARTIAL_FLAG,undefined$1,partials,holders);});/**
+ * This method is like `_.partial` except that partially applied arguments
+ * are appended to the arguments it receives.
+ *
+ * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
+ * builds, may be used as a placeholder for partially applied arguments.
+ *
+ * **Note:** This method doesn't set the "length" property of partially
+ * applied functions.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.0.0
+ * @category Function
+ * @param {Function} func The function to partially apply arguments to.
+ * @param {...*} [partials] The arguments to be partially applied.
+ * @returns {Function} Returns the new partially applied function.
+ * @example
+ *
+ * function greet(greeting, name) {
+ * return greeting + ' ' + name;
+ * }
+ *
+ * var greetFred = _.partialRight(greet, 'fred');
+ * greetFred('hi');
+ * // => 'hi fred'
+ *
+ * // Partially applied with placeholders.
+ * var sayHelloTo = _.partialRight(greet, 'hello', _);
+ * sayHelloTo('fred');
+ * // => 'hello fred'
+ */var partialRight=baseRest(function(func,partials){var holders=replaceHolders(partials,getHolder(partialRight));return createWrap(func,WRAP_PARTIAL_RIGHT_FLAG,undefined$1,partials,holders);});/**
+ * Creates a function that invokes `func` with arguments arranged according
+ * to the specified `indexes` where the argument value at the first index is
+ * provided as the first argument, the argument value at the second index is
+ * provided as the second argument, and so on.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Function
+ * @param {Function} func The function to rearrange arguments for.
+ * @param {...(number|number[])} indexes The arranged argument indexes.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var rearged = _.rearg(function(a, b, c) {
+ * return [a, b, c];
+ * }, [2, 0, 1]);
+ *
+ * rearged('b', 'c', 'a')
+ * // => ['a', 'b', 'c']
+ */var rearg=flatRest(function(func,indexes){return createWrap(func,WRAP_REARG_FLAG,undefined$1,undefined$1,undefined$1,indexes);});/**
+ * Creates a function that invokes `func` with the `this` binding of the
+ * created function and arguments from `start` and beyond provided as
+ * an array.
+ *
+ * **Note:** This method is based on the
+ * [rest parameter](https://mdn.io/rest_parameters).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Function
+ * @param {Function} func The function to apply a rest parameter to.
+ * @param {number} [start=func.length-1] The start position of the rest parameter.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var say = _.rest(function(what, names) {
+ * return what + ' ' + _.initial(names).join(', ') +
+ * (_.size(names) > 1 ? ', & ' : '') + _.last(names);
+ * });
+ *
+ * say('hello', 'fred', 'barney', 'pebbles');
+ * // => 'hello fred, barney, & pebbles'
+ */function rest(func,start){if(typeof func!='function'){throw new TypeError(FUNC_ERROR_TEXT);}start=start===undefined$1?start:toInteger(start);return baseRest(func,start);}/**
+ * Creates a function that invokes `func` with the `this` binding of the
+ * create function and an array of arguments much like
+ * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
+ *
+ * **Note:** This method is based on the
+ * [spread operator](https://mdn.io/spread_operator).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.2.0
+ * @category Function
+ * @param {Function} func The function to spread arguments over.
+ * @param {number} [start=0] The start position of the spread.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var say = _.spread(function(who, what) {
+ * return who + ' says ' + what;
+ * });
+ *
+ * say(['fred', 'hello']);
+ * // => 'fred says hello'
+ *
+ * var numbers = Promise.all([
+ * Promise.resolve(40),
+ * Promise.resolve(36)
+ * ]);
+ *
+ * numbers.then(_.spread(function(x, y) {
+ * return x + y;
+ * }));
+ * // => a Promise of 76
+ */function spread(func,start){if(typeof func!='function'){throw new TypeError(FUNC_ERROR_TEXT);}start=start==null?0:nativeMax(toInteger(start),0);return baseRest(function(args){var array=args[start],otherArgs=castSlice(args,0,start);if(array){arrayPush(otherArgs,array);}return apply(func,this,otherArgs);});}/**
+ * Creates a throttled function that only invokes `func` at most once per
+ * every `wait` milliseconds. The throttled function comes with a `cancel`
+ * method to cancel delayed `func` invocations and a `flush` method to
+ * immediately invoke them. Provide `options` to indicate whether `func`
+ * should be invoked on the leading and/or trailing edge of the `wait`
+ * timeout. The `func` is invoked with the last arguments provided to the
+ * throttled function. Subsequent calls to the throttled function return the
+ * result of the last `func` invocation.
+ *
+ * **Note:** If `leading` and `trailing` options are `true`, `func` is
+ * invoked on the trailing edge of the timeout only if the throttled function
+ * is invoked more than once during the `wait` timeout.
+ *
+ * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
+ * until to the next tick, similar to `setTimeout` with a timeout of `0`.
+ *
+ * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
+ * for details over the differences between `_.throttle` and `_.debounce`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Function
+ * @param {Function} func The function to throttle.
+ * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
+ * @param {Object} [options={}] The options object.
+ * @param {boolean} [options.leading=true]
+ * Specify invoking on the leading edge of the timeout.
+ * @param {boolean} [options.trailing=true]
+ * Specify invoking on the trailing edge of the timeout.
+ * @returns {Function} Returns the new throttled function.
+ * @example
+ *
+ * // Avoid excessively updating the position while scrolling.
+ * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
+ *
+ * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
+ * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
+ * jQuery(element).on('click', throttled);
+ *
+ * // Cancel the trailing throttled invocation.
+ * jQuery(window).on('popstate', throttled.cancel);
+ */function throttle(func,wait,options){var leading=true,trailing=true;if(typeof func!='function'){throw new TypeError(FUNC_ERROR_TEXT);}if(isObject(options)){leading='leading'in options?!!options.leading:leading;trailing='trailing'in options?!!options.trailing:trailing;}return debounce(func,wait,{'leading':leading,'maxWait':wait,'trailing':trailing});}/**
+ * Creates a function that accepts up to one argument, ignoring any
+ * additional arguments.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Function
+ * @param {Function} func The function to cap arguments for.
+ * @returns {Function} Returns the new capped function.
+ * @example
+ *
+ * _.map(['6', '8', '10'], _.unary(parseInt));
+ * // => [6, 8, 10]
+ */function unary(func){return ary(func,1);}/**
+ * Creates a function that provides `value` to `wrapper` as its first
+ * argument. Any additional arguments provided to the function are appended
+ * to those provided to the `wrapper`. The wrapper is invoked with the `this`
+ * binding of the created function.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Function
+ * @param {*} value The value to wrap.
+ * @param {Function} [wrapper=identity] The wrapper function.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var p = _.wrap(_.escape, function(func, text) {
+ * return '<p>' + func(text) + '</p>';
+ * });
+ *
+ * p('fred, barney, & pebbles');
+ * // => '<p>fred, barney, & pebbles</p>'
+ */function wrap(value,wrapper){return partial(castFunction(wrapper),value);}/*------------------------------------------------------------------------*/ /**
+ * Casts `value` as an array if it's not one.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.4.0
+ * @category Lang
+ * @param {*} value The value to inspect.
+ * @returns {Array} Returns the cast array.
+ * @example
+ *
+ * _.castArray(1);
+ * // => [1]
+ *
+ * _.castArray({ 'a': 1 });
+ * // => [{ 'a': 1 }]
+ *
+ * _.castArray('abc');
+ * // => ['abc']
+ *
+ * _.castArray(null);
+ * // => [null]
+ *
+ * _.castArray(undefined);
+ * // => [undefined]
+ *
+ * _.castArray();
+ * // => []
+ *
+ * var array = [1, 2, 3];
+ * console.log(_.castArray(array) === array);
+ * // => true
+ */function castArray(){if(!arguments.length){return [];}var value=arguments[0];return isArray(value)?value:[value];}/**
+ * Creates a shallow clone of `value`.
+ *
+ * **Note:** This method is loosely based on the
+ * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
+ * and supports cloning arrays, array buffers, booleans, date objects, maps,
+ * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
+ * arrays. The own enumerable properties of `arguments` objects are cloned
+ * as plain objects. An empty object is returned for uncloneable values such
+ * as error objects, functions, DOM nodes, and WeakMaps.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to clone.
+ * @returns {*} Returns the cloned value.
+ * @see _.cloneDeep
+ * @example
+ *
+ * var objects = [{ 'a': 1 }, { 'b': 2 }];
+ *
+ * var shallow = _.clone(objects);
+ * console.log(shallow[0] === objects[0]);
+ * // => true
+ */function clone(value){return baseClone(value,CLONE_SYMBOLS_FLAG);}/**
+ * This method is like `_.clone` except that it accepts `customizer` which
+ * is invoked to produce the cloned value. If `customizer` returns `undefined`,
+ * cloning is handled by the method instead. The `customizer` is invoked with
+ * up to four arguments; (value [, index|key, object, stack]).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to clone.
+ * @param {Function} [customizer] The function to customize cloning.
+ * @returns {*} Returns the cloned value.
+ * @see _.cloneDeepWith
+ * @example
+ *
+ * function customizer(value) {
+ * if (_.isElement(value)) {
+ * return value.cloneNode(false);
+ * }
+ * }
+ *
+ * var el = _.cloneWith(document.body, customizer);
+ *
+ * console.log(el === document.body);
+ * // => false
+ * console.log(el.nodeName);
+ * // => 'BODY'
+ * console.log(el.childNodes.length);
+ * // => 0
+ */function cloneWith(value,customizer){customizer=typeof customizer=='function'?customizer:undefined$1;return baseClone(value,CLONE_SYMBOLS_FLAG,customizer);}/**
+ * This method is like `_.clone` except that it recursively clones `value`.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.0.0
+ * @category Lang
+ * @param {*} value The value to recursively clone.
+ * @returns {*} Returns the deep cloned value.
+ * @see _.clone
+ * @example
+ *
+ * var objects = [{ 'a': 1 }, { 'b': 2 }];
+ *
+ * var deep = _.cloneDeep(objects);
+ * console.log(deep[0] === objects[0]);
+ * // => false
+ */function cloneDeep(value){return baseClone(value,CLONE_DEEP_FLAG|CLONE_SYMBOLS_FLAG);}/**
+ * This method is like `_.cloneWith` except that it recursively clones `value`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to recursively clone.
+ * @param {Function} [customizer] The function to customize cloning.
+ * @returns {*} Returns the deep cloned value.
+ * @see _.cloneWith
+ * @example
+ *
+ * function customizer(value) {
+ * if (_.isElement(value)) {
+ * return value.cloneNode(true);
+ * }
+ * }
+ *
+ * var el = _.cloneDeepWith(document.body, customizer);
+ *
+ * console.log(el === document.body);
+ * // => false
+ * console.log(el.nodeName);
+ * // => 'BODY'
+ * console.log(el.childNodes.length);
+ * // => 20
+ */function cloneDeepWith(value,customizer){customizer=typeof customizer=='function'?customizer:undefined$1;return baseClone(value,CLONE_DEEP_FLAG|CLONE_SYMBOLS_FLAG,customizer);}/**
+ * Checks if `object` conforms to `source` by invoking the predicate
+ * properties of `source` with the corresponding property values of `object`.
+ *
+ * **Note:** This method is equivalent to `_.conforms` when `source` is
+ * partially applied.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.14.0
+ * @category Lang
+ * @param {Object} object The object to inspect.
+ * @param {Object} source The object of property predicates to conform to.
+ * @returns {boolean} Returns `true` if `object` conforms, else `false`.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': 2 };
+ *
+ * _.conformsTo(object, { 'b': function(n) { return n > 1; } });
+ * // => true
+ *
+ * _.conformsTo(object, { 'b': function(n) { return n > 2; } });
+ * // => false
+ */function conformsTo(object,source){return source==null||baseConformsTo(object,source,keys(source));}/**
+ * Performs a
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * comparison between two values to determine if they are equivalent.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ * @example
+ *
+ * var object = { 'a': 1 };
+ * var other = { 'a': 1 };
+ *
+ * _.eq(object, object);
+ * // => true
+ *
+ * _.eq(object, other);
+ * // => false
+ *
+ * _.eq('a', 'a');
+ * // => true
+ *
+ * _.eq('a', Object('a'));
+ * // => false
+ *
+ * _.eq(NaN, NaN);
+ * // => true
+ */function eq(value,other){return value===other||value!==value&&other!==other;}/**
+ * Checks if `value` is greater than `other`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.9.0
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if `value` is greater than `other`,
+ * else `false`.
+ * @see _.lt
+ * @example
+ *
+ * _.gt(3, 1);
+ * // => true
+ *
+ * _.gt(3, 3);
+ * // => false
+ *
+ * _.gt(1, 3);
+ * // => false
+ */var gt=createRelationalOperation(baseGt);/**
+ * Checks if `value` is greater than or equal to `other`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.9.0
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if `value` is greater than or equal to
+ * `other`, else `false`.
+ * @see _.lte
+ * @example
+ *
+ * _.gte(3, 1);
+ * // => true
+ *
+ * _.gte(3, 3);
+ * // => true
+ *
+ * _.gte(1, 3);
+ * // => false
+ */var gte=createRelationalOperation(function(value,other){return value>=other;});/**
+ * Checks if `value` is likely an `arguments` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an `arguments` object,
+ * else `false`.
+ * @example
+ *
+ * _.isArguments(function() { return arguments; }());
+ * // => true
+ *
+ * _.isArguments([1, 2, 3]);
+ * // => false
+ */var isArguments=baseIsArguments(function(){return arguments;}())?baseIsArguments:function(value){return isObjectLike(value)&&hasOwnProperty.call(value,'callee')&&!propertyIsEnumerable.call(value,'callee');};/**
+ * Checks if `value` is classified as an `Array` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an array, else `false`.
+ * @example
+ *
+ * _.isArray([1, 2, 3]);
+ * // => true
+ *
+ * _.isArray(document.body.children);
+ * // => false
+ *
+ * _.isArray('abc');
+ * // => false
+ *
+ * _.isArray(_.noop);
+ * // => false
+ */var isArray=Array.isArray;/**
+ * Checks if `value` is classified as an `ArrayBuffer` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.3.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
+ * @example
+ *
+ * _.isArrayBuffer(new ArrayBuffer(2));
+ * // => true
+ *
+ * _.isArrayBuffer(new Array(2));
+ * // => false
+ */var isArrayBuffer=nodeIsArrayBuffer?baseUnary(nodeIsArrayBuffer):baseIsArrayBuffer;/**
+ * Checks if `value` is array-like. A value is considered array-like if it's
+ * not a function and has a `value.length` that's an integer greater than or
+ * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+ * @example
+ *
+ * _.isArrayLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLike(document.body.children);
+ * // => true
+ *
+ * _.isArrayLike('abc');
+ * // => true
+ *
+ * _.isArrayLike(_.noop);
+ * // => false
+ */function isArrayLike(value){return value!=null&&isLength(value.length)&&!isFunction(value);}/**
+ * This method is like `_.isArrayLike` except that it also checks if `value`
+ * is an object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an array-like object,
+ * else `false`.
+ * @example
+ *
+ * _.isArrayLikeObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLikeObject(document.body.children);
+ * // => true
+ *
+ * _.isArrayLikeObject('abc');
+ * // => false
+ *
+ * _.isArrayLikeObject(_.noop);
+ * // => false
+ */function isArrayLikeObject(value){return isObjectLike(value)&&isArrayLike(value);}/**
+ * Checks if `value` is classified as a boolean primitive or object.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
+ * @example
+ *
+ * _.isBoolean(false);
+ * // => true
+ *
+ * _.isBoolean(null);
+ * // => false
+ */function isBoolean(value){return value===true||value===false||isObjectLike(value)&&baseGetTag(value)==boolTag;}/**
+ * Checks if `value` is a buffer.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.3.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
+ * @example
+ *
+ * _.isBuffer(new Buffer(2));
+ * // => true
+ *
+ * _.isBuffer(new Uint8Array(2));
+ * // => false
+ */var isBuffer=nativeIsBuffer||stubFalse;/**
+ * Checks if `value` is classified as a `Date` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
+ * @example
+ *
+ * _.isDate(new Date);
+ * // => true
+ *
+ * _.isDate('Mon April 23 2012');
+ * // => false
+ */var isDate=nodeIsDate?baseUnary(nodeIsDate):baseIsDate;/**
+ * Checks if `value` is likely a DOM element.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
+ * @example
+ *
+ * _.isElement(document.body);
+ * // => true
+ *
+ * _.isElement('<body>');
+ * // => false
+ */function isElement(value){return isObjectLike(value)&&value.nodeType===1&&!isPlainObject(value);}/**
+ * Checks if `value` is an empty object, collection, map, or set.
+ *
+ * Objects are considered empty if they have no own enumerable string keyed
+ * properties.
+ *
+ * Array-like values such as `arguments` objects, arrays, buffers, strings, or
+ * jQuery-like collections are considered empty if they have a `length` of `0`.
+ * Similarly, maps and sets are considered empty if they have a `size` of `0`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is empty, else `false`.
+ * @example
+ *
+ * _.isEmpty(null);
+ * // => true
+ *
+ * _.isEmpty(true);
+ * // => true
+ *
+ * _.isEmpty(1);
+ * // => true
+ *
+ * _.isEmpty([1, 2, 3]);
+ * // => false
+ *
+ * _.isEmpty({ 'a': 1 });
+ * // => false
+ */function isEmpty(value){if(value==null){return true;}if(isArrayLike(value)&&(isArray(value)||typeof value=='string'||typeof value.splice=='function'||isBuffer(value)||isTypedArray(value)||isArguments(value))){return !value.length;}var tag=getTag(value);if(tag==mapTag||tag==setTag){return !value.size;}if(isPrototype(value)){return !baseKeys(value).length;}for(var key in value){if(hasOwnProperty.call(value,key)){return false;}}return true;}/**
+ * Performs a deep comparison between two values to determine if they are
+ * equivalent.
+ *
+ * **Note:** This method supports comparing arrays, array buffers, booleans,
+ * date objects, error objects, maps, numbers, `Object` objects, regexes,
+ * sets, strings, symbols, and typed arrays. `Object` objects are compared
+ * by their own, not inherited, enumerable properties. Functions and DOM
+ * nodes are compared by strict equality, i.e. `===`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ * @example
+ *
+ * var object = { 'a': 1 };
+ * var other = { 'a': 1 };
+ *
+ * _.isEqual(object, other);
+ * // => true
+ *
+ * object === other;
+ * // => false
+ */function isEqual(value,other){return baseIsEqual(value,other);}/**
+ * This method is like `_.isEqual` except that it accepts `customizer` which
+ * is invoked to compare values. If `customizer` returns `undefined`, comparisons
+ * are handled by the method instead. The `customizer` is invoked with up to
+ * six arguments: (objValue, othValue [, index|key, object, other, stack]).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ * @example
+ *
+ * function isGreeting(value) {
+ * return /^h(?:i|ello)$/.test(value);
+ * }
+ *
+ * function customizer(objValue, othValue) {
+ * if (isGreeting(objValue) && isGreeting(othValue)) {
+ * return true;
+ * }
+ * }
+ *
+ * var array = ['hello', 'goodbye'];
+ * var other = ['hi', 'goodbye'];
+ *
+ * _.isEqualWith(array, other, customizer);
+ * // => true
+ */function isEqualWith(value,other,customizer){customizer=typeof customizer=='function'?customizer:undefined$1;var result=customizer?customizer(value,other):undefined$1;return result===undefined$1?baseIsEqual(value,other,undefined$1,customizer):!!result;}/**
+ * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
+ * `SyntaxError`, `TypeError`, or `URIError` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
+ * @example
+ *
+ * _.isError(new Error);
+ * // => true
+ *
+ * _.isError(Error);
+ * // => false
+ */function isError(value){if(!isObjectLike(value)){return false;}var tag=baseGetTag(value);return tag==errorTag||tag==domExcTag||typeof value.message=='string'&&typeof value.name=='string'&&!isPlainObject(value);}/**
+ * Checks if `value` is a finite primitive number.
+ *
+ * **Note:** This method is based on
+ * [`Number.isFinite`](https://mdn.io/Number/isFinite).
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
+ * @example
+ *
+ * _.isFinite(3);
+ * // => true
+ *
+ * _.isFinite(Number.MIN_VALUE);
+ * // => true
+ *
+ * _.isFinite(Infinity);
+ * // => false
+ *
+ * _.isFinite('3');
+ * // => false
+ */function isFinite(value){return typeof value=='number'&&nativeIsFinite(value);}/**
+ * Checks if `value` is classified as a `Function` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a function, else `false`.
+ * @example
+ *
+ * _.isFunction(_);
+ * // => true
+ *
+ * _.isFunction(/abc/);
+ * // => false
+ */function isFunction(value){if(!isObject(value)){return false;}// The use of `Object#toString` avoids issues with the `typeof` operator
+// in Safari 9 which returns 'object' for typed arrays and other constructors.
+var tag=baseGetTag(value);return tag==funcTag||tag==genTag||tag==asyncTag||tag==proxyTag;}/**
+ * Checks if `value` is an integer.
+ *
+ * **Note:** This method is based on
+ * [`Number.isInteger`](https://mdn.io/Number/isInteger).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
+ * @example
+ *
+ * _.isInteger(3);
+ * // => true
+ *
+ * _.isInteger(Number.MIN_VALUE);
+ * // => false
+ *
+ * _.isInteger(Infinity);
+ * // => false
+ *
+ * _.isInteger('3');
+ * // => false
+ */function isInteger(value){return typeof value=='number'&&value==toInteger(value);}/**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This method is loosely based on
+ * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ * @example
+ *
+ * _.isLength(3);
+ * // => true
+ *
+ * _.isLength(Number.MIN_VALUE);
+ * // => false
+ *
+ * _.isLength(Infinity);
+ * // => false
+ *
+ * _.isLength('3');
+ * // => false
+ */function isLength(value){return typeof value=='number'&&value>-1&&value%1==0&&value<=MAX_SAFE_INTEGER;}/**
+ * Checks if `value` is the
+ * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
+ * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(_.noop);
+ * // => true
+ *
+ * _.isObject(null);
+ * // => false
+ */function isObject(value){var type=typeof value;return value!=null&&(type=='object'||type=='function');}/**
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
+ * and has a `typeof` result of "object".
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ * @example
+ *
+ * _.isObjectLike({});
+ * // => true
+ *
+ * _.isObjectLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isObjectLike(_.noop);
+ * // => false
+ *
+ * _.isObjectLike(null);
+ * // => false
+ */function isObjectLike(value){return value!=null&&typeof value=='object';}/**
+ * Checks if `value` is classified as a `Map` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.3.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a map, else `false`.
+ * @example
+ *
+ * _.isMap(new Map);
+ * // => true
+ *
+ * _.isMap(new WeakMap);
+ * // => false
+ */var isMap=nodeIsMap?baseUnary(nodeIsMap):baseIsMap;/**
+ * Performs a partial deep comparison between `object` and `source` to
+ * determine if `object` contains equivalent property values.
+ *
+ * **Note:** This method is equivalent to `_.matches` when `source` is
+ * partially applied.
+ *
+ * Partial comparisons will match empty array and empty object `source`
+ * values against any array or object value, respectively. See `_.isEqual`
+ * for a list of supported value comparisons.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Lang
+ * @param {Object} object The object to inspect.
+ * @param {Object} source The object of property values to match.
+ * @returns {boolean} Returns `true` if `object` is a match, else `false`.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': 2 };
+ *
+ * _.isMatch(object, { 'b': 2 });
+ * // => true
+ *
+ * _.isMatch(object, { 'b': 1 });
+ * // => false
+ */function isMatch(object,source){return object===source||baseIsMatch(object,source,getMatchData(source));}/**
+ * This method is like `_.isMatch` except that it accepts `customizer` which
+ * is invoked to compare values. If `customizer` returns `undefined`, comparisons
+ * are handled by the method instead. The `customizer` is invoked with five
+ * arguments: (objValue, srcValue, index|key, object, source).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {Object} object The object to inspect.
+ * @param {Object} source The object of property values to match.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @returns {boolean} Returns `true` if `object` is a match, else `false`.
+ * @example
+ *
+ * function isGreeting(value) {
+ * return /^h(?:i|ello)$/.test(value);
+ * }
+ *
+ * function customizer(objValue, srcValue) {
+ * if (isGreeting(objValue) && isGreeting(srcValue)) {
+ * return true;
+ * }
+ * }
+ *
+ * var object = { 'greeting': 'hello' };
+ * var source = { 'greeting': 'hi' };
+ *
+ * _.isMatchWith(object, source, customizer);
+ * // => true
+ */function isMatchWith(object,source,customizer){customizer=typeof customizer=='function'?customizer:undefined$1;return baseIsMatch(object,source,getMatchData(source),customizer);}/**
+ * Checks if `value` is `NaN`.
+ *
+ * **Note:** This method is based on
+ * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
+ * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
+ * `undefined` and other non-number values.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
+ * @example
+ *
+ * _.isNaN(NaN);
+ * // => true
+ *
+ * _.isNaN(new Number(NaN));
+ * // => true
+ *
+ * isNaN(undefined);
+ * // => true
+ *
+ * _.isNaN(undefined);
+ * // => false
+ */function isNaN(value){// An `NaN` primitive is the only value that is not equal to itself.
+// Perform the `toStringTag` check first to avoid errors with some
+// ActiveX objects in IE.
+return isNumber(value)&&value!=+value;}/**
+ * Checks if `value` is a pristine native function.
+ *
+ * **Note:** This method can't reliably detect native functions in the presence
+ * of the core-js package because core-js circumvents this kind of detection.
+ * Despite multiple requests, the core-js maintainer has made it clear: any
+ * attempt to fix the detection will be obstructed. As a result, we're left
+ * with little choice but to throw an error. Unfortunately, this also affects
+ * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
+ * which rely on core-js.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a native function,
+ * else `false`.
+ * @example
+ *
+ * _.isNative(Array.prototype.push);
+ * // => true
+ *
+ * _.isNative(_);
+ * // => false
+ */function isNative(value){if(isMaskable(value)){throw new Error(CORE_ERROR_TEXT);}return baseIsNative(value);}/**
+ * Checks if `value` is `null`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
+ * @example
+ *
+ * _.isNull(null);
+ * // => true
+ *
+ * _.isNull(void 0);
+ * // => false
+ */function isNull(value){return value===null;}/**
+ * Checks if `value` is `null` or `undefined`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
+ * @example
+ *
+ * _.isNil(null);
+ * // => true
+ *
+ * _.isNil(void 0);
+ * // => true
+ *
+ * _.isNil(NaN);
+ * // => false
+ */function isNil(value){return value==null;}/**
+ * Checks if `value` is classified as a `Number` primitive or object.
+ *
+ * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
+ * classified as numbers, use the `_.isFinite` method.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a number, else `false`.
+ * @example
+ *
+ * _.isNumber(3);
+ * // => true
+ *
+ * _.isNumber(Number.MIN_VALUE);
+ * // => true
+ *
+ * _.isNumber(Infinity);
+ * // => true
+ *
+ * _.isNumber('3');
+ * // => false
+ */function isNumber(value){return typeof value=='number'||isObjectLike(value)&&baseGetTag(value)==numberTag;}/**
+ * Checks if `value` is a plain object, that is, an object created by the
+ * `Object` constructor or one with a `[[Prototype]]` of `null`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.8.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * }
+ *
+ * _.isPlainObject(new Foo);
+ * // => false
+ *
+ * _.isPlainObject([1, 2, 3]);
+ * // => false
+ *
+ * _.isPlainObject({ 'x': 0, 'y': 0 });
+ * // => true
+ *
+ * _.isPlainObject(Object.create(null));
+ * // => true
+ */function isPlainObject(value){if(!isObjectLike(value)||baseGetTag(value)!=objectTag){return false;}var proto=getPrototype(value);if(proto===null){return true;}var Ctor=hasOwnProperty.call(proto,'constructor')&&proto.constructor;return typeof Ctor=='function'&&Ctor instanceof Ctor&&funcToString.call(Ctor)==objectCtorString;}/**
+ * Checks if `value` is classified as a `RegExp` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
+ * @example
+ *
+ * _.isRegExp(/abc/);
+ * // => true
+ *
+ * _.isRegExp('/abc/');
+ * // => false
+ */var isRegExp=nodeIsRegExp?baseUnary(nodeIsRegExp):baseIsRegExp;/**
+ * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
+ * double precision number which isn't the result of a rounded unsafe integer.
+ *
+ * **Note:** This method is based on
+ * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
+ * @example
+ *
+ * _.isSafeInteger(3);
+ * // => true
+ *
+ * _.isSafeInteger(Number.MIN_VALUE);
+ * // => false
+ *
+ * _.isSafeInteger(Infinity);
+ * // => false
+ *
+ * _.isSafeInteger('3');
+ * // => false
+ */function isSafeInteger(value){return isInteger(value)&&value>=-MAX_SAFE_INTEGER&&value<=MAX_SAFE_INTEGER;}/**
+ * Checks if `value` is classified as a `Set` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.3.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a set, else `false`.
+ * @example
+ *
+ * _.isSet(new Set);
+ * // => true
+ *
+ * _.isSet(new WeakSet);
+ * // => false
+ */var isSet=nodeIsSet?baseUnary(nodeIsSet):baseIsSet;/**
+ * Checks if `value` is classified as a `String` primitive or object.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a string, else `false`.
+ * @example
+ *
+ * _.isString('abc');
+ * // => true
+ *
+ * _.isString(1);
+ * // => false
+ */function isString(value){return typeof value=='string'||!isArray(value)&&isObjectLike(value)&&baseGetTag(value)==stringTag;}/**
+ * Checks if `value` is classified as a `Symbol` primitive or object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
+ * @example
+ *
+ * _.isSymbol(Symbol.iterator);
+ * // => true
+ *
+ * _.isSymbol('abc');
+ * // => false
+ */function isSymbol(value){return typeof value=='symbol'||isObjectLike(value)&&baseGetTag(value)==symbolTag;}/**
+ * Checks if `value` is classified as a typed array.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
+ * @example
+ *
+ * _.isTypedArray(new Uint8Array);
+ * // => true
+ *
+ * _.isTypedArray([]);
+ * // => false
+ */var isTypedArray=nodeIsTypedArray?baseUnary(nodeIsTypedArray):baseIsTypedArray;/**
+ * Checks if `value` is `undefined`.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
+ * @example
+ *
+ * _.isUndefined(void 0);
+ * // => true
+ *
+ * _.isUndefined(null);
+ * // => false
+ */function isUndefined(value){return value===undefined$1;}/**
+ * Checks if `value` is classified as a `WeakMap` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.3.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
+ * @example
+ *
+ * _.isWeakMap(new WeakMap);
+ * // => true
+ *
+ * _.isWeakMap(new Map);
+ * // => false
+ */function isWeakMap(value){return isObjectLike(value)&&getTag(value)==weakMapTag;}/**
+ * Checks if `value` is classified as a `WeakSet` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.3.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
+ * @example
+ *
+ * _.isWeakSet(new WeakSet);
+ * // => true
+ *
+ * _.isWeakSet(new Set);
+ * // => false
+ */function isWeakSet(value){return isObjectLike(value)&&baseGetTag(value)==weakSetTag;}/**
+ * Checks if `value` is less than `other`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.9.0
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if `value` is less than `other`,
+ * else `false`.
+ * @see _.gt
+ * @example
+ *
+ * _.lt(1, 3);
+ * // => true
+ *
+ * _.lt(3, 3);
+ * // => false
+ *
+ * _.lt(3, 1);
+ * // => false
+ */var lt=createRelationalOperation(baseLt);/**
+ * Checks if `value` is less than or equal to `other`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.9.0
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if `value` is less than or equal to
+ * `other`, else `false`.
+ * @see _.gte
+ * @example
+ *
+ * _.lte(1, 3);
+ * // => true
+ *
+ * _.lte(3, 3);
+ * // => true
+ *
+ * _.lte(3, 1);
+ * // => false
+ */var lte=createRelationalOperation(function(value,other){return value<=other;});/**
+ * Converts `value` to an array.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {Array} Returns the converted array.
+ * @example
+ *
+ * _.toArray({ 'a': 1, 'b': 2 });
+ * // => [1, 2]
+ *
+ * _.toArray('abc');
+ * // => ['a', 'b', 'c']
+ *
+ * _.toArray(1);
+ * // => []
+ *
+ * _.toArray(null);
+ * // => []
+ */function toArray(value){if(!value){return [];}if(isArrayLike(value)){return isString(value)?stringToArray(value):copyArray(value);}if(symIterator&&value[symIterator]){return iteratorToArray(value[symIterator]());}var tag=getTag(value),func=tag==mapTag?mapToArray:tag==setTag?setToArray:values;return func(value);}/**
+ * Converts `value` to a finite number.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.12.0
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {number} Returns the converted number.
+ * @example
+ *
+ * _.toFinite(3.2);
+ * // => 3.2
+ *
+ * _.toFinite(Number.MIN_VALUE);
+ * // => 5e-324
+ *
+ * _.toFinite(Infinity);
+ * // => 1.7976931348623157e+308
+ *
+ * _.toFinite('3.2');
+ * // => 3.2
+ */function toFinite(value){if(!value){return value===0?value:0;}value=toNumber(value);if(value===INFINITY||value===-INFINITY){var sign=value<0?-1:1;return sign*MAX_INTEGER;}return value===value?value:0;}/**
+ * Converts `value` to an integer.
+ *
+ * **Note:** This method is loosely based on
+ * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {number} Returns the converted integer.
+ * @example
+ *
+ * _.toInteger(3.2);
+ * // => 3
+ *
+ * _.toInteger(Number.MIN_VALUE);
+ * // => 0
+ *
+ * _.toInteger(Infinity);
+ * // => 1.7976931348623157e+308
+ *
+ * _.toInteger('3.2');
+ * // => 3
+ */function toInteger(value){var result=toFinite(value),remainder=result%1;return result===result?remainder?result-remainder:result:0;}/**
+ * Converts `value` to an integer suitable for use as the length of an
+ * array-like object.
+ *
+ * **Note:** This method is based on
+ * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {number} Returns the converted integer.
+ * @example
+ *
+ * _.toLength(3.2);
+ * // => 3
+ *
+ * _.toLength(Number.MIN_VALUE);
+ * // => 0
+ *
+ * _.toLength(Infinity);
+ * // => 4294967295
+ *
+ * _.toLength('3.2');
+ * // => 3
+ */function toLength(value){return value?baseClamp(toInteger(value),0,MAX_ARRAY_LENGTH):0;}/**
+ * Converts `value` to a number.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to process.
+ * @returns {number} Returns the number.
+ * @example
+ *
+ * _.toNumber(3.2);
+ * // => 3.2
+ *
+ * _.toNumber(Number.MIN_VALUE);
+ * // => 5e-324
+ *
+ * _.toNumber(Infinity);
+ * // => Infinity
+ *
+ * _.toNumber('3.2');
+ * // => 3.2
+ */function toNumber(value){if(typeof value=='number'){return value;}if(isSymbol(value)){return NAN;}if(isObject(value)){var other=typeof value.valueOf=='function'?value.valueOf():value;value=isObject(other)?other+'':other;}if(typeof value!='string'){return value===0?value:+value;}value=baseTrim(value);var isBinary=reIsBinary.test(value);return isBinary||reIsOctal.test(value)?freeParseInt(value.slice(2),isBinary?2:8):reIsBadHex.test(value)?NAN:+value;}/**
+ * Converts `value` to a plain object flattening inherited enumerable string
+ * keyed properties of `value` to own properties of the plain object.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {Object} Returns the converted plain object.
+ * @example
+ *
+ * function Foo() {
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.assign({ 'a': 1 }, new Foo);
+ * // => { 'a': 1, 'b': 2 }
+ *
+ * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
+ * // => { 'a': 1, 'b': 2, 'c': 3 }
+ */function toPlainObject(value){return copyObject(value,keysIn(value));}/**
+ * Converts `value` to a safe integer. A safe integer can be compared and
+ * represented correctly.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {number} Returns the converted integer.
+ * @example
+ *
+ * _.toSafeInteger(3.2);
+ * // => 3
+ *
+ * _.toSafeInteger(Number.MIN_VALUE);
+ * // => 0
+ *
+ * _.toSafeInteger(Infinity);
+ * // => 9007199254740991
+ *
+ * _.toSafeInteger('3.2');
+ * // => 3
+ */function toSafeInteger(value){return value?baseClamp(toInteger(value),-MAX_SAFE_INTEGER,MAX_SAFE_INTEGER):value===0?value:0;}/**
+ * Converts `value` to a string. An empty string is returned for `null`
+ * and `undefined` values. The sign of `-0` is preserved.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {string} Returns the converted string.
+ * @example
+ *
+ * _.toString(null);
+ * // => ''
+ *
+ * _.toString(-0);
+ * // => '-0'
+ *
+ * _.toString([1, 2, 3]);
+ * // => '1,2,3'
+ */function toString(value){return value==null?'':baseToString(value);}/*------------------------------------------------------------------------*/ /**
+ * Assigns own enumerable string keyed properties of source objects to the
+ * destination object. Source objects are applied from left to right.
+ * Subsequent sources overwrite property assignments of previous sources.
+ *
+ * **Note:** This method mutates `object` and is loosely based on
+ * [`Object.assign`](https://mdn.io/Object/assign).
+ *
+ * @static
+ * @memberOf _
+ * @since 0.10.0
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
+ * @see _.assignIn
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * }
+ *
+ * function Bar() {
+ * this.c = 3;
+ * }
+ *
+ * Foo.prototype.b = 2;
+ * Bar.prototype.d = 4;
+ *
+ * _.assign({ 'a': 0 }, new Foo, new Bar);
+ * // => { 'a': 1, 'c': 3 }
+ */var assign=createAssigner(function(object,source){if(isPrototype(source)||isArrayLike(source)){copyObject(source,keys(source),object);return;}for(var key in source){if(hasOwnProperty.call(source,key)){assignValue(object,key,source[key]);}}});/**
+ * This method is like `_.assign` except that it iterates over own and
+ * inherited source properties.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @alias extend
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
+ * @see _.assign
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * }
+ *
+ * function Bar() {
+ * this.c = 3;
+ * }
+ *
+ * Foo.prototype.b = 2;
+ * Bar.prototype.d = 4;
+ *
+ * _.assignIn({ 'a': 0 }, new Foo, new Bar);
+ * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
+ */var assignIn=createAssigner(function(object,source){copyObject(source,keysIn(source),object);});/**
+ * This method is like `_.assignIn` except that it accepts `customizer`
+ * which is invoked to produce the assigned values. If `customizer` returns
+ * `undefined`, assignment is handled by the method instead. The `customizer`
+ * is invoked with five arguments: (objValue, srcValue, key, object, source).
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @alias extendWith
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} sources The source objects.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @returns {Object} Returns `object`.
+ * @see _.assignWith
+ * @example
+ *
+ * function customizer(objValue, srcValue) {
+ * return _.isUndefined(objValue) ? srcValue : objValue;
+ * }
+ *
+ * var defaults = _.partialRight(_.assignInWith, customizer);
+ *
+ * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
+ * // => { 'a': 1, 'b': 2 }
+ */var assignInWith=createAssigner(function(object,source,srcIndex,customizer){copyObject(source,keysIn(source),object,customizer);});/**
+ * This method is like `_.assign` except that it accepts `customizer`
+ * which is invoked to produce the assigned values. If `customizer` returns
+ * `undefined`, assignment is handled by the method instead. The `customizer`
+ * is invoked with five arguments: (objValue, srcValue, key, object, source).
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} sources The source objects.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @returns {Object} Returns `object`.
+ * @see _.assignInWith
+ * @example
+ *
+ * function customizer(objValue, srcValue) {
+ * return _.isUndefined(objValue) ? srcValue : objValue;
+ * }
+ *
+ * var defaults = _.partialRight(_.assignWith, customizer);
+ *
+ * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
+ * // => { 'a': 1, 'b': 2 }
+ */var assignWith=createAssigner(function(object,source,srcIndex,customizer){copyObject(source,keys(source),object,customizer);});/**
+ * Creates an array of values corresponding to `paths` of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.0.0
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {...(string|string[])} [paths] The property paths to pick.
+ * @returns {Array} Returns the picked values.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
+ *
+ * _.at(object, ['a[0].b.c', 'a[1]']);
+ * // => [3, 4]
+ */var at=flatRest(baseAt);/**
+ * Creates an object that inherits from the `prototype` object. If a
+ * `properties` object is given, its own enumerable string keyed properties
+ * are assigned to the created object.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.3.0
+ * @category Object
+ * @param {Object} prototype The object to inherit from.
+ * @param {Object} [properties] The properties to assign to the object.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * function Shape() {
+ * this.x = 0;
+ * this.y = 0;
+ * }
+ *
+ * function Circle() {
+ * Shape.call(this);
+ * }
+ *
+ * Circle.prototype = _.create(Shape.prototype, {
+ * 'constructor': Circle
+ * });
+ *
+ * var circle = new Circle;
+ * circle instanceof Circle;
+ * // => true
+ *
+ * circle instanceof Shape;
+ * // => true
+ */function create(prototype,properties){var result=baseCreate(prototype);return properties==null?result:baseAssign(result,properties);}/**
+ * Assigns own and inherited enumerable string keyed properties of source
+ * objects to the destination object for all destination properties that
+ * resolve to `undefined`. Source objects are applied from left to right.
+ * Once a property is set, additional values of the same property are ignored.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
+ * @see _.defaultsDeep
+ * @example
+ *
+ * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
+ * // => { 'a': 1, 'b': 2 }
+ */var defaults=baseRest(function(object,sources){object=Object(object);var index=-1;var length=sources.length;var guard=length>2?sources[2]:undefined$1;if(guard&&isIterateeCall(sources[0],sources[1],guard)){length=1;}while(++index<length){var source=sources[index];var props=keysIn(source);var propsIndex=-1;var propsLength=props.length;while(++propsIndex<propsLength){var key=props[propsIndex];var value=object[key];if(value===undefined$1||eq(value,objectProto[key])&&!hasOwnProperty.call(object,key)){object[key]=source[key];}}}return object;});/**
+ * This method is like `_.defaults` except that it recursively assigns
+ * default properties.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.10.0
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
+ * @see _.defaults
+ * @example
+ *
+ * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
+ * // => { 'a': { 'b': 2, 'c': 3 } }
+ */var defaultsDeep=baseRest(function(args){args.push(undefined$1,customDefaultsMerge);return apply(mergeWith,undefined$1,args);});/**
+ * This method is like `_.find` except that it returns the key of the first
+ * element `predicate` returns truthy for instead of the element itself.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.1.0
+ * @category Object
+ * @param {Object} object The object to inspect.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {string|undefined} Returns the key of the matched element,
+ * else `undefined`.
+ * @example
+ *
+ * var users = {
+ * 'barney': { 'age': 36, 'active': true },
+ * 'fred': { 'age': 40, 'active': false },
+ * 'pebbles': { 'age': 1, 'active': true }
+ * };
+ *
+ * _.findKey(users, function(o) { return o.age < 40; });
+ * // => 'barney' (iteration order is not guaranteed)
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.findKey(users, { 'age': 1, 'active': true });
+ * // => 'pebbles'
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.findKey(users, ['active', false]);
+ * // => 'fred'
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.findKey(users, 'active');
+ * // => 'barney'
+ */function findKey(object,predicate){return baseFindKey(object,getIteratee(predicate,3),baseForOwn);}/**
+ * This method is like `_.findKey` except that it iterates over elements of
+ * a collection in the opposite order.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @category Object
+ * @param {Object} object The object to inspect.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {string|undefined} Returns the key of the matched element,
+ * else `undefined`.
+ * @example
+ *
+ * var users = {
+ * 'barney': { 'age': 36, 'active': true },
+ * 'fred': { 'age': 40, 'active': false },
+ * 'pebbles': { 'age': 1, 'active': true }
+ * };
+ *
+ * _.findLastKey(users, function(o) { return o.age < 40; });
+ * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.findLastKey(users, { 'age': 36, 'active': true });
+ * // => 'barney'
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.findLastKey(users, ['active', false]);
+ * // => 'fred'
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.findLastKey(users, 'active');
+ * // => 'pebbles'
+ */function findLastKey(object,predicate){return baseFindKey(object,getIteratee(predicate,3),baseForOwnRight);}/**
+ * Iterates over own and inherited enumerable string keyed properties of an
+ * object and invokes `iteratee` for each property. The iteratee is invoked
+ * with three arguments: (value, key, object). Iteratee functions may exit
+ * iteration early by explicitly returning `false`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.3.0
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ * @see _.forInRight
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.forIn(new Foo, function(value, key) {
+ * console.log(key);
+ * });
+ * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
+ */function forIn(object,iteratee){return object==null?object:baseFor(object,getIteratee(iteratee,3),keysIn);}/**
+ * This method is like `_.forIn` except that it iterates over properties of
+ * `object` in the opposite order.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ * @see _.forIn
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.forInRight(new Foo, function(value, key) {
+ * console.log(key);
+ * });
+ * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
+ */function forInRight(object,iteratee){return object==null?object:baseForRight(object,getIteratee(iteratee,3),keysIn);}/**
+ * Iterates over own enumerable string keyed properties of an object and
+ * invokes `iteratee` for each property. The iteratee is invoked with three
+ * arguments: (value, key, object). Iteratee functions may exit iteration
+ * early by explicitly returning `false`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.3.0
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ * @see _.forOwnRight
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.forOwn(new Foo, function(value, key) {
+ * console.log(key);
+ * });
+ * // => Logs 'a' then 'b' (iteration order is not guaranteed).
+ */function forOwn(object,iteratee){return object&&baseForOwn(object,getIteratee(iteratee,3));}/**
+ * This method is like `_.forOwn` except that it iterates over properties of
+ * `object` in the opposite order.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ * @see _.forOwn
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.forOwnRight(new Foo, function(value, key) {
+ * console.log(key);
+ * });
+ * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
+ */function forOwnRight(object,iteratee){return object&&baseForOwnRight(object,getIteratee(iteratee,3));}/**
+ * Creates an array of function property names from own enumerable properties
+ * of `object`.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to inspect.
+ * @returns {Array} Returns the function names.
+ * @see _.functionsIn
+ * @example
+ *
+ * function Foo() {
+ * this.a = _.constant('a');
+ * this.b = _.constant('b');
+ * }
+ *
+ * Foo.prototype.c = _.constant('c');
+ *
+ * _.functions(new Foo);
+ * // => ['a', 'b']
+ */function functions(object){return object==null?[]:baseFunctions(object,keys(object));}/**
+ * Creates an array of function property names from own and inherited
+ * enumerable properties of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Object
+ * @param {Object} object The object to inspect.
+ * @returns {Array} Returns the function names.
+ * @see _.functions
+ * @example
+ *
+ * function Foo() {
+ * this.a = _.constant('a');
+ * this.b = _.constant('b');
+ * }
+ *
+ * Foo.prototype.c = _.constant('c');
+ *
+ * _.functionsIn(new Foo);
+ * // => ['a', 'b', 'c']
+ */function functionsIn(object){return object==null?[]:baseFunctions(object,keysIn(object));}/**
+ * Gets the value at `path` of `object`. If the resolved value is
+ * `undefined`, the `defaultValue` is returned in its place.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.7.0
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the property to get.
+ * @param {*} [defaultValue] The value returned for `undefined` resolved values.
+ * @returns {*} Returns the resolved value.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 3 } }] };
+ *
+ * _.get(object, 'a[0].b.c');
+ * // => 3
+ *
+ * _.get(object, ['a', '0', 'b', 'c']);
+ * // => 3
+ *
+ * _.get(object, 'a.b.c', 'default');
+ * // => 'default'
+ */function get(object,path,defaultValue){var result=object==null?undefined$1:baseGet(object,path);return result===undefined$1?defaultValue:result;}/**
+ * Checks if `path` is a direct property of `object`.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path to check.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ * @example
+ *
+ * var object = { 'a': { 'b': 2 } };
+ * var other = _.create({ 'a': _.create({ 'b': 2 }) });
+ *
+ * _.has(object, 'a');
+ * // => true
+ *
+ * _.has(object, 'a.b');
+ * // => true
+ *
+ * _.has(object, ['a', 'b']);
+ * // => true
+ *
+ * _.has(other, 'a');
+ * // => false
+ */function has(object,path){return object!=null&&hasPath(object,path,baseHas);}/**
+ * Checks if `path` is a direct or inherited property of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path to check.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ * @example
+ *
+ * var object = _.create({ 'a': _.create({ 'b': 2 }) });
+ *
+ * _.hasIn(object, 'a');
+ * // => true
+ *
+ * _.hasIn(object, 'a.b');
+ * // => true
+ *
+ * _.hasIn(object, ['a', 'b']);
+ * // => true
+ *
+ * _.hasIn(object, 'b');
+ * // => false
+ */function hasIn(object,path){return object!=null&&hasPath(object,path,baseHasIn);}/**
+ * Creates an object composed of the inverted keys and values of `object`.
+ * If `object` contains duplicate values, subsequent values overwrite
+ * property assignments of previous values.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.7.0
+ * @category Object
+ * @param {Object} object The object to invert.
+ * @returns {Object} Returns the new inverted object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': 2, 'c': 1 };
+ *
+ * _.invert(object);
+ * // => { '1': 'c', '2': 'b' }
+ */var invert=createInverter(function(result,value,key){if(value!=null&&typeof value.toString!='function'){value=nativeObjectToString.call(value);}result[value]=key;},constant(identity));/**
+ * This method is like `_.invert` except that the inverted object is generated
+ * from the results of running each element of `object` thru `iteratee`. The
+ * corresponding inverted value of each inverted key is an array of keys
+ * responsible for generating the inverted value. The iteratee is invoked
+ * with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.1.0
+ * @category Object
+ * @param {Object} object The object to invert.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Object} Returns the new inverted object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': 2, 'c': 1 };
+ *
+ * _.invertBy(object);
+ * // => { '1': ['a', 'c'], '2': ['b'] }
+ *
+ * _.invertBy(object, function(value) {
+ * return 'group' + value;
+ * });
+ * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
+ */var invertBy=createInverter(function(result,value,key){if(value!=null&&typeof value.toString!='function'){value=nativeObjectToString.call(value);}if(hasOwnProperty.call(result,value)){result[value].push(key);}else {result[value]=[key];}},getIteratee);/**
+ * Invokes the method at `path` of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the method to invoke.
+ * @param {...*} [args] The arguments to invoke the method with.
+ * @returns {*} Returns the result of the invoked method.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
+ *
+ * _.invoke(object, 'a[0].b.c.slice', 1, 3);
+ * // => [2, 3]
+ */var invoke=baseRest(baseInvoke);/**
+ * Creates an array of the own enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects. See the
+ * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
+ * for more details.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keys(new Foo);
+ * // => ['a', 'b'] (iteration order is not guaranteed)
+ *
+ * _.keys('hi');
+ * // => ['0', '1']
+ */function keys(object){return isArrayLike(object)?arrayLikeKeys(object):baseKeys(object);}/**
+ * Creates an array of the own and inherited enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keysIn(new Foo);
+ * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
+ */function keysIn(object){return isArrayLike(object)?arrayLikeKeys(object,true):baseKeysIn(object);}/**
+ * The opposite of `_.mapValues`; this method creates an object with the
+ * same values as `object` and keys generated by running each own enumerable
+ * string keyed property of `object` thru `iteratee`. The iteratee is invoked
+ * with three arguments: (value, key, object).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.8.0
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns the new mapped object.
+ * @see _.mapValues
+ * @example
+ *
+ * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
+ * return key + value;
+ * });
+ * // => { 'a1': 1, 'b2': 2 }
+ */function mapKeys(object,iteratee){var result={};iteratee=getIteratee(iteratee,3);baseForOwn(object,function(value,key,object){baseAssignValue(result,iteratee(value,key,object),value);});return result;}/**
+ * Creates an object with the same keys as `object` and values generated
+ * by running each own enumerable string keyed property of `object` thru
+ * `iteratee`. The iteratee is invoked with three arguments:
+ * (value, key, object).
+ *
+ * @static
+ * @memberOf _
+ * @since 2.4.0
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns the new mapped object.
+ * @see _.mapKeys
+ * @example
+ *
+ * var users = {
+ * 'fred': { 'user': 'fred', 'age': 40 },
+ * 'pebbles': { 'user': 'pebbles', 'age': 1 }
+ * };
+ *
+ * _.mapValues(users, function(o) { return o.age; });
+ * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.mapValues(users, 'age');
+ * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
+ */function mapValues(object,iteratee){var result={};iteratee=getIteratee(iteratee,3);baseForOwn(object,function(value,key,object){baseAssignValue(result,key,iteratee(value,key,object));});return result;}/**
+ * This method is like `_.assign` except that it recursively merges own and
+ * inherited enumerable string keyed properties of source objects into the
+ * destination object. Source properties that resolve to `undefined` are
+ * skipped if a destination value exists. Array and plain object properties
+ * are merged recursively. Other objects and value types are overridden by
+ * assignment. Source objects are applied from left to right. Subsequent
+ * sources overwrite property assignments of previous sources.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.5.0
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * var object = {
+ * 'a': [{ 'b': 2 }, { 'd': 4 }]
+ * };
+ *
+ * var other = {
+ * 'a': [{ 'c': 3 }, { 'e': 5 }]
+ * };
+ *
+ * _.merge(object, other);
+ * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
+ */var merge=createAssigner(function(object,source,srcIndex){baseMerge(object,source,srcIndex);});/**
+ * This method is like `_.merge` except that it accepts `customizer` which
+ * is invoked to produce the merged values of the destination and source
+ * properties. If `customizer` returns `undefined`, merging is handled by the
+ * method instead. The `customizer` is invoked with six arguments:
+ * (objValue, srcValue, key, object, source, stack).
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} sources The source objects.
+ * @param {Function} customizer The function to customize assigned values.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * function customizer(objValue, srcValue) {
+ * if (_.isArray(objValue)) {
+ * return objValue.concat(srcValue);
+ * }
+ * }
+ *
+ * var object = { 'a': [1], 'b': [2] };
+ * var other = { 'a': [3], 'b': [4] };
+ *
+ * _.mergeWith(object, other, customizer);
+ * // => { 'a': [1, 3], 'b': [2, 4] }
+ */var mergeWith=createAssigner(function(object,source,srcIndex,customizer){baseMerge(object,source,srcIndex,customizer);});/**
+ * The opposite of `_.pick`; this method creates an object composed of the
+ * own and inherited enumerable property paths of `object` that are not omitted.
+ *
+ * **Note:** This method is considerably slower than `_.pick`.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The source object.
+ * @param {...(string|string[])} [paths] The property paths to omit.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
+ *
+ * _.omit(object, ['a', 'c']);
+ * // => { 'b': '2' }
+ */var omit=flatRest(function(object,paths){var result={};if(object==null){return result;}var isDeep=false;paths=arrayMap(paths,function(path){path=castPath(path,object);isDeep||(isDeep=path.length>1);return path;});copyObject(object,getAllKeysIn(object),result);if(isDeep){result=baseClone(result,CLONE_DEEP_FLAG|CLONE_FLAT_FLAG|CLONE_SYMBOLS_FLAG,customOmitClone);}var length=paths.length;while(length--){baseUnset(result,paths[length]);}return result;});/**
+ * The opposite of `_.pickBy`; this method creates an object composed of
+ * the own and inherited enumerable string keyed properties of `object` that
+ * `predicate` doesn't return truthy for. The predicate is invoked with two
+ * arguments: (value, key).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Object
+ * @param {Object} object The source object.
+ * @param {Function} [predicate=_.identity] The function invoked per property.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
+ *
+ * _.omitBy(object, _.isNumber);
+ * // => { 'b': '2' }
+ */function omitBy(object,predicate){return pickBy(object,negate(getIteratee(predicate)));}/**
+ * Creates an object composed of the picked `object` properties.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The source object.
+ * @param {...(string|string[])} [paths] The property paths to pick.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
+ *
+ * _.pick(object, ['a', 'c']);
+ * // => { 'a': 1, 'c': 3 }
+ */var pick=flatRest(function(object,paths){return object==null?{}:basePick(object,paths);});/**
+ * Creates an object composed of the `object` properties `predicate` returns
+ * truthy for. The predicate is invoked with two arguments: (value, key).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Object
+ * @param {Object} object The source object.
+ * @param {Function} [predicate=_.identity] The function invoked per property.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
+ *
+ * _.pickBy(object, _.isNumber);
+ * // => { 'a': 1, 'c': 3 }
+ */function pickBy(object,predicate){if(object==null){return {};}var props=arrayMap(getAllKeysIn(object),function(prop){return [prop];});predicate=getIteratee(predicate);return basePickBy(object,props,function(value,path){return predicate(value,path[0]);});}/**
+ * This method is like `_.get` except that if the resolved value is a
+ * function it's invoked with the `this` binding of its parent object and
+ * its result is returned.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the property to resolve.
+ * @param {*} [defaultValue] The value returned for `undefined` resolved values.
+ * @returns {*} Returns the resolved value.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
+ *
+ * _.result(object, 'a[0].b.c1');
+ * // => 3
+ *
+ * _.result(object, 'a[0].b.c2');
+ * // => 4
+ *
+ * _.result(object, 'a[0].b.c3', 'default');
+ * // => 'default'
+ *
+ * _.result(object, 'a[0].b.c3', _.constant('default'));
+ * // => 'default'
+ */function result(object,path,defaultValue){path=castPath(path,object);var index=-1,length=path.length;// Ensure the loop is entered when path is empty.
+if(!length){length=1;object=undefined$1;}while(++index<length){var value=object==null?undefined$1:object[toKey(path[index])];if(value===undefined$1){index=length;value=defaultValue;}object=isFunction(value)?value.call(object):value;}return object;}/**
+ * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
+ * it's created. Arrays are created for missing index properties while objects
+ * are created for all other missing properties. Use `_.setWith` to customize
+ * `path` creation.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.7.0
+ * @category Object
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 3 } }] };
+ *
+ * _.set(object, 'a[0].b.c', 4);
+ * console.log(object.a[0].b.c);
+ * // => 4
+ *
+ * _.set(object, ['x', '0', 'y', 'z'], 5);
+ * console.log(object.x[0].y.z);
+ * // => 5
+ */function set(object,path,value){return object==null?object:baseSet(object,path,value);}/**
+ * This method is like `_.set` except that it accepts `customizer` which is
+ * invoked to produce the objects of `path`. If `customizer` returns `undefined`
+ * path creation is handled by the method instead. The `customizer` is invoked
+ * with three arguments: (nsValue, key, nsObject).
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Object
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to set.
+ * @param {*} value The value to set.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * var object = {};
+ *
+ * _.setWith(object, '[0][1]', 'a', Object);
+ * // => { '0': { '1': 'a' } }
+ */function setWith(object,path,value,customizer){customizer=typeof customizer=='function'?customizer:undefined$1;return object==null?object:baseSet(object,path,value,customizer);}/**
+ * Creates an array of own enumerable string keyed-value pairs for `object`
+ * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
+ * entries are returned.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @alias entries
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the key-value pairs.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.toPairs(new Foo);
+ * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
+ */var toPairs=createToPairs(keys);/**
+ * Creates an array of own and inherited enumerable string keyed-value pairs
+ * for `object` which can be consumed by `_.fromPairs`. If `object` is a map
+ * or set, its entries are returned.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @alias entriesIn
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the key-value pairs.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.toPairsIn(new Foo);
+ * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
+ */var toPairsIn=createToPairs(keysIn);/**
+ * An alternative to `_.reduce`; this method transforms `object` to a new
+ * `accumulator` object which is the result of running each of its own
+ * enumerable string keyed properties thru `iteratee`, with each invocation
+ * potentially mutating the `accumulator` object. If `accumulator` is not
+ * provided, a new object with the same `[[Prototype]]` will be used. The
+ * iteratee is invoked with four arguments: (accumulator, value, key, object).
+ * Iteratee functions may exit iteration early by explicitly returning `false`.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.3.0
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @param {*} [accumulator] The custom accumulator value.
+ * @returns {*} Returns the accumulated value.
+ * @example
+ *
+ * _.transform([2, 3, 4], function(result, n) {
+ * result.push(n *= n);
+ * return n % 2 == 0;
+ * }, []);
+ * // => [4, 9]
+ *
+ * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
+ * (result[value] || (result[value] = [])).push(key);
+ * }, {});
+ * // => { '1': ['a', 'c'], '2': ['b'] }
+ */function transform(object,iteratee,accumulator){var isArr=isArray(object),isArrLike=isArr||isBuffer(object)||isTypedArray(object);iteratee=getIteratee(iteratee,4);if(accumulator==null){var Ctor=object&&object.constructor;if(isArrLike){accumulator=isArr?new Ctor():[];}else if(isObject(object)){accumulator=isFunction(Ctor)?baseCreate(getPrototype(object)):{};}else {accumulator={};}}(isArrLike?arrayEach:baseForOwn)(object,function(value,index,object){return iteratee(accumulator,value,index,object);});return accumulator;}/**
+ * Removes the property at `path` of `object`.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Object
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to unset.
+ * @returns {boolean} Returns `true` if the property is deleted, else `false`.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 7 } }] };
+ * _.unset(object, 'a[0].b.c');
+ * // => true
+ *
+ * console.log(object);
+ * // => { 'a': [{ 'b': {} }] };
+ *
+ * _.unset(object, ['a', '0', 'b', 'c']);
+ * // => true
+ *
+ * console.log(object);
+ * // => { 'a': [{ 'b': {} }] };
+ */function unset(object,path){return object==null?true:baseUnset(object,path);}/**
+ * This method is like `_.set` except that accepts `updater` to produce the
+ * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
+ * is invoked with one argument: (value).
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.6.0
+ * @category Object
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to set.
+ * @param {Function} updater The function to produce the updated value.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 3 } }] };
+ *
+ * _.update(object, 'a[0].b.c', function(n) { return n * n; });
+ * console.log(object.a[0].b.c);
+ * // => 9
+ *
+ * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
+ * console.log(object.x[0].y.z);
+ * // => 0
+ */function update(object,path,updater){return object==null?object:baseUpdate(object,path,castFunction(updater));}/**
+ * This method is like `_.update` except that it accepts `customizer` which is
+ * invoked to produce the objects of `path`. If `customizer` returns `undefined`
+ * path creation is handled by the method instead. The `customizer` is invoked
+ * with three arguments: (nsValue, key, nsObject).
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.6.0
+ * @category Object
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to set.
+ * @param {Function} updater The function to produce the updated value.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * var object = {};
+ *
+ * _.updateWith(object, '[0][1]', _.constant('a'), Object);
+ * // => { '0': { '1': 'a' } }
+ */function updateWith(object,path,updater,customizer){customizer=typeof customizer=='function'?customizer:undefined$1;return object==null?object:baseUpdate(object,path,castFunction(updater),customizer);}/**
+ * Creates an array of the own enumerable string keyed property values of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property values.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.values(new Foo);
+ * // => [1, 2] (iteration order is not guaranteed)
+ *
+ * _.values('hi');
+ * // => ['h', 'i']
+ */function values(object){return object==null?[]:baseValues(object,keys(object));}/**
+ * Creates an array of the own and inherited enumerable string keyed property
+ * values of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property values.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.valuesIn(new Foo);
+ * // => [1, 2, 3] (iteration order is not guaranteed)
+ */function valuesIn(object){return object==null?[]:baseValues(object,keysIn(object));}/*------------------------------------------------------------------------*/ /**
+ * Clamps `number` within the inclusive `lower` and `upper` bounds.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Number
+ * @param {number} number The number to clamp.
+ * @param {number} [lower] The lower bound.
+ * @param {number} upper The upper bound.
+ * @returns {number} Returns the clamped number.
+ * @example
+ *
+ * _.clamp(-10, -5, 5);
+ * // => -5
+ *
+ * _.clamp(10, -5, 5);
+ * // => 5
+ */function clamp(number,lower,upper){if(upper===undefined$1){upper=lower;lower=undefined$1;}if(upper!==undefined$1){upper=toNumber(upper);upper=upper===upper?upper:0;}if(lower!==undefined$1){lower=toNumber(lower);lower=lower===lower?lower:0;}return baseClamp(toNumber(number),lower,upper);}/**
+ * Checks if `n` is between `start` and up to, but not including, `end`. If
+ * `end` is not specified, it's set to `start` with `start` then set to `0`.
+ * If `start` is greater than `end` the params are swapped to support
+ * negative ranges.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.3.0
+ * @category Number
+ * @param {number} number The number to check.
+ * @param {number} [start=0] The start of the range.
+ * @param {number} end The end of the range.
+ * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
+ * @see _.range, _.rangeRight
+ * @example
+ *
+ * _.inRange(3, 2, 4);
+ * // => true
+ *
+ * _.inRange(4, 8);
+ * // => true
+ *
+ * _.inRange(4, 2);
+ * // => false
+ *
+ * _.inRange(2, 2);
+ * // => false
+ *
+ * _.inRange(1.2, 2);
+ * // => true
+ *
+ * _.inRange(5.2, 4);
+ * // => false
+ *
+ * _.inRange(-3, -2, -6);
+ * // => true
+ */function inRange(number,start,end){start=toFinite(start);if(end===undefined$1){end=start;start=0;}else {end=toFinite(end);}number=toNumber(number);return baseInRange(number,start,end);}/**
+ * Produces a random number between the inclusive `lower` and `upper` bounds.
+ * If only one argument is provided a number between `0` and the given number
+ * is returned. If `floating` is `true`, or either `lower` or `upper` are
+ * floats, a floating-point number is returned instead of an integer.
+ *
+ * **Note:** JavaScript follows the IEEE-754 standard for resolving
+ * floating-point values which can produce unexpected results.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.7.0
+ * @category Number
+ * @param {number} [lower=0] The lower bound.
+ * @param {number} [upper=1] The upper bound.
+ * @param {boolean} [floating] Specify returning a floating-point number.
+ * @returns {number} Returns the random number.
+ * @example
+ *
+ * _.random(0, 5);
+ * // => an integer between 0 and 5
+ *
+ * _.random(5);
+ * // => also an integer between 0 and 5
+ *
+ * _.random(5, true);
+ * // => a floating-point number between 0 and 5
+ *
+ * _.random(1.2, 5.2);
+ * // => a floating-point number between 1.2 and 5.2
+ */function random(lower,upper,floating){if(floating&&typeof floating!='boolean'&&isIterateeCall(lower,upper,floating)){upper=floating=undefined$1;}if(floating===undefined$1){if(typeof upper=='boolean'){floating=upper;upper=undefined$1;}else if(typeof lower=='boolean'){floating=lower;lower=undefined$1;}}if(lower===undefined$1&&upper===undefined$1){lower=0;upper=1;}else {lower=toFinite(lower);if(upper===undefined$1){upper=lower;lower=0;}else {upper=toFinite(upper);}}if(lower>upper){var temp=lower;lower=upper;upper=temp;}if(floating||lower%1||upper%1){var rand=nativeRandom();return nativeMin(lower+rand*(upper-lower+freeParseFloat('1e-'+((rand+'').length-1))),upper);}return baseRandom(lower,upper);}/*------------------------------------------------------------------------*/ /**
+ * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the camel cased string.
+ * @example
+ *
+ * _.camelCase('Foo Bar');
+ * // => 'fooBar'
+ *
+ * _.camelCase('--foo-bar--');
+ * // => 'fooBar'
+ *
+ * _.camelCase('__FOO_BAR__');
+ * // => 'fooBar'
+ */var camelCase=createCompounder(function(result,word,index){word=word.toLowerCase();return result+(index?capitalize(word):word);});/**
+ * Converts the first character of `string` to upper case and the remaining
+ * to lower case.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to capitalize.
+ * @returns {string} Returns the capitalized string.
+ * @example
+ *
+ * _.capitalize('FRED');
+ * // => 'Fred'
+ */function capitalize(string){return upperFirst(toString(string).toLowerCase());}/**
+ * Deburrs `string` by converting
+ * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
+ * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
+ * letters to basic Latin letters and removing
+ * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to deburr.
+ * @returns {string} Returns the deburred string.
+ * @example
+ *
+ * _.deburr('d茅j脿 vu');
+ * // => 'deja vu'
+ */function deburr(string){string=toString(string);return string&&string.replace(reLatin,deburrLetter).replace(reComboMark,'');}/**
+ * Checks if `string` ends with the given target string.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to inspect.
+ * @param {string} [target] The string to search for.
+ * @param {number} [position=string.length] The position to search up to.
+ * @returns {boolean} Returns `true` if `string` ends with `target`,
+ * else `false`.
+ * @example
+ *
+ * _.endsWith('abc', 'c');
+ * // => true
+ *
+ * _.endsWith('abc', 'b');
+ * // => false
+ *
+ * _.endsWith('abc', 'b', 2);
+ * // => true
+ */function endsWith(string,target,position){string=toString(string);target=baseToString(target);var length=string.length;position=position===undefined$1?length:baseClamp(toInteger(position),0,length);var end=position;position-=target.length;return position>=0&&string.slice(position,end)==target;}/**
+ * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
+ * corresponding HTML entities.
+ *
+ * **Note:** No other characters are escaped. To escape additional
+ * characters use a third-party library like [_he_](https://mths.be/he).
+ *
+ * Though the ">" character is escaped for symmetry, characters like
+ * ">" and "/" don't need escaping in HTML and have no special meaning
+ * unless they're part of a tag or unquoted attribute value. See
+ * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
+ * (under "semi-related fun fact") for more details.
+ *
+ * When working with HTML you should always
+ * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
+ * XSS vectors.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to escape.
+ * @returns {string} Returns the escaped string.
+ * @example
+ *
+ * _.escape('fred, barney, & pebbles');
+ * // => 'fred, barney, & pebbles'
+ */function escape(string){string=toString(string);return string&&reHasUnescapedHtml.test(string)?string.replace(reUnescapedHtml,escapeHtmlChar):string;}/**
+ * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
+ * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to escape.
+ * @returns {string} Returns the escaped string.
+ * @example
+ *
+ * _.escapeRegExp('[lodash](https://lodash.com/)');
+ * // => '\[lodash\]\(https://lodash\.com/\)'
+ */function escapeRegExp(string){string=toString(string);return string&&reHasRegExpChar.test(string)?string.replace(reRegExpChar,'\\$&'):string;}/**
+ * Converts `string` to
+ * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the kebab cased string.
+ * @example
+ *
+ * _.kebabCase('Foo Bar');
+ * // => 'foo-bar'
+ *
+ * _.kebabCase('fooBar');
+ * // => 'foo-bar'
+ *
+ * _.kebabCase('__FOO_BAR__');
+ * // => 'foo-bar'
+ */var kebabCase=createCompounder(function(result,word,index){return result+(index?'-':'')+word.toLowerCase();});/**
+ * Converts `string`, as space separated words, to lower case.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the lower cased string.
+ * @example
+ *
+ * _.lowerCase('--Foo-Bar--');
+ * // => 'foo bar'
+ *
+ * _.lowerCase('fooBar');
+ * // => 'foo bar'
+ *
+ * _.lowerCase('__FOO_BAR__');
+ * // => 'foo bar'
+ */var lowerCase=createCompounder(function(result,word,index){return result+(index?' ':'')+word.toLowerCase();});/**
+ * Converts the first character of `string` to lower case.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the converted string.
+ * @example
+ *
+ * _.lowerFirst('Fred');
+ * // => 'fred'
+ *
+ * _.lowerFirst('FRED');
+ * // => 'fRED'
+ */var lowerFirst=createCaseFirst('toLowerCase');/**
+ * Pads `string` on the left and right sides if it's shorter than `length`.
+ * Padding characters are truncated if they can't be evenly divided by `length`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to pad.
+ * @param {number} [length=0] The padding length.
+ * @param {string} [chars=' '] The string used as padding.
+ * @returns {string} Returns the padded string.
+ * @example
+ *
+ * _.pad('abc', 8);
+ * // => ' abc '
+ *
+ * _.pad('abc', 8, '_-');
+ * // => '_-abc_-_'
+ *
+ * _.pad('abc', 3);
+ * // => 'abc'
+ */function pad(string,length,chars){string=toString(string);length=toInteger(length);var strLength=length?stringSize(string):0;if(!length||strLength>=length){return string;}var mid=(length-strLength)/2;return createPadding(nativeFloor(mid),chars)+string+createPadding(nativeCeil(mid),chars);}/**
+ * Pads `string` on the right side if it's shorter than `length`. Padding
+ * characters are truncated if they exceed `length`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to pad.
+ * @param {number} [length=0] The padding length.
+ * @param {string} [chars=' '] The string used as padding.
+ * @returns {string} Returns the padded string.
+ * @example
+ *
+ * _.padEnd('abc', 6);
+ * // => 'abc '
+ *
+ * _.padEnd('abc', 6, '_-');
+ * // => 'abc_-_'
+ *
+ * _.padEnd('abc', 3);
+ * // => 'abc'
+ */function padEnd(string,length,chars){string=toString(string);length=toInteger(length);var strLength=length?stringSize(string):0;return length&&strLength<length?string+createPadding(length-strLength,chars):string;}/**
+ * Pads `string` on the left side if it's shorter than `length`. Padding
+ * characters are truncated if they exceed `length`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to pad.
+ * @param {number} [length=0] The padding length.
+ * @param {string} [chars=' '] The string used as padding.
+ * @returns {string} Returns the padded string.
+ * @example
+ *
+ * _.padStart('abc', 6);
+ * // => ' abc'
+ *
+ * _.padStart('abc', 6, '_-');
+ * // => '_-_abc'
+ *
+ * _.padStart('abc', 3);
+ * // => 'abc'
+ */function padStart(string,length,chars){string=toString(string);length=toInteger(length);var strLength=length?stringSize(string):0;return length&&strLength<length?createPadding(length-strLength,chars)+string:string;}/**
+ * Converts `string` to an integer of the specified radix. If `radix` is
+ * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
+ * hexadecimal, in which case a `radix` of `16` is used.
+ *
+ * **Note:** This method aligns with the
+ * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.1.0
+ * @category String
+ * @param {string} string The string to convert.
+ * @param {number} [radix=10] The radix to interpret `value` by.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {number} Returns the converted integer.
+ * @example
+ *
+ * _.parseInt('08');
+ * // => 8
+ *
+ * _.map(['6', '08', '10'], _.parseInt);
+ * // => [6, 8, 10]
+ */function parseInt(string,radix,guard){if(guard||radix==null){radix=0;}else if(radix){radix=+radix;}return nativeParseInt(toString(string).replace(reTrimStart,''),radix||0);}/**
+ * Repeats the given string `n` times.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to repeat.
+ * @param {number} [n=1] The number of times to repeat the string.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {string} Returns the repeated string.
+ * @example
+ *
+ * _.repeat('*', 3);
+ * // => '***'
+ *
+ * _.repeat('abc', 2);
+ * // => 'abcabc'
+ *
+ * _.repeat('abc', 0);
+ * // => ''
+ */function repeat(string,n,guard){if(guard?isIterateeCall(string,n,guard):n===undefined$1){n=1;}else {n=toInteger(n);}return baseRepeat(toString(string),n);}/**
+ * Replaces matches for `pattern` in `string` with `replacement`.
+ *
+ * **Note:** This method is based on
+ * [`String#replace`](https://mdn.io/String/replace).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to modify.
+ * @param {RegExp|string} pattern The pattern to replace.
+ * @param {Function|string} replacement The match replacement.
+ * @returns {string} Returns the modified string.
+ * @example
+ *
+ * _.replace('Hi Fred', 'Fred', 'Barney');
+ * // => 'Hi Barney'
+ */function replace(){var args=arguments,string=toString(args[0]);return args.length<3?string:string.replace(args[1],args[2]);}/**
+ * Converts `string` to
+ * [snake case](https://en.wikipedia.org/wiki/Snake_case).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the snake cased string.
+ * @example
+ *
+ * _.snakeCase('Foo Bar');
+ * // => 'foo_bar'
+ *
+ * _.snakeCase('fooBar');
+ * // => 'foo_bar'
+ *
+ * _.snakeCase('--FOO-BAR--');
+ * // => 'foo_bar'
+ */var snakeCase=createCompounder(function(result,word,index){return result+(index?'_':'')+word.toLowerCase();});/**
+ * Splits `string` by `separator`.
+ *
+ * **Note:** This method is based on
+ * [`String#split`](https://mdn.io/String/split).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to split.
+ * @param {RegExp|string} separator The separator pattern to split by.
+ * @param {number} [limit] The length to truncate results to.
+ * @returns {Array} Returns the string segments.
+ * @example
+ *
+ * _.split('a-b-c', '-', 2);
+ * // => ['a', 'b']
+ */function split(string,separator,limit){if(limit&&typeof limit!='number'&&isIterateeCall(string,separator,limit)){separator=limit=undefined$1;}limit=limit===undefined$1?MAX_ARRAY_LENGTH:limit>>>0;if(!limit){return [];}string=toString(string);if(string&&(typeof separator=='string'||separator!=null&&!isRegExp(separator))){separator=baseToString(separator);if(!separator&&hasUnicode(string)){return castSlice(stringToArray(string),0,limit);}}return string.split(separator,limit);}/**
+ * Converts `string` to
+ * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.1.0
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the start cased string.
+ * @example
+ *
+ * _.startCase('--foo-bar--');
+ * // => 'Foo Bar'
+ *
+ * _.startCase('fooBar');
+ * // => 'Foo Bar'
+ *
+ * _.startCase('__FOO_BAR__');
+ * // => 'FOO BAR'
+ */var startCase=createCompounder(function(result,word,index){return result+(index?' ':'')+upperFirst(word);});/**
+ * Checks if `string` starts with the given target string.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to inspect.
+ * @param {string} [target] The string to search for.
+ * @param {number} [position=0] The position to search from.
+ * @returns {boolean} Returns `true` if `string` starts with `target`,
+ * else `false`.
+ * @example
+ *
+ * _.startsWith('abc', 'a');
+ * // => true
+ *
+ * _.startsWith('abc', 'b');
+ * // => false
+ *
+ * _.startsWith('abc', 'b', 1);
+ * // => true
+ */function startsWith(string,target,position){string=toString(string);position=position==null?0:baseClamp(toInteger(position),0,string.length);target=baseToString(target);return string.slice(position,position+target.length)==target;}/**
+ * Creates a compiled template function that can interpolate data properties
+ * in "interpolate" delimiters, HTML-escape interpolated data properties in
+ * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
+ * properties may be accessed as free variables in the template. If a setting
+ * object is given, it takes precedence over `_.templateSettings` values.
+ *
+ * **Note:** In the development build `_.template` utilizes
+ * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
+ * for easier debugging.
+ *
+ * For more information on precompiling templates see
+ * [lodash's custom builds documentation](https://lodash.com/custom-builds).
+ *
+ * For more information on Chrome extension sandboxes see
+ * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The template string.
+ * @param {Object} [options={}] The options object.
+ * @param {RegExp} [options.escape=_.templateSettings.escape]
+ * The HTML "escape" delimiter.
+ * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
+ * The "evaluate" delimiter.
+ * @param {Object} [options.imports=_.templateSettings.imports]
+ * An object to import into the template as free variables.
+ * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
+ * The "interpolate" delimiter.
+ * @param {string} [options.sourceURL='lodash.templateSources[n]']
+ * The sourceURL of the compiled template.
+ * @param {string} [options.variable='obj']
+ * The data object variable name.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Function} Returns the compiled template function.
+ * @example
+ *
+ * // Use the "interpolate" delimiter to create a compiled template.
+ * var compiled = _.template('hello <%= user %>!');
+ * compiled({ 'user': 'fred' });
+ * // => 'hello fred!'
+ *
+ * // Use the HTML "escape" delimiter to escape data property values.
+ * var compiled = _.template('<b><%- value %></b>');
+ * compiled({ 'value': '<script>' });
+ * // => '<b><script></b>'
+ *
+ * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
+ * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
+ * compiled({ 'users': ['fred', 'barney'] });
+ * // => '<li>fred</li><li>barney</li>'
+ *
+ * // Use the internal `print` function in "evaluate" delimiters.
+ * var compiled = _.template('<% print("hello " + user); %>!');
+ * compiled({ 'user': 'barney' });
+ * // => 'hello barney!'
+ *
+ * // Use the ES template literal delimiter as an "interpolate" delimiter.
+ * // Disable support by replacing the "interpolate" delimiter.
+ * var compiled = _.template('hello ${ user }!');
+ * compiled({ 'user': 'pebbles' });
+ * // => 'hello pebbles!'
+ *
+ * // Use backslashes to treat delimiters as plain text.
+ * var compiled = _.template('<%= "\\<%- value %\\>" %>');
+ * compiled({ 'value': 'ignored' });
+ * // => '<%- value %>'
+ *
+ * // Use the `imports` option to import `jQuery` as `jq`.
+ * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
+ * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
+ * compiled({ 'users': ['fred', 'barney'] });
+ * // => '<li>fred</li><li>barney</li>'
+ *
+ * // Use the `sourceURL` option to specify a custom sourceURL for the template.
+ * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
+ * compiled(data);
+ * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
+ *
+ * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
+ * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
+ * compiled.source;
+ * // => function(data) {
+ * // var __t, __p = '';
+ * // __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
+ * // return __p;
+ * // }
+ *
+ * // Use custom template delimiters.
+ * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
+ * var compiled = _.template('hello {{ user }}!');
+ * compiled({ 'user': 'mustache' });
+ * // => 'hello mustache!'
+ *
+ * // Use the `source` property to inline compiled templates for meaningful
+ * // line numbers in error messages and stack traces.
+ * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
+ * var JST = {\
+ * "main": ' + _.template(mainText).source + '\
+ * };\
+ * ');
+ */function template(string,options,guard){// Based on John Resig's `tmpl` implementation
+// (http://ejohn.org/blog/javascript-micro-templating/)
+// and Laura Doktorova's doT.js (https://github.com/olado/doT).
+var settings=lodash.templateSettings;if(guard&&isIterateeCall(string,options,guard)){options=undefined$1;}string=toString(string);options=assignInWith({},options,settings,customDefaultsAssignIn);var imports=assignInWith({},options.imports,settings.imports,customDefaultsAssignIn),importsKeys=keys(imports),importsValues=baseValues(imports,importsKeys);var isEscaping,isEvaluating,index=0,interpolate=options.interpolate||reNoMatch,source="__p += '";// Compile the regexp to match each delimiter.
+var reDelimiters=RegExp((options.escape||reNoMatch).source+'|'+interpolate.source+'|'+(interpolate===reInterpolate?reEsTemplate:reNoMatch).source+'|'+(options.evaluate||reNoMatch).source+'|$','g');// Use a sourceURL for easier debugging.
+// The sourceURL gets injected into the source that's eval-ed, so be careful
+// to normalize all kinds of whitespace, so e.g. newlines (and unicode versions of it) can't sneak in
+// and escape the comment, thus injecting code that gets evaled.
+var sourceURL='//# sourceURL='+(hasOwnProperty.call(options,'sourceURL')?(options.sourceURL+'').replace(/\s/g,' '):'lodash.templateSources['+ ++templateCounter+']')+'\n';string.replace(reDelimiters,function(match,escapeValue,interpolateValue,esTemplateValue,evaluateValue,offset){interpolateValue||(interpolateValue=esTemplateValue);// Escape characters that can't be included in string literals.
+source+=string.slice(index,offset).replace(reUnescapedString,escapeStringChar);// Replace delimiters with snippets.
+if(escapeValue){isEscaping=true;source+="' +\n__e("+escapeValue+") +\n'";}if(evaluateValue){isEvaluating=true;source+="';\n"+evaluateValue+";\n__p += '";}if(interpolateValue){source+="' +\n((__t = ("+interpolateValue+")) == null ? '' : __t) +\n'";}index=offset+match.length;// The JS engine embedded in Adobe products needs `match` returned in
+// order to produce the correct `offset` value.
+return match;});source+="';\n";// If `variable` is not specified wrap a with-statement around the generated
+// code to add the data object to the top of the scope chain.
+var variable=hasOwnProperty.call(options,'variable')&&options.variable;if(!variable){source='with (obj) {\n'+source+'\n}\n';}// Throw an error if a forbidden character was found in `variable`, to prevent
+// potential command injection attacks.
+else if(reForbiddenIdentifierChars.test(variable)){throw new Error(INVALID_TEMPL_VAR_ERROR_TEXT);}// Cleanup code by stripping empty strings.
+source=(isEvaluating?source.replace(reEmptyStringLeading,''):source).replace(reEmptyStringMiddle,'$1').replace(reEmptyStringTrailing,'$1;');// Frame code as the function body.
+source='function('+(variable||'obj')+') {\n'+(variable?'':'obj || (obj = {});\n')+"var __t, __p = ''"+(isEscaping?', __e = _.escape':'')+(isEvaluating?', __j = Array.prototype.join;\n'+"function print() { __p += __j.call(arguments, '') }\n":';\n')+source+'return __p\n}';var result=attempt(function(){return Function(importsKeys,sourceURL+'return '+source).apply(undefined$1,importsValues);});// Provide the compiled function's source by its `toString` method or
+// the `source` property as a convenience for inlining compiled templates.
+result.source=source;if(isError(result)){throw result;}return result;}/**
+ * Converts `string`, as a whole, to lower case just like
+ * [String#toLowerCase](https://mdn.io/toLowerCase).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the lower cased string.
+ * @example
+ *
+ * _.toLower('--Foo-Bar--');
+ * // => '--foo-bar--'
+ *
+ * _.toLower('fooBar');
+ * // => 'foobar'
+ *
+ * _.toLower('__FOO_BAR__');
+ * // => '__foo_bar__'
+ */function toLower(value){return toString(value).toLowerCase();}/**
+ * Converts `string`, as a whole, to upper case just like
+ * [String#toUpperCase](https://mdn.io/toUpperCase).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the upper cased string.
+ * @example
+ *
+ * _.toUpper('--foo-bar--');
+ * // => '--FOO-BAR--'
+ *
+ * _.toUpper('fooBar');
+ * // => 'FOOBAR'
+ *
+ * _.toUpper('__foo_bar__');
+ * // => '__FOO_BAR__'
+ */function toUpper(value){return toString(value).toUpperCase();}/**
+ * Removes leading and trailing whitespace or specified characters from `string`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to trim.
+ * @param {string} [chars=whitespace] The characters to trim.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {string} Returns the trimmed string.
+ * @example
+ *
+ * _.trim(' abc ');
+ * // => 'abc'
+ *
+ * _.trim('-_-abc-_-', '_-');
+ * // => 'abc'
+ *
+ * _.map([' foo ', ' bar '], _.trim);
+ * // => ['foo', 'bar']
+ */function trim(string,chars,guard){string=toString(string);if(string&&(guard||chars===undefined$1)){return baseTrim(string);}if(!string||!(chars=baseToString(chars))){return string;}var strSymbols=stringToArray(string),chrSymbols=stringToArray(chars),start=charsStartIndex(strSymbols,chrSymbols),end=charsEndIndex(strSymbols,chrSymbols)+1;return castSlice(strSymbols,start,end).join('');}/**
+ * Removes trailing whitespace or specified characters from `string`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to trim.
+ * @param {string} [chars=whitespace] The characters to trim.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {string} Returns the trimmed string.
+ * @example
+ *
+ * _.trimEnd(' abc ');
+ * // => ' abc'
+ *
+ * _.trimEnd('-_-abc-_-', '_-');
+ * // => '-_-abc'
+ */function trimEnd(string,chars,guard){string=toString(string);if(string&&(guard||chars===undefined$1)){return string.slice(0,trimmedEndIndex(string)+1);}if(!string||!(chars=baseToString(chars))){return string;}var strSymbols=stringToArray(string),end=charsEndIndex(strSymbols,stringToArray(chars))+1;return castSlice(strSymbols,0,end).join('');}/**
+ * Removes leading whitespace or specified characters from `string`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to trim.
+ * @param {string} [chars=whitespace] The characters to trim.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {string} Returns the trimmed string.
+ * @example
+ *
+ * _.trimStart(' abc ');
+ * // => 'abc '
+ *
+ * _.trimStart('-_-abc-_-', '_-');
+ * // => 'abc-_-'
+ */function trimStart(string,chars,guard){string=toString(string);if(string&&(guard||chars===undefined$1)){return string.replace(reTrimStart,'');}if(!string||!(chars=baseToString(chars))){return string;}var strSymbols=stringToArray(string),start=charsStartIndex(strSymbols,stringToArray(chars));return castSlice(strSymbols,start).join('');}/**
+ * Truncates `string` if it's longer than the given maximum string length.
+ * The last characters of the truncated string are replaced with the omission
+ * string which defaults to "...".
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to truncate.
+ * @param {Object} [options={}] The options object.
+ * @param {number} [options.length=30] The maximum string length.
+ * @param {string} [options.omission='...'] The string to indicate text is omitted.
+ * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
+ * @returns {string} Returns the truncated string.
+ * @example
+ *
+ * _.truncate('hi-diddly-ho there, neighborino');
+ * // => 'hi-diddly-ho there, neighbo...'
+ *
+ * _.truncate('hi-diddly-ho there, neighborino', {
+ * 'length': 24,
+ * 'separator': ' '
+ * });
+ * // => 'hi-diddly-ho there,...'
+ *
+ * _.truncate('hi-diddly-ho there, neighborino', {
+ * 'length': 24,
+ * 'separator': /,? +/
+ * });
+ * // => 'hi-diddly-ho there...'
+ *
+ * _.truncate('hi-diddly-ho there, neighborino', {
+ * 'omission': ' [...]'
+ * });
+ * // => 'hi-diddly-ho there, neig [...]'
+ */function truncate(string,options){var length=DEFAULT_TRUNC_LENGTH,omission=DEFAULT_TRUNC_OMISSION;if(isObject(options)){var separator='separator'in options?options.separator:separator;length='length'in options?toInteger(options.length):length;omission='omission'in options?baseToString(options.omission):omission;}string=toString(string);var strLength=string.length;if(hasUnicode(string)){var strSymbols=stringToArray(string);strLength=strSymbols.length;}if(length>=strLength){return string;}var end=length-stringSize(omission);if(end<1){return omission;}var result=strSymbols?castSlice(strSymbols,0,end).join(''):string.slice(0,end);if(separator===undefined$1){return result+omission;}if(strSymbols){end+=result.length-end;}if(isRegExp(separator)){if(string.slice(end).search(separator)){var match,substring=result;if(!separator.global){separator=RegExp(separator.source,toString(reFlags.exec(separator))+'g');}separator.lastIndex=0;while(match=separator.exec(substring)){var newEnd=match.index;}result=result.slice(0,newEnd===undefined$1?end:newEnd);}}else if(string.indexOf(baseToString(separator),end)!=end){var index=result.lastIndexOf(separator);if(index>-1){result=result.slice(0,index);}}return result+omission;}/**
+ * The inverse of `_.escape`; this method converts the HTML entities
+ * `&`, `<`, `>`, `"`, and `'` in `string` to
+ * their corresponding characters.
+ *
+ * **Note:** No other HTML entities are unescaped. To unescape additional
+ * HTML entities use a third-party library like [_he_](https://mths.be/he).
+ *
+ * @static
+ * @memberOf _
+ * @since 0.6.0
+ * @category String
+ * @param {string} [string=''] The string to unescape.
+ * @returns {string} Returns the unescaped string.
+ * @example
+ *
+ * _.unescape('fred, barney, & pebbles');
+ * // => 'fred, barney, & pebbles'
+ */function unescape(string){string=toString(string);return string&&reHasEscapedHtml.test(string)?string.replace(reEscapedHtml,unescapeHtmlChar):string;}/**
+ * Converts `string`, as space separated words, to upper case.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the upper cased string.
+ * @example
+ *
+ * _.upperCase('--foo-bar');
+ * // => 'FOO BAR'
+ *
+ * _.upperCase('fooBar');
+ * // => 'FOO BAR'
+ *
+ * _.upperCase('__foo_bar__');
+ * // => 'FOO BAR'
+ */var upperCase=createCompounder(function(result,word,index){return result+(index?' ':'')+word.toUpperCase();});/**
+ * Converts the first character of `string` to upper case.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the converted string.
+ * @example
+ *
+ * _.upperFirst('fred');
+ * // => 'Fred'
+ *
+ * _.upperFirst('FRED');
+ * // => 'FRED'
+ */var upperFirst=createCaseFirst('toUpperCase');/**
+ * Splits `string` into an array of its words.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to inspect.
+ * @param {RegExp|string} [pattern] The pattern to match words.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Array} Returns the words of `string`.
+ * @example
+ *
+ * _.words('fred, barney, & pebbles');
+ * // => ['fred', 'barney', 'pebbles']
+ *
+ * _.words('fred, barney, & pebbles', /[^, ]+/g);
+ * // => ['fred', 'barney', '&', 'pebbles']
+ */function words(string,pattern,guard){string=toString(string);pattern=guard?undefined$1:pattern;if(pattern===undefined$1){return hasUnicodeWord(string)?unicodeWords(string):asciiWords(string);}return string.match(pattern)||[];}/*------------------------------------------------------------------------*/ /**
+ * Attempts to invoke `func`, returning either the result or the caught error
+ * object. Any additional arguments are provided to `func` when it's invoked.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Util
+ * @param {Function} func The function to attempt.
+ * @param {...*} [args] The arguments to invoke `func` with.
+ * @returns {*} Returns the `func` result or error object.
+ * @example
+ *
+ * // Avoid throwing errors for invalid selectors.
+ * var elements = _.attempt(function(selector) {
+ * return document.querySelectorAll(selector);
+ * }, '>_>');
+ *
+ * if (_.isError(elements)) {
+ * elements = [];
+ * }
+ */var attempt=baseRest(function(func,args){try{return apply(func,undefined$1,args);}catch(e){return isError(e)?e:new Error(e);}});/**
+ * Binds methods of an object to the object itself, overwriting the existing
+ * method.
+ *
+ * **Note:** This method doesn't set the "length" property of bound functions.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Util
+ * @param {Object} object The object to bind and assign the bound methods to.
+ * @param {...(string|string[])} methodNames The object method names to bind.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * var view = {
+ * 'label': 'docs',
+ * 'click': function() {
+ * console.log('clicked ' + this.label);
+ * }
+ * };
+ *
+ * _.bindAll(view, ['click']);
+ * jQuery(element).on('click', view.click);
+ * // => Logs 'clicked docs' when clicked.
+ */var bindAll=flatRest(function(object,methodNames){arrayEach(methodNames,function(key){key=toKey(key);baseAssignValue(object,key,bind(object[key],object));});return object;});/**
+ * Creates a function that iterates over `pairs` and invokes the corresponding
+ * function of the first predicate to return truthy. The predicate-function
+ * pairs are invoked with the `this` binding and arguments of the created
+ * function.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Util
+ * @param {Array} pairs The predicate-function pairs.
+ * @returns {Function} Returns the new composite function.
+ * @example
+ *
+ * var func = _.cond([
+ * [_.matches({ 'a': 1 }), _.constant('matches A')],
+ * [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
+ * [_.stubTrue, _.constant('no match')]
+ * ]);
+ *
+ * func({ 'a': 1, 'b': 2 });
+ * // => 'matches A'
+ *
+ * func({ 'a': 0, 'b': 1 });
+ * // => 'matches B'
+ *
+ * func({ 'a': '1', 'b': '2' });
+ * // => 'no match'
+ */function cond(pairs){var length=pairs==null?0:pairs.length,toIteratee=getIteratee();pairs=!length?[]:arrayMap(pairs,function(pair){if(typeof pair[1]!='function'){throw new TypeError(FUNC_ERROR_TEXT);}return [toIteratee(pair[0]),pair[1]];});return baseRest(function(args){var index=-1;while(++index<length){var pair=pairs[index];if(apply(pair[0],this,args)){return apply(pair[1],this,args);}}});}/**
+ * Creates a function that invokes the predicate properties of `source` with
+ * the corresponding property values of a given object, returning `true` if
+ * all predicates return truthy, else `false`.
+ *
+ * **Note:** The created function is equivalent to `_.conformsTo` with
+ * `source` partially applied.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Util
+ * @param {Object} source The object of property predicates to conform to.
+ * @returns {Function} Returns the new spec function.
+ * @example
+ *
+ * var objects = [
+ * { 'a': 2, 'b': 1 },
+ * { 'a': 1, 'b': 2 }
+ * ];
+ *
+ * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
+ * // => [{ 'a': 1, 'b': 2 }]
+ */function conforms(source){return baseConforms(baseClone(source,CLONE_DEEP_FLAG));}/**
+ * Creates a function that returns `value`.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.4.0
+ * @category Util
+ * @param {*} value The value to return from the new function.
+ * @returns {Function} Returns the new constant function.
+ * @example
+ *
+ * var objects = _.times(2, _.constant({ 'a': 1 }));
+ *
+ * console.log(objects);
+ * // => [{ 'a': 1 }, { 'a': 1 }]
+ *
+ * console.log(objects[0] === objects[1]);
+ * // => true
+ */function constant(value){return function(){return value;};}/**
+ * Checks `value` to determine whether a default value should be returned in
+ * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
+ * or `undefined`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.14.0
+ * @category Util
+ * @param {*} value The value to check.
+ * @param {*} defaultValue The default value.
+ * @returns {*} Returns the resolved value.
+ * @example
+ *
+ * _.defaultTo(1, 10);
+ * // => 1
+ *
+ * _.defaultTo(undefined, 10);
+ * // => 10
+ */function defaultTo(value,defaultValue){return value==null||value!==value?defaultValue:value;}/**
+ * Creates a function that returns the result of invoking the given functions
+ * with the `this` binding of the created function, where each successive
+ * invocation is supplied the return value of the previous.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Util
+ * @param {...(Function|Function[])} [funcs] The functions to invoke.
+ * @returns {Function} Returns the new composite function.
+ * @see _.flowRight
+ * @example
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * var addSquare = _.flow([_.add, square]);
+ * addSquare(1, 2);
+ * // => 9
+ */var flow=createFlow();/**
+ * This method is like `_.flow` except that it creates a function that
+ * invokes the given functions from right to left.
+ *
+ * @static
+ * @since 3.0.0
+ * @memberOf _
+ * @category Util
+ * @param {...(Function|Function[])} [funcs] The functions to invoke.
+ * @returns {Function} Returns the new composite function.
+ * @see _.flow
+ * @example
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * var addSquare = _.flowRight([square, _.add]);
+ * addSquare(1, 2);
+ * // => 9
+ */var flowRight=createFlow(true);/**
+ * This method returns the first argument it receives.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Util
+ * @param {*} value Any value.
+ * @returns {*} Returns `value`.
+ * @example
+ *
+ * var object = { 'a': 1 };
+ *
+ * console.log(_.identity(object) === object);
+ * // => true
+ */function identity(value){return value;}/**
+ * Creates a function that invokes `func` with the arguments of the created
+ * function. If `func` is a property name, the created function returns the
+ * property value for a given element. If `func` is an array or object, the
+ * created function returns `true` for elements that contain the equivalent
+ * source properties, otherwise it returns `false`.
+ *
+ * @static
+ * @since 4.0.0
+ * @memberOf _
+ * @category Util
+ * @param {*} [func=_.identity] The value to convert to a callback.
+ * @returns {Function} Returns the callback.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36, 'active': true },
+ * { 'user': 'fred', 'age': 40, 'active': false }
+ * ];
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
+ * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.filter(users, _.iteratee(['user', 'fred']));
+ * // => [{ 'user': 'fred', 'age': 40 }]
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.map(users, _.iteratee('user'));
+ * // => ['barney', 'fred']
+ *
+ * // Create custom iteratee shorthands.
+ * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
+ * return !_.isRegExp(func) ? iteratee(func) : function(string) {
+ * return func.test(string);
+ * };
+ * });
+ *
+ * _.filter(['abc', 'def'], /ef/);
+ * // => ['def']
+ */function iteratee(func){return baseIteratee(typeof func=='function'?func:baseClone(func,CLONE_DEEP_FLAG));}/**
+ * Creates a function that performs a partial deep comparison between a given
+ * object and `source`, returning `true` if the given object has equivalent
+ * property values, else `false`.
+ *
+ * **Note:** The created function is equivalent to `_.isMatch` with `source`
+ * partially applied.
+ *
+ * Partial comparisons will match empty array and empty object `source`
+ * values against any array or object value, respectively. See `_.isEqual`
+ * for a list of supported value comparisons.
+ *
+ * **Note:** Multiple values can be checked by combining several matchers
+ * using `_.overSome`
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Util
+ * @param {Object} source The object of property values to match.
+ * @returns {Function} Returns the new spec function.
+ * @example
+ *
+ * var objects = [
+ * { 'a': 1, 'b': 2, 'c': 3 },
+ * { 'a': 4, 'b': 5, 'c': 6 }
+ * ];
+ *
+ * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
+ * // => [{ 'a': 4, 'b': 5, 'c': 6 }]
+ *
+ * // Checking for several possible values
+ * _.filter(objects, _.overSome([_.matches({ 'a': 1 }), _.matches({ 'a': 4 })]));
+ * // => [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 4, 'b': 5, 'c': 6 }]
+ */function matches(source){return baseMatches(baseClone(source,CLONE_DEEP_FLAG));}/**
+ * Creates a function that performs a partial deep comparison between the
+ * value at `path` of a given object to `srcValue`, returning `true` if the
+ * object value is equivalent, else `false`.
+ *
+ * **Note:** Partial comparisons will match empty array and empty object
+ * `srcValue` values against any array or object value, respectively. See
+ * `_.isEqual` for a list of supported value comparisons.
+ *
+ * **Note:** Multiple values can be checked by combining several matchers
+ * using `_.overSome`
+ *
+ * @static
+ * @memberOf _
+ * @since 3.2.0
+ * @category Util
+ * @param {Array|string} path The path of the property to get.
+ * @param {*} srcValue The value to match.
+ * @returns {Function} Returns the new spec function.
+ * @example
+ *
+ * var objects = [
+ * { 'a': 1, 'b': 2, 'c': 3 },
+ * { 'a': 4, 'b': 5, 'c': 6 }
+ * ];
+ *
+ * _.find(objects, _.matchesProperty('a', 4));
+ * // => { 'a': 4, 'b': 5, 'c': 6 }
+ *
+ * // Checking for several possible values
+ * _.filter(objects, _.overSome([_.matchesProperty('a', 1), _.matchesProperty('a', 4)]));
+ * // => [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 4, 'b': 5, 'c': 6 }]
+ */function matchesProperty(path,srcValue){return baseMatchesProperty(path,baseClone(srcValue,CLONE_DEEP_FLAG));}/**
+ * Creates a function that invokes the method at `path` of a given object.
+ * Any additional arguments are provided to the invoked method.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.7.0
+ * @category Util
+ * @param {Array|string} path The path of the method to invoke.
+ * @param {...*} [args] The arguments to invoke the method with.
+ * @returns {Function} Returns the new invoker function.
+ * @example
+ *
+ * var objects = [
+ * { 'a': { 'b': _.constant(2) } },
+ * { 'a': { 'b': _.constant(1) } }
+ * ];
+ *
+ * _.map(objects, _.method('a.b'));
+ * // => [2, 1]
+ *
+ * _.map(objects, _.method(['a', 'b']));
+ * // => [2, 1]
+ */var method=baseRest(function(path,args){return function(object){return baseInvoke(object,path,args);};});/**
+ * The opposite of `_.method`; this method creates a function that invokes
+ * the method at a given path of `object`. Any additional arguments are
+ * provided to the invoked method.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.7.0
+ * @category Util
+ * @param {Object} object The object to query.
+ * @param {...*} [args] The arguments to invoke the method with.
+ * @returns {Function} Returns the new invoker function.
+ * @example
+ *
+ * var array = _.times(3, _.constant),
+ * object = { 'a': array, 'b': array, 'c': array };
+ *
+ * _.map(['a[2]', 'c[0]'], _.methodOf(object));
+ * // => [2, 0]
+ *
+ * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
+ * // => [2, 0]
+ */var methodOf=baseRest(function(object,args){return function(path){return baseInvoke(object,path,args);};});/**
+ * Adds all own enumerable string keyed function properties of a source
+ * object to the destination object. If `object` is a function, then methods
+ * are added to its prototype as well.
+ *
+ * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
+ * avoid conflicts caused by modifying the original.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Util
+ * @param {Function|Object} [object=lodash] The destination object.
+ * @param {Object} source The object of functions to add.
+ * @param {Object} [options={}] The options object.
+ * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
+ * @returns {Function|Object} Returns `object`.
+ * @example
+ *
+ * function vowels(string) {
+ * return _.filter(string, function(v) {
+ * return /[aeiou]/i.test(v);
+ * });
+ * }
+ *
+ * _.mixin({ 'vowels': vowels });
+ * _.vowels('fred');
+ * // => ['e']
+ *
+ * _('fred').vowels().value();
+ * // => ['e']
+ *
+ * _.mixin({ 'vowels': vowels }, { 'chain': false });
+ * _('fred').vowels();
+ * // => ['e']
+ */function mixin(object,source,options){var props=keys(source),methodNames=baseFunctions(source,props);if(options==null&&!(isObject(source)&&(methodNames.length||!props.length))){options=source;source=object;object=this;methodNames=baseFunctions(source,keys(source));}var chain=!(isObject(options)&&'chain'in options)||!!options.chain,isFunc=isFunction(object);arrayEach(methodNames,function(methodName){var func=source[methodName];object[methodName]=func;if(isFunc){object.prototype[methodName]=function(){var chainAll=this.__chain__;if(chain||chainAll){var result=object(this.__wrapped__),actions=result.__actions__=copyArray(this.__actions__);actions.push({'func':func,'args':arguments,'thisArg':object});result.__chain__=chainAll;return result;}return func.apply(object,arrayPush([this.value()],arguments));};}});return object;}/**
+ * Reverts the `_` variable to its previous value and returns a reference to
+ * the `lodash` function.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Util
+ * @returns {Function} Returns the `lodash` function.
+ * @example
+ *
+ * var lodash = _.noConflict();
+ */function noConflict(){if(root._===this){root._=oldDash;}return this;}/**
+ * This method returns `undefined`.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.3.0
+ * @category Util
+ * @example
+ *
+ * _.times(2, _.noop);
+ * // => [undefined, undefined]
+ */function noop(){// No operation performed.
+}/**
+ * Creates a function that gets the argument at index `n`. If `n` is negative,
+ * the nth argument from the end is returned.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Util
+ * @param {number} [n=0] The index of the argument to return.
+ * @returns {Function} Returns the new pass-thru function.
+ * @example
+ *
+ * var func = _.nthArg(1);
+ * func('a', 'b', 'c', 'd');
+ * // => 'b'
+ *
+ * var func = _.nthArg(-2);
+ * func('a', 'b', 'c', 'd');
+ * // => 'c'
+ */function nthArg(n){n=toInteger(n);return baseRest(function(args){return baseNth(args,n);});}/**
+ * Creates a function that invokes `iteratees` with the arguments it receives
+ * and returns their results.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Util
+ * @param {...(Function|Function[])} [iteratees=[_.identity]]
+ * The iteratees to invoke.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var func = _.over([Math.max, Math.min]);
+ *
+ * func(1, 2, 3, 4);
+ * // => [4, 1]
+ */var over=createOver(arrayMap);/**
+ * Creates a function that checks if **all** of the `predicates` return
+ * truthy when invoked with the arguments it receives.
+ *
+ * Following shorthands are possible for providing predicates.
+ * Pass an `Object` and it will be used as an parameter for `_.matches` to create the predicate.
+ * Pass an `Array` of parameters for `_.matchesProperty` and the predicate will be created using them.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Util
+ * @param {...(Function|Function[])} [predicates=[_.identity]]
+ * The predicates to check.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var func = _.overEvery([Boolean, isFinite]);
+ *
+ * func('1');
+ * // => true
+ *
+ * func(null);
+ * // => false
+ *
+ * func(NaN);
+ * // => false
+ */var overEvery=createOver(arrayEvery);/**
+ * Creates a function that checks if **any** of the `predicates` return
+ * truthy when invoked with the arguments it receives.
+ *
+ * Following shorthands are possible for providing predicates.
+ * Pass an `Object` and it will be used as an parameter for `_.matches` to create the predicate.
+ * Pass an `Array` of parameters for `_.matchesProperty` and the predicate will be created using them.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Util
+ * @param {...(Function|Function[])} [predicates=[_.identity]]
+ * The predicates to check.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var func = _.overSome([Boolean, isFinite]);
+ *
+ * func('1');
+ * // => true
+ *
+ * func(null);
+ * // => true
+ *
+ * func(NaN);
+ * // => false
+ *
+ * var matchesFunc = _.overSome([{ 'a': 1 }, { 'a': 2 }])
+ * var matchesPropertyFunc = _.overSome([['a', 1], ['a', 2]])
+ */var overSome=createOver(arraySome);/**
+ * Creates a function that returns the value at `path` of a given object.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.4.0
+ * @category Util
+ * @param {Array|string} path The path of the property to get.
+ * @returns {Function} Returns the new accessor function.
+ * @example
+ *
+ * var objects = [
+ * { 'a': { 'b': 2 } },
+ * { 'a': { 'b': 1 } }
+ * ];
+ *
+ * _.map(objects, _.property('a.b'));
+ * // => [2, 1]
+ *
+ * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
+ * // => [1, 2]
+ */function property(path){return isKey(path)?baseProperty(toKey(path)):basePropertyDeep(path);}/**
+ * The opposite of `_.property`; this method creates a function that returns
+ * the value at a given path of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Util
+ * @param {Object} object The object to query.
+ * @returns {Function} Returns the new accessor function.
+ * @example
+ *
+ * var array = [0, 1, 2],
+ * object = { 'a': array, 'b': array, 'c': array };
+ *
+ * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
+ * // => [2, 0]
+ *
+ * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
+ * // => [2, 0]
+ */function propertyOf(object){return function(path){return object==null?undefined$1:baseGet(object,path);};}/**
+ * Creates an array of numbers (positive and/or negative) progressing from
+ * `start` up to, but not including, `end`. A step of `-1` is used if a negative
+ * `start` is specified without an `end` or `step`. If `end` is not specified,
+ * it's set to `start` with `start` then set to `0`.
+ *
+ * **Note:** JavaScript follows the IEEE-754 standard for resolving
+ * floating-point values which can produce unexpected results.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Util
+ * @param {number} [start=0] The start of the range.
+ * @param {number} end The end of the range.
+ * @param {number} [step=1] The value to increment or decrement by.
+ * @returns {Array} Returns the range of numbers.
+ * @see _.inRange, _.rangeRight
+ * @example
+ *
+ * _.range(4);
+ * // => [0, 1, 2, 3]
+ *
+ * _.range(-4);
+ * // => [0, -1, -2, -3]
+ *
+ * _.range(1, 5);
+ * // => [1, 2, 3, 4]
+ *
+ * _.range(0, 20, 5);
+ * // => [0, 5, 10, 15]
+ *
+ * _.range(0, -4, -1);
+ * // => [0, -1, -2, -3]
+ *
+ * _.range(1, 4, 0);
+ * // => [1, 1, 1]
+ *
+ * _.range(0);
+ * // => []
+ */var range=createRange();/**
+ * This method is like `_.range` except that it populates values in
+ * descending order.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Util
+ * @param {number} [start=0] The start of the range.
+ * @param {number} end The end of the range.
+ * @param {number} [step=1] The value to increment or decrement by.
+ * @returns {Array} Returns the range of numbers.
+ * @see _.inRange, _.range
+ * @example
+ *
+ * _.rangeRight(4);
+ * // => [3, 2, 1, 0]
+ *
+ * _.rangeRight(-4);
+ * // => [-3, -2, -1, 0]
+ *
+ * _.rangeRight(1, 5);
+ * // => [4, 3, 2, 1]
+ *
+ * _.rangeRight(0, 20, 5);
+ * // => [15, 10, 5, 0]
+ *
+ * _.rangeRight(0, -4, -1);
+ * // => [-3, -2, -1, 0]
+ *
+ * _.rangeRight(1, 4, 0);
+ * // => [1, 1, 1]
+ *
+ * _.rangeRight(0);
+ * // => []
+ */var rangeRight=createRange(true);/**
+ * This method returns a new empty array.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.13.0
+ * @category Util
+ * @returns {Array} Returns the new empty array.
+ * @example
+ *
+ * var arrays = _.times(2, _.stubArray);
+ *
+ * console.log(arrays);
+ * // => [[], []]
+ *
+ * console.log(arrays[0] === arrays[1]);
+ * // => false
+ */function stubArray(){return [];}/**
+ * This method returns `false`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.13.0
+ * @category Util
+ * @returns {boolean} Returns `false`.
+ * @example
+ *
+ * _.times(2, _.stubFalse);
+ * // => [false, false]
+ */function stubFalse(){return false;}/**
+ * This method returns a new empty object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.13.0
+ * @category Util
+ * @returns {Object} Returns the new empty object.
+ * @example
+ *
+ * var objects = _.times(2, _.stubObject);
+ *
+ * console.log(objects);
+ * // => [{}, {}]
+ *
+ * console.log(objects[0] === objects[1]);
+ * // => false
+ */function stubObject(){return {};}/**
+ * This method returns an empty string.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.13.0
+ * @category Util
+ * @returns {string} Returns the empty string.
+ * @example
+ *
+ * _.times(2, _.stubString);
+ * // => ['', '']
+ */function stubString(){return '';}/**
+ * This method returns `true`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.13.0
+ * @category Util
+ * @returns {boolean} Returns `true`.
+ * @example
+ *
+ * _.times(2, _.stubTrue);
+ * // => [true, true]
+ */function stubTrue(){return true;}/**
+ * Invokes the iteratee `n` times, returning an array of the results of
+ * each invocation. The iteratee is invoked with one argument; (index).
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Util
+ * @param {number} n The number of times to invoke `iteratee`.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the array of results.
+ * @example
+ *
+ * _.times(3, String);
+ * // => ['0', '1', '2']
+ *
+ * _.times(4, _.constant(0));
+ * // => [0, 0, 0, 0]
+ */function times(n,iteratee){n=toInteger(n);if(n<1||n>MAX_SAFE_INTEGER){return [];}var index=MAX_ARRAY_LENGTH,length=nativeMin(n,MAX_ARRAY_LENGTH);iteratee=getIteratee(iteratee);n-=MAX_ARRAY_LENGTH;var result=baseTimes(length,iteratee);while(++index<n){iteratee(index);}return result;}/**
+ * Converts `value` to a property path array.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Util
+ * @param {*} value The value to convert.
+ * @returns {Array} Returns the new property path array.
+ * @example
+ *
+ * _.toPath('a.b.c');
+ * // => ['a', 'b', 'c']
+ *
+ * _.toPath('a[0].b.c');
+ * // => ['a', '0', 'b', 'c']
+ */function toPath(value){if(isArray(value)){return arrayMap(value,toKey);}return isSymbol(value)?[value]:copyArray(stringToPath(toString(value)));}/**
+ * Generates a unique ID. If `prefix` is given, the ID is appended to it.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Util
+ * @param {string} [prefix=''] The value to prefix the ID with.
+ * @returns {string} Returns the unique ID.
+ * @example
+ *
+ * _.uniqueId('contact_');
+ * // => 'contact_104'
+ *
+ * _.uniqueId();
+ * // => '105'
+ */function uniqueId(prefix){var id=++idCounter;return toString(prefix)+id;}/*------------------------------------------------------------------------*/ /**
+ * Adds two numbers.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.4.0
+ * @category Math
+ * @param {number} augend The first number in an addition.
+ * @param {number} addend The second number in an addition.
+ * @returns {number} Returns the total.
+ * @example
+ *
+ * _.add(6, 4);
+ * // => 10
+ */var add=createMathOperation(function(augend,addend){return augend+addend;},0);/**
+ * Computes `number` rounded up to `precision`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.10.0
+ * @category Math
+ * @param {number} number The number to round up.
+ * @param {number} [precision=0] The precision to round up to.
+ * @returns {number} Returns the rounded up number.
+ * @example
+ *
+ * _.ceil(4.006);
+ * // => 5
+ *
+ * _.ceil(6.004, 2);
+ * // => 6.01
+ *
+ * _.ceil(6040, -2);
+ * // => 6100
+ */var ceil=createRound('ceil');/**
+ * Divide two numbers.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.7.0
+ * @category Math
+ * @param {number} dividend The first number in a division.
+ * @param {number} divisor The second number in a division.
+ * @returns {number} Returns the quotient.
+ * @example
+ *
+ * _.divide(6, 4);
+ * // => 1.5
+ */var divide=createMathOperation(function(dividend,divisor){return dividend/divisor;},1);/**
+ * Computes `number` rounded down to `precision`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.10.0
+ * @category Math
+ * @param {number} number The number to round down.
+ * @param {number} [precision=0] The precision to round down to.
+ * @returns {number} Returns the rounded down number.
+ * @example
+ *
+ * _.floor(4.006);
+ * // => 4
+ *
+ * _.floor(0.046, 2);
+ * // => 0.04
+ *
+ * _.floor(4060, -2);
+ * // => 4000
+ */var floor=createRound('floor');/**
+ * Computes the maximum value of `array`. If `array` is empty or falsey,
+ * `undefined` is returned.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Math
+ * @param {Array} array The array to iterate over.
+ * @returns {*} Returns the maximum value.
+ * @example
+ *
+ * _.max([4, 2, 8, 6]);
+ * // => 8
+ *
+ * _.max([]);
+ * // => undefined
+ */function max(array){return array&&array.length?baseExtremum(array,identity,baseGt):undefined$1;}/**
+ * This method is like `_.max` except that it accepts `iteratee` which is
+ * invoked for each element in `array` to generate the criterion by which
+ * the value is ranked. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Math
+ * @param {Array} array The array to iterate over.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {*} Returns the maximum value.
+ * @example
+ *
+ * var objects = [{ 'n': 1 }, { 'n': 2 }];
+ *
+ * _.maxBy(objects, function(o) { return o.n; });
+ * // => { 'n': 2 }
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.maxBy(objects, 'n');
+ * // => { 'n': 2 }
+ */function maxBy(array,iteratee){return array&&array.length?baseExtremum(array,getIteratee(iteratee,2),baseGt):undefined$1;}/**
+ * Computes the mean of the values in `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Math
+ * @param {Array} array The array to iterate over.
+ * @returns {number} Returns the mean.
+ * @example
+ *
+ * _.mean([4, 2, 8, 6]);
+ * // => 5
+ */function mean(array){return baseMean(array,identity);}/**
+ * This method is like `_.mean` except that it accepts `iteratee` which is
+ * invoked for each element in `array` to generate the value to be averaged.
+ * The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.7.0
+ * @category Math
+ * @param {Array} array The array to iterate over.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {number} Returns the mean.
+ * @example
+ *
+ * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
+ *
+ * _.meanBy(objects, function(o) { return o.n; });
+ * // => 5
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.meanBy(objects, 'n');
+ * // => 5
+ */function meanBy(array,iteratee){return baseMean(array,getIteratee(iteratee,2));}/**
+ * Computes the minimum value of `array`. If `array` is empty or falsey,
+ * `undefined` is returned.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Math
+ * @param {Array} array The array to iterate over.
+ * @returns {*} Returns the minimum value.
+ * @example
+ *
+ * _.min([4, 2, 8, 6]);
+ * // => 2
+ *
+ * _.min([]);
+ * // => undefined
+ */function min(array){return array&&array.length?baseExtremum(array,identity,baseLt):undefined$1;}/**
+ * This method is like `_.min` except that it accepts `iteratee` which is
+ * invoked for each element in `array` to generate the criterion by which
+ * the value is ranked. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Math
+ * @param {Array} array The array to iterate over.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {*} Returns the minimum value.
+ * @example
+ *
+ * var objects = [{ 'n': 1 }, { 'n': 2 }];
+ *
+ * _.minBy(objects, function(o) { return o.n; });
+ * // => { 'n': 1 }
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.minBy(objects, 'n');
+ * // => { 'n': 1 }
+ */function minBy(array,iteratee){return array&&array.length?baseExtremum(array,getIteratee(iteratee,2),baseLt):undefined$1;}/**
+ * Multiply two numbers.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.7.0
+ * @category Math
+ * @param {number} multiplier The first number in a multiplication.
+ * @param {number} multiplicand The second number in a multiplication.
+ * @returns {number} Returns the product.
+ * @example
+ *
+ * _.multiply(6, 4);
+ * // => 24
+ */var multiply=createMathOperation(function(multiplier,multiplicand){return multiplier*multiplicand;},1);/**
+ * Computes `number` rounded to `precision`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.10.0
+ * @category Math
+ * @param {number} number The number to round.
+ * @param {number} [precision=0] The precision to round to.
+ * @returns {number} Returns the rounded number.
+ * @example
+ *
+ * _.round(4.006);
+ * // => 4
+ *
+ * _.round(4.006, 2);
+ * // => 4.01
+ *
+ * _.round(4060, -2);
+ * // => 4100
+ */var round=createRound('round');/**
+ * Subtract two numbers.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Math
+ * @param {number} minuend The first number in a subtraction.
+ * @param {number} subtrahend The second number in a subtraction.
+ * @returns {number} Returns the difference.
+ * @example
+ *
+ * _.subtract(6, 4);
+ * // => 2
+ */var subtract=createMathOperation(function(minuend,subtrahend){return minuend-subtrahend;},0);/**
+ * Computes the sum of the values in `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.4.0
+ * @category Math
+ * @param {Array} array The array to iterate over.
+ * @returns {number} Returns the sum.
+ * @example
+ *
+ * _.sum([4, 2, 8, 6]);
+ * // => 20
+ */function sum(array){return array&&array.length?baseSum(array,identity):0;}/**
+ * This method is like `_.sum` except that it accepts `iteratee` which is
+ * invoked for each element in `array` to generate the value to be summed.
+ * The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Math
+ * @param {Array} array The array to iterate over.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {number} Returns the sum.
+ * @example
+ *
+ * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
+ *
+ * _.sumBy(objects, function(o) { return o.n; });
+ * // => 20
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.sumBy(objects, 'n');
+ * // => 20
+ */function sumBy(array,iteratee){return array&&array.length?baseSum(array,getIteratee(iteratee,2)):0;}/*------------------------------------------------------------------------*/ // Add methods that return wrapped values in chain sequences.
+lodash.after=after;lodash.ary=ary;lodash.assign=assign;lodash.assignIn=assignIn;lodash.assignInWith=assignInWith;lodash.assignWith=assignWith;lodash.at=at;lodash.before=before;lodash.bind=bind;lodash.bindAll=bindAll;lodash.bindKey=bindKey;lodash.castArray=castArray;lodash.chain=chain;lodash.chunk=chunk;lodash.compact=compact;lodash.concat=concat;lodash.cond=cond;lodash.conforms=conforms;lodash.constant=constant;lodash.countBy=countBy;lodash.create=create;lodash.curry=curry;lodash.curryRight=curryRight;lodash.debounce=debounce;lodash.defaults=defaults;lodash.defaultsDeep=defaultsDeep;lodash.defer=defer;lodash.delay=delay;lodash.difference=difference;lodash.differenceBy=differenceBy;lodash.differenceWith=differenceWith;lodash.drop=drop;lodash.dropRight=dropRight;lodash.dropRightWhile=dropRightWhile;lodash.dropWhile=dropWhile;lodash.fill=fill;lodash.filter=filter;lodash.flatMap=flatMap;lodash.flatMapDeep=flatMapDeep;lodash.flatMapDepth=flatMapDepth;lodash.flatten=flatten;lodash.flattenDeep=flattenDeep;lodash.flattenDepth=flattenDepth;lodash.flip=flip;lodash.flow=flow;lodash.flowRight=flowRight;lodash.fromPairs=fromPairs;lodash.functions=functions;lodash.functionsIn=functionsIn;lodash.groupBy=groupBy;lodash.initial=initial;lodash.intersection=intersection;lodash.intersectionBy=intersectionBy;lodash.intersectionWith=intersectionWith;lodash.invert=invert;lodash.invertBy=invertBy;lodash.invokeMap=invokeMap;lodash.iteratee=iteratee;lodash.keyBy=keyBy;lodash.keys=keys;lodash.keysIn=keysIn;lodash.map=map;lodash.mapKeys=mapKeys;lodash.mapValues=mapValues;lodash.matches=matches;lodash.matchesProperty=matchesProperty;lodash.memoize=memoize;lodash.merge=merge;lodash.mergeWith=mergeWith;lodash.method=method;lodash.methodOf=methodOf;lodash.mixin=mixin;lodash.negate=negate;lodash.nthArg=nthArg;lodash.omit=omit;lodash.omitBy=omitBy;lodash.once=once;lodash.orderBy=orderBy;lodash.over=over;lodash.overArgs=overArgs;lodash.overEvery=overEvery;lodash.overSome=overSome;lodash.partial=partial;lodash.partialRight=partialRight;lodash.partition=partition;lodash.pick=pick;lodash.pickBy=pickBy;lodash.property=property;lodash.propertyOf=propertyOf;lodash.pull=pull;lodash.pullAll=pullAll;lodash.pullAllBy=pullAllBy;lodash.pullAllWith=pullAllWith;lodash.pullAt=pullAt;lodash.range=range;lodash.rangeRight=rangeRight;lodash.rearg=rearg;lodash.reject=reject;lodash.remove=remove;lodash.rest=rest;lodash.reverse=reverse;lodash.sampleSize=sampleSize;lodash.set=set;lodash.setWith=setWith;lodash.shuffle=shuffle;lodash.slice=slice;lodash.sortBy=sortBy;lodash.sortedUniq=sortedUniq;lodash.sortedUniqBy=sortedUniqBy;lodash.split=split;lodash.spread=spread;lodash.tail=tail;lodash.take=take;lodash.takeRight=takeRight;lodash.takeRightWhile=takeRightWhile;lodash.takeWhile=takeWhile;lodash.tap=tap;lodash.throttle=throttle;lodash.thru=thru;lodash.toArray=toArray;lodash.toPairs=toPairs;lodash.toPairsIn=toPairsIn;lodash.toPath=toPath;lodash.toPlainObject=toPlainObject;lodash.transform=transform;lodash.unary=unary;lodash.union=union;lodash.unionBy=unionBy;lodash.unionWith=unionWith;lodash.uniq=uniq;lodash.uniqBy=uniqBy;lodash.uniqWith=uniqWith;lodash.unset=unset;lodash.unzip=unzip;lodash.unzipWith=unzipWith;lodash.update=update;lodash.updateWith=updateWith;lodash.values=values;lodash.valuesIn=valuesIn;lodash.without=without;lodash.words=words;lodash.wrap=wrap;lodash.xor=xor;lodash.xorBy=xorBy;lodash.xorWith=xorWith;lodash.zip=zip;lodash.zipObject=zipObject;lodash.zipObjectDeep=zipObjectDeep;lodash.zipWith=zipWith;// Add aliases.
+lodash.entries=toPairs;lodash.entriesIn=toPairsIn;lodash.extend=assignIn;lodash.extendWith=assignInWith;// Add methods to `lodash.prototype`.
+mixin(lodash,lodash);/*------------------------------------------------------------------------*/ // Add methods that return unwrapped values in chain sequences.
+lodash.add=add;lodash.attempt=attempt;lodash.camelCase=camelCase;lodash.capitalize=capitalize;lodash.ceil=ceil;lodash.clamp=clamp;lodash.clone=clone;lodash.cloneDeep=cloneDeep;lodash.cloneDeepWith=cloneDeepWith;lodash.cloneWith=cloneWith;lodash.conformsTo=conformsTo;lodash.deburr=deburr;lodash.defaultTo=defaultTo;lodash.divide=divide;lodash.endsWith=endsWith;lodash.eq=eq;lodash.escape=escape;lodash.escapeRegExp=escapeRegExp;lodash.every=every;lodash.find=find;lodash.findIndex=findIndex;lodash.findKey=findKey;lodash.findLast=findLast;lodash.findLastIndex=findLastIndex;lodash.findLastKey=findLastKey;lodash.floor=floor;lodash.forEach=forEach;lodash.forEachRight=forEachRight;lodash.forIn=forIn;lodash.forInRight=forInRight;lodash.forOwn=forOwn;lodash.forOwnRight=forOwnRight;lodash.get=get;lodash.gt=gt;lodash.gte=gte;lodash.has=has;lodash.hasIn=hasIn;lodash.head=head;lodash.identity=identity;lodash.includes=includes;lodash.indexOf=indexOf;lodash.inRange=inRange;lodash.invoke=invoke;lodash.isArguments=isArguments;lodash.isArray=isArray;lodash.isArrayBuffer=isArrayBuffer;lodash.isArrayLike=isArrayLike;lodash.isArrayLikeObject=isArrayLikeObject;lodash.isBoolean=isBoolean;lodash.isBuffer=isBuffer;lodash.isDate=isDate;lodash.isElement=isElement;lodash.isEmpty=isEmpty;lodash.isEqual=isEqual;lodash.isEqualWith=isEqualWith;lodash.isError=isError;lodash.isFinite=isFinite;lodash.isFunction=isFunction;lodash.isInteger=isInteger;lodash.isLength=isLength;lodash.isMap=isMap;lodash.isMatch=isMatch;lodash.isMatchWith=isMatchWith;lodash.isNaN=isNaN;lodash.isNative=isNative;lodash.isNil=isNil;lodash.isNull=isNull;lodash.isNumber=isNumber;lodash.isObject=isObject;lodash.isObjectLike=isObjectLike;lodash.isPlainObject=isPlainObject;lodash.isRegExp=isRegExp;lodash.isSafeInteger=isSafeInteger;lodash.isSet=isSet;lodash.isString=isString;lodash.isSymbol=isSymbol;lodash.isTypedArray=isTypedArray;lodash.isUndefined=isUndefined;lodash.isWeakMap=isWeakMap;lodash.isWeakSet=isWeakSet;lodash.join=join;lodash.kebabCase=kebabCase;lodash.last=last;lodash.lastIndexOf=lastIndexOf;lodash.lowerCase=lowerCase;lodash.lowerFirst=lowerFirst;lodash.lt=lt;lodash.lte=lte;lodash.max=max;lodash.maxBy=maxBy;lodash.mean=mean;lodash.meanBy=meanBy;lodash.min=min;lodash.minBy=minBy;lodash.stubArray=stubArray;lodash.stubFalse=stubFalse;lodash.stubObject=stubObject;lodash.stubString=stubString;lodash.stubTrue=stubTrue;lodash.multiply=multiply;lodash.nth=nth;lodash.noConflict=noConflict;lodash.noop=noop;lodash.now=now;lodash.pad=pad;lodash.padEnd=padEnd;lodash.padStart=padStart;lodash.parseInt=parseInt;lodash.random=random;lodash.reduce=reduce;lodash.reduceRight=reduceRight;lodash.repeat=repeat;lodash.replace=replace;lodash.result=result;lodash.round=round;lodash.runInContext=runInContext;lodash.sample=sample;lodash.size=size;lodash.snakeCase=snakeCase;lodash.some=some;lodash.sortedIndex=sortedIndex;lodash.sortedIndexBy=sortedIndexBy;lodash.sortedIndexOf=sortedIndexOf;lodash.sortedLastIndex=sortedLastIndex;lodash.sortedLastIndexBy=sortedLastIndexBy;lodash.sortedLastIndexOf=sortedLastIndexOf;lodash.startCase=startCase;lodash.startsWith=startsWith;lodash.subtract=subtract;lodash.sum=sum;lodash.sumBy=sumBy;lodash.template=template;lodash.times=times;lodash.toFinite=toFinite;lodash.toInteger=toInteger;lodash.toLength=toLength;lodash.toLower=toLower;lodash.toNumber=toNumber;lodash.toSafeInteger=toSafeInteger;lodash.toString=toString;lodash.toUpper=toUpper;lodash.trim=trim;lodash.trimEnd=trimEnd;lodash.trimStart=trimStart;lodash.truncate=truncate;lodash.unescape=unescape;lodash.uniqueId=uniqueId;lodash.upperCase=upperCase;lodash.upperFirst=upperFirst;// Add aliases.
+lodash.each=forEach;lodash.eachRight=forEachRight;lodash.first=head;mixin(lodash,function(){var source={};baseForOwn(lodash,function(func,methodName){if(!hasOwnProperty.call(lodash.prototype,methodName)){source[methodName]=func;}});return source;}(),{'chain':false});/*------------------------------------------------------------------------*/ /**
+ * The semantic version number.
+ *
+ * @static
+ * @memberOf _
+ * @type {string}
+ */lodash.VERSION=VERSION;// Assign default placeholders.
+arrayEach(['bind','bindKey','curry','curryRight','partial','partialRight'],function(methodName){lodash[methodName].placeholder=lodash;});// Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
+arrayEach(['drop','take'],function(methodName,index){LazyWrapper.prototype[methodName]=function(n){n=n===undefined$1?1:nativeMax(toInteger(n),0);var result=this.__filtered__&&!index?new LazyWrapper(this):this.clone();if(result.__filtered__){result.__takeCount__=nativeMin(n,result.__takeCount__);}else {result.__views__.push({'size':nativeMin(n,MAX_ARRAY_LENGTH),'type':methodName+(result.__dir__<0?'Right':'')});}return result;};LazyWrapper.prototype[methodName+'Right']=function(n){return this.reverse()[methodName](n).reverse();};});// Add `LazyWrapper` methods that accept an `iteratee` value.
+arrayEach(['filter','map','takeWhile'],function(methodName,index){var type=index+1,isFilter=type==LAZY_FILTER_FLAG||type==LAZY_WHILE_FLAG;LazyWrapper.prototype[methodName]=function(iteratee){var result=this.clone();result.__iteratees__.push({'iteratee':getIteratee(iteratee,3),'type':type});result.__filtered__=result.__filtered__||isFilter;return result;};});// Add `LazyWrapper` methods for `_.head` and `_.last`.
+arrayEach(['head','last'],function(methodName,index){var takeName='take'+(index?'Right':'');LazyWrapper.prototype[methodName]=function(){return this[takeName](1).value()[0];};});// Add `LazyWrapper` methods for `_.initial` and `_.tail`.
+arrayEach(['initial','tail'],function(methodName,index){var dropName='drop'+(index?'':'Right');LazyWrapper.prototype[methodName]=function(){return this.__filtered__?new LazyWrapper(this):this[dropName](1);};});LazyWrapper.prototype.compact=function(){return this.filter(identity);};LazyWrapper.prototype.find=function(predicate){return this.filter(predicate).head();};LazyWrapper.prototype.findLast=function(predicate){return this.reverse().find(predicate);};LazyWrapper.prototype.invokeMap=baseRest(function(path,args){if(typeof path=='function'){return new LazyWrapper(this);}return this.map(function(value){return baseInvoke(value,path,args);});});LazyWrapper.prototype.reject=function(predicate){return this.filter(negate(getIteratee(predicate)));};LazyWrapper.prototype.slice=function(start,end){start=toInteger(start);var result=this;if(result.__filtered__&&(start>0||end<0)){return new LazyWrapper(result);}if(start<0){result=result.takeRight(-start);}else if(start){result=result.drop(start);}if(end!==undefined$1){end=toInteger(end);result=end<0?result.dropRight(-end):result.take(end-start);}return result;};LazyWrapper.prototype.takeRightWhile=function(predicate){return this.reverse().takeWhile(predicate).reverse();};LazyWrapper.prototype.toArray=function(){return this.take(MAX_ARRAY_LENGTH);};// Add `LazyWrapper` methods to `lodash.prototype`.
+baseForOwn(LazyWrapper.prototype,function(func,methodName){var checkIteratee=/^(?:filter|find|map|reject)|While$/.test(methodName),isTaker=/^(?:head|last)$/.test(methodName),lodashFunc=lodash[isTaker?'take'+(methodName=='last'?'Right':''):methodName],retUnwrapped=isTaker||/^find/.test(methodName);if(!lodashFunc){return;}lodash.prototype[methodName]=function(){var value=this.__wrapped__,args=isTaker?[1]:arguments,isLazy=value instanceof LazyWrapper,iteratee=args[0],useLazy=isLazy||isArray(value);var interceptor=function(value){var result=lodashFunc.apply(lodash,arrayPush([value],args));return isTaker&&chainAll?result[0]:result;};if(useLazy&&checkIteratee&&typeof iteratee=='function'&&iteratee.length!=1){// Avoid lazy use if the iteratee has a "length" value other than `1`.
+isLazy=useLazy=false;}var chainAll=this.__chain__,isHybrid=!!this.__actions__.length,isUnwrapped=retUnwrapped&&!chainAll,onlyLazy=isLazy&&!isHybrid;if(!retUnwrapped&&useLazy){value=onlyLazy?value:new LazyWrapper(this);var result=func.apply(value,args);result.__actions__.push({'func':thru,'args':[interceptor],'thisArg':undefined$1});return new LodashWrapper(result,chainAll);}if(isUnwrapped&&onlyLazy){return func.apply(this,args);}result=this.thru(interceptor);return isUnwrapped?isTaker?result.value()[0]:result.value():result;};});// Add `Array` methods to `lodash.prototype`.
+arrayEach(['pop','push','shift','sort','splice','unshift'],function(methodName){var func=arrayProto[methodName],chainName=/^(?:push|sort|unshift)$/.test(methodName)?'tap':'thru',retUnwrapped=/^(?:pop|shift)$/.test(methodName);lodash.prototype[methodName]=function(){var args=arguments;if(retUnwrapped&&!this.__chain__){var value=this.value();return func.apply(isArray(value)?value:[],args);}return this[chainName](function(value){return func.apply(isArray(value)?value:[],args);});};});// Map minified method names to their real names.
+baseForOwn(LazyWrapper.prototype,function(func,methodName){var lodashFunc=lodash[methodName];if(lodashFunc){var key=lodashFunc.name+'';if(!hasOwnProperty.call(realNames,key)){realNames[key]=[];}realNames[key].push({'name':methodName,'func':lodashFunc});}});realNames[createHybrid(undefined$1,WRAP_BIND_KEY_FLAG).name]=[{'name':'wrapper','func':undefined$1}];// Add methods to `LazyWrapper`.
+LazyWrapper.prototype.clone=lazyClone;LazyWrapper.prototype.reverse=lazyReverse;LazyWrapper.prototype.value=lazyValue;// Add chain sequence methods to the `lodash` wrapper.
+lodash.prototype.at=wrapperAt;lodash.prototype.chain=wrapperChain;lodash.prototype.commit=wrapperCommit;lodash.prototype.next=wrapperNext;lodash.prototype.plant=wrapperPlant;lodash.prototype.reverse=wrapperReverse;lodash.prototype.toJSON=lodash.prototype.valueOf=lodash.prototype.value=wrapperValue;// Add lazy aliases.
+lodash.prototype.first=lodash.prototype.head;if(symIterator){lodash.prototype[symIterator]=wrapperToIterator;}return lodash;};/*--------------------------------------------------------------------------*/ // Export lodash.
+var _=runInContext();// Some AMD build optimizers, like r.js, check for condition patterns like:
+if(freeModule){// Export for Node.js.
+(freeModule.exports=_)._=_;// Export for CommonJS support.
+freeExports._=_;}else {// Export to the global object.
+root._=_;}}).call(commonjsGlobal);
+});
+
+/* eslint-disable valid-jsdoc */
+
+/** insertAfter */
+function insertAfter(newElement, targetElement) {
+ var parent = targetElement.parentNode;
+
+ if (parent.lastChild == targetElement) {
+ parent.appendChild(newElement);
+ } else {
+ parent.insertBefore(newElement, targetElement.nextSibling);
+ }
+}
+
+var Status = /*#__PURE__*/function () {
+ function Status(jSPlugin, id) {
+ _classCallCheck$1(this, Status);
+
+ this.id = id;
+ this.jSPlugin = jSPlugin;
+ this.state = {
+ play: false,
+ loading: false
+ };
+ }
+
+ _createClass$1(Status, [{
+ key: "toString",
+ value: function toString() {
+ return "".concat(this.coreX, "-").concat(this.coreY);
+ }
+ }, {
+ key: "setPlayStatus",
+ value: function setPlayStatus(options) {
+ this.state = Object.assign(this.state, options);
+ }
+ }, {
+ key: "loadingStart",
+ value: function loadingStart(id) {
+ var oS = document.createElement('style');
+ document.getElementsByTagName("head")[0].appendChild(oS);
+ oS.innerHTML = '@keyframes antRotate {to {transform: rotate(400deg);transform-origin:50% 50%;}} .loading {display: inline-block;z-index: 1000;-webkit-animation: antRotate 1s infinite linear;animation: antRotate 1s infinite linear;}';
+ var domId = id;
+ var domElement = document.getElementById(domId);
+ var windowWidth = domElement.offsetWidth;
+ var windowHeight = domElement.offsetHeight;
+ var offsetTop = 0; //`calc(50% - ${(domElement.offsetTop / 2)}px)`;//domElement.offsetTop; // `calc(50% - ${domElement.offsetTop / 2}px)`
+
+ var offsetLeft = domElement.offsetLeft; // 鍏堟墽琛屾竻绌簂oading
+
+ if (document.getElementById("".concat(id, "-loading-id-0"))) {
+ document.getElementById("".concat(id, "-loading-id-0")).parentNode.removeChild(document.getElementById("".concat(id, "-loading-id-0")));
+ }
+
+ var loadingContainerDOM = document.createElement('div');
+ loadingContainerDOM.setAttribute('id', "".concat(id, "-loading-id-0"));
+ var style = 'position:absolute;outline:none;pointer-events:none;';
+ console.log("this.jSPlugin", this.jSPlugin);
+ style += 'width: 100%;background-size: cover; background-repeat:no-repeat;';
+ style += 'height: 100%;';
+ style += 'top:' + offsetTop + ';';
+ style += 'left:' + offsetLeft + 'px;';
+ loadingContainerDOM.setAttribute('style', style);
+ loadingContainerDOM.style.height = windowHeight;
+ loadingContainerDOM.setAttribute('class', 'loading-container'); // loadingContainerDOM.innerHTML= loading;
+
+ insertAfter(loadingContainerDOM, domElement);
+ var splitBasis = 1;
+ var loadingItemContainer = document.createElement('div');
+ var loadingStatusDOM = document.createElement('div');
+ loadingItemContainer.setAttribute('class', 'loading-item');
+ loadingItemContainer.setAttribute('id', "".concat(id, "-loading-item-0")); //loadingContainer.setAttribute('style','display:inline-flex;flex-direction:column;justify-content:center;align-items: center;width:'+(windowWidth / splitBasis)+'px;height:'+(windowHeight /splitBasis )+'px;outline:none;vertical-align: top;position:absolute');
+
+ var style = 'display:inline-flex;pointer-events:none;flex-direction:column;justify-content:center;align-items: center;width:100%;height:' + windowHeight + 'px;outline:none;vertical-align: top;position:absolute;';
+ style += 'left:' + calLoadingPostion(windowHeight, windowWidth, splitBasis, 0).left + 'px;';
+ style += 'top:' + calLoadingPostion(windowHeight, windowWidth, splitBasis, 0).top + 'px;';
+ loadingItemContainer.setAttribute('style', style);
+
+ function calLoadingPostion(windowHeight, windowWidth, splitBasis, i) {
+ var top = parseInt(i / splitBasis, 10) * (windowHeight / splitBasis);
+ var left = i % splitBasis * (windowWidth / splitBasis);
+ return {
+ top: top,
+ left: left
+ };
+ }
+
+ var loadingDOM = document.createElement('div');
+ loadingStatusDOM.innerHTML = "";
+ loadingStatusDOM.style.color = "#fff";
+ loadingDOM.setAttribute('class', 'loading');
+ var loading = '<svg t="1567069979438" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2399" width="32" height="32"><path d="M538.5344 266.4448a133.12 133.12 0 1 1 133.12-133.12 133.4272 133.4272 0 0 1-133.12 133.12zM255.0144 372.1984a121.6768 121.6768 0 1 1 121.6768-121.6768 121.856 121.856 0 0 1-121.6768 121.6768zM134.72 647.424a107.3664 107.3664 0 1 1 107.3664-107.264A107.52 107.52 0 0 1 134.72 647.424z m120.32 272.4608a90.9824 90.9824 0 1 1 90.9824-90.9824A91.1616 91.1616 0 0 1 255.04 919.8848zM538.5344 1024a79.36 79.36 0 1 1 79.36-79.36 79.36 79.36 0 0 1-79.36 79.36z m287.6928-134.144a64.1792 64.1792 0 1 1 64.1792-64.1792 64.3584 64.3584 0 0 1-64.1792 64.1792z m117.76-296.704a52.6336 52.6336 0 1 1 52.6592-52.6336 52.608 52.608 0 0 1-52.6336 52.6336z m-158.72-338.7136a40.96 40.96 0 1 1 12.0064 28.8512 40.5248 40.5248 0 0 1-12.0064-28.8512z" fill="#ffffff" p-id="2400"></path></svg>';
+ loadingDOM.innerHTML = loading;
+ loadingItemContainer.appendChild(loadingDOM); // loadingContainer.appendChild(loading);
+
+ loadingItemContainer.appendChild(loadingStatusDOM);
+ loadingContainerDOM.appendChild(loadingItemContainer);
+ }
+ }, {
+ key: "loadingSetText",
+ value: function loadingSetText(opt) {
+ this.loadingClearText();
+
+ if (document.getElementById("".concat(this.id, "-loading-item-0"))) {
+ var textElement = document.getElementById("".concat(this.id, "-loading-item-0")).childNodes[1];
+
+ if (!textElement) {
+ var loadingItemContainer = document.getElementById("".concat(this.id, "-loading-item-0"));
+ textElement = document.createElement('div');
+ textElement.innerHTML = opt.text;
+ loadingItemContainer.appendChild(textElement);
+ }
+
+ textElement.innerHTML = opt.text;
+ textElement.style.fontSize = "14px";
+ textElement.style.color = opt.color || "#FFFFFF";
+ }
+ }
+ }, {
+ key: "loadingClearText",
+ value: function loadingClearText() {
+ if (document.getElementById("".concat(this.id, "-loading-item-0"))) {
+ var elements = document.getElementById("".concat(this.id, "-loading-item-0")).childNodes;
+
+ if (elements.length > 1) {
+ elements[1].parentNode.removeChild(elements[1]);
+ } else {
+ elements[0] && elements[0].parentNode.removeChild(elements[0]);
+ }
+ }
+ }
+ }, {
+ key: "loadingClear",
+ value: function loadingClear() {
+ if (document.getElementById("".concat(this.id, "-loading-item-0"))) {
+ var elements = document.getElementById("".concat(this.id, "-loading-item-0")).childNodes;
+
+ for (var i = elements.length - 1; i >= 0; i--) {
+ elements[i].parentNode.removeChild(elements[i]);
+ }
+
+ if (document.getElementById("".concat(this.id, "-loading-id-0"))) {
+ document.getElementById("".concat(this.id, "-loading-id-0")).style.background = 'none';
+ }
+ }
+ }
+ }, {
+ key: "loadingEnd",
+ value: function loadingEnd() {
+ var loadingItemContainerDOM = document.getElementById("".concat(this.id, "-loading-item-0"));
+
+ if (loadingItemContainerDOM) {
+ loadingItemContainerDOM.parentNode.removeChild(loadingItemContainerDOM);
+ var loadingContainerDOM = document.getElementById("".concat(this.id, "-loading-id-0"));
+
+ if (loadingContainerDOM && loadingContainerDOM.children.length === 0) {
+ loadingContainerDOM.parentNode.removeChild(loadingContainerDOM);
+ }
+ }
+
+ document.getElementById("".concat(this.id, "-loading-item-0")).style.background = 'none';
+ }
+ }]);
+
+ return Status;
+}();
+
+var Message = /*#__PURE__*/function () {
+ function Message(jSPlugin, id) {
+ _classCallCheck$1(this, Message);
+
+ this.id = id;
+ this.jSPlugin = jSPlugin;
+ this.timer = null;
+ this.state = {
+ play: false,
+ loading: false
+ };
+ }
+
+ _createClass$1(Message, [{
+ key: "default",
+ value: function _default(msg) {
+ var _this = this;
+
+ var msgId = "msgId";
+
+ if (document.getElementById("".concat(this.id, "-").concat(msgId))) {
+ document.getElementById("".concat(this.id, "-wrap")).removeChild(document.getElementById("".concat(this.id, "-").concat(msgId)));
+ }
+
+ var messageDOM = document.createElement('div');
+ messageDOM.id = "".concat(this.id, "-").concat(msgId);
+ messageDOM.style = "position: absolute;top: 50%;left:calc(50% - ".concat(msg.length * 14 / 2, "px);padding: 4px 16px;background: #00000080;color: #FFFFFF;font-size: 14px");
+ messageDOM.innerHTML = msg;
+ document.getElementById("".concat(this.id, "-wrap")).appendChild(messageDOM);
+
+ if (this.timer) {
+ clearTimeout(this.timer);
+ }
+
+ this.timer = setTimeout(function () {
+ document.getElementById("".concat(_this.id, "-wrap")).removeChild(document.getElementById("".concat(_this.id, "-").concat(msgId)));
+ }, 2000);
+ }
+ }]);
+
+ return Message;
+}();
+
+var data$8 = [
+ {
+ moduleCode: "",
+ detailCode: "405984",
+ description: "",
+ solution: "",
+ updateTime: 1559564188000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10035",
+ description: "鑾峰彇瀛愯处鎴稟ccessToken寮傚父,瀛愯处鎴蜂笉瀛樺湪鎴栧瓙璐︽埛涓嶅睘浜庤寮�鍙戣��",
+ solution: "",
+ updateTime: 1559551958000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1052674",
+ description: "鑾峰彇鏈湴褰曞儚澶辫触",
+ solution: "",
+ updateTime: 1558579653000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395547",
+ description: "",
+ solution: "",
+ updateTime: 1557367296000
+ },
+ {
+ moduleCode: "",
+ detailCode: "12",
+ description: "",
+ solution: "",
+ updateTime: 1557229476000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10052",
+ description: "浣欓涓嶈冻",
+ solution: "",
+ updateTime: 1557121463000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20108",
+ description: "褰撳墠鐢ㄦ埛鍜屾墍娣诲姞鐢ㄦ埛涓嶆槸濂藉弸鍏崇郴",
+ solution: "",
+ updateTime: 1556541725000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10009",
+ description: "",
+ solution: "",
+ updateTime: 1556422452000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320001",
+ description: "閫氶亾涓嶅瓨鍦�",
+ solution: "璇锋鏌ュ綍鍍忔満鐨勫叧鑱旂姸鎬佹槸鍚︽甯革紝娌℃湁鎽勫儚澶寸殑閫氶亾鏃犳硶鎾斁",
+ updateTime: 1556419044000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120001",
+ description: "閫氶亾涓嶅瓨鍦�",
+ solution: "璇锋鏌ュ綍鍍忔満鐨勫叧鑱旂姸鎬佹槸鍚︽甯革紝娌℃湁鎽勫儚澶寸殑閫氶亾鏃犳硶鎾斁",
+ updateTime: 1556419030000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320049",
+ description: "",
+ solution: "",
+ updateTime: 1556272984000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380227",
+ description: "",
+ solution: "",
+ updateTime: 1556264379000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10033",
+ description: "policy鍙傛暟淇℃伅寮傚父",
+ solution: "",
+ updateTime: 1555922124000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10065",
+ description: "weakAppKey 涓嶅睘浜巃ccessToken瀵瑰簲鐨勭敤鎴�",
+ solution: "",
+ updateTime: 1555497522000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395416",
+ description: "璁惧杈惧埌鏈�澶ц繛鎺ユ暟锛屾棤娉曞缓绔嬭繛鎺�",
+ solution: "璇峰崌绾ц澶囧浐浠剁増鏈�",
+ updateTime: 1555394722000
+ },
+ {
+ moduleCode: "",
+ detailCode: "100001",
+ description: "",
+ solution: "",
+ updateTime: 1555141776000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395558",
+ description: "",
+ solution: "",
+ updateTime: 1554987121000
+ },
+ {
+ moduleCode: "",
+ detailCode: "70001",
+ description: "鏅鸿兘瀹跺眳涔版柇鐢ㄦ埛璁惧鍙楀埌闄愬埗,寤鸿鍚堢悊閫夋嫨pagestart鍜宲ageSize",
+ solution: "",
+ updateTime: 1554691023000
+ },
+ {
+ moduleCode: "",
+ detailCode: "170001",
+ description: "",
+ solution: "",
+ updateTime: 1554691023000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1012",
+ description: "閲嶇疆澶辫触",
+ solution: "",
+ updateTime: 1554645841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1043",
+ description: "閲嶇疆澶辫触",
+ solution: "",
+ updateTime: 1554645834000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60060",
+ description: "鐩存挱鍔熻兘鏈紑閫�",
+ solution: "閫氶亾鏈紑閫氱洿鎾姛鑳斤紝璇峰厛寮�閫氱洿鎾�",
+ updateTime: 1554346018000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380203",
+ description: "",
+ solution: "",
+ updateTime: 1554093666000
+ },
+ {
+ moduleCode: "",
+ detailCode: "399048",
+ description: "鍏嶈垂鐗堝苟鍙戞暟杈惧埌涓婇檺锛岃鍗囩骇浼佷笟鐗堜娇鐢ㄥ骞跺彂鑳藉姏",
+ solution: "鍗囩骇鎴愪负浼佷笟鐗堝椁愬嵆鍙彇娑堝苟鍙戞暟闄愬埗",
+ updateTime: 1553839878000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60007",
+ description: "棰勭疆鐐逛釜鏁拌秴杩囨渶澶у��",
+ solution: "",
+ updateTime: 1553671316000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1005",
+ description: "",
+ solution: "",
+ updateTime: 1553513701000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20605",
+ description: "鍏朵粬鐢ㄦ埛姝e湪璁よ瘉涓�",
+ solution: "",
+ updateTime: 1552976317000
+ },
+ {
+ moduleCode: "",
+ detailCode: "90004",
+ description: "褰撳墠鍨嬪彿璁惧鏆傛椂涓嶆敮鎸丄I浠诲姟锛欳S-C3W-3B1WFR-YGL",
+ solution: "",
+ updateTime: 1552898525000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60046",
+ description: "娣诲姞鐨勮澶囩殑IP鍜屾湰璁惧鐨処P鍐茬獊",
+ solution: "",
+ updateTime: 1552872372000
+ },
+ {
+ moduleCode: "",
+ detailCode: "3",
+ description: "淇敼瑙嗛娓呮櫚搴﹀け璐�!",
+ solution: "",
+ updateTime: 1552440229000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1013",
+ description: "",
+ solution: "",
+ updateTime: 1552035069000
+ },
+ {
+ moduleCode: "",
+ detailCode: "370007",
+ description: "",
+ solution: "",
+ updateTime: 1551852327000
+ },
+ {
+ moduleCode: "",
+ detailCode: "-1",
+ description: "",
+ solution: "",
+ updateTime: 1551752889000
+ },
+ {
+ moduleCode: "",
+ detailCode: "30005",
+ description: "寮辫处鎴蜂笉瀛樺湪",
+ solution: "",
+ updateTime: 1551422358000
+ },
+ {
+ moduleCode: "",
+ detailCode: "90006",
+ description: "鐢ㄦ埛鎿嶄綔AI浠诲姟鍙楅檺",
+ solution: "",
+ updateTime: 1551073320000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60203",
+ description: "鏈紑閫氱浉鍏虫湇鍔�",
+ solution: "",
+ updateTime: 1550623070000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10002",
+ description: "accessToken杩囨湡鎴栧紓甯�",
+ solution: "",
+ updateTime: 1550300346000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380339",
+ description: "",
+ solution: "",
+ updateTime: 1549889458000
+ },
+ {
+ moduleCode: "",
+ detailCode: "90002",
+ description: "AI浠诲姟璁惧閰嶇疆鏁拌揪鍒颁笂闄愶細3",
+ solution: "",
+ updateTime: 1549071664000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380008",
+ description: "",
+ solution: "",
+ updateTime: 1549005979000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320227",
+ description: "",
+ solution: "",
+ updateTime: 1548739731000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60059",
+ description: "ezopen鍦板潃鍧囦笉鍙敤",
+ solution: "",
+ updateTime: 1548395350000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10005",
+ description: "appKey寮傚父",
+ solution: "",
+ updateTime: 1548317858000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60045",
+ description: "娣诲姞鐨勮澶囩殑IP鍜屽叾浠栭�氶亾鐨処P鍐茬獊",
+ solution: "",
+ updateTime: 1548155085000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60047",
+ description: "鐮佹祦绫诲瀷涓嶆敮鎸�",
+ solution: "",
+ updateTime: 1547962108000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60041",
+ description: "娣诲姞鐨勮澶囪鍏朵粬璁惧鍏宠仈鎴栧搷搴旇秴鏃�",
+ solution: "",
+ updateTime: 1547960980000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110029",
+ description: "涓汉鐢ㄦ埛鎺ュ彛璋冪敤棰戠巼瓒呴檺",
+ solution: "璇峰崌绾т紒涓氱増锛歨ttps://open.ys7.com/price.html",
+ updateTime: 1547606859000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380355",
+ description: "璁惧鐩磋繛鎺ㄦ祦寮傚父缁撴潫",
+ solution: "",
+ updateTime: 1547106294000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320081",
+ description: "",
+ solution: "",
+ updateTime: 1547106279000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60035",
+ description: "璐拱浜戝瓨鍌ㄦ湇鍔″け璐�",
+ solution: "",
+ updateTime: 1547026959000
+ },
+ {
+ moduleCode: "",
+ detailCode: "90005",
+ description: "璁惧宸插瓨鍦細C75714141",
+ solution: "",
+ updateTime: 1546940622000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1053445",
+ description: "璇ユ椂闂存娌℃湁褰曞儚鐗囨",
+ solution: "",
+ updateTime: 1546935727000
+ },
+ {
+ moduleCode: "",
+ detailCode: "90007",
+ description: "璁惧鏈姞鍏ュ埌AI浠诲姟",
+ solution: "",
+ updateTime: 1546932948000
+ },
+ {
+ moduleCode: "",
+ detailCode: "326000",
+ description: "",
+ solution: "",
+ updateTime: 1546823143000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1021",
+ description: "閲嶇疆澶辫触",
+ solution: "",
+ updateTime: 1546781152000
+ },
+ {
+ moduleCode: "",
+ detailCode: "2001",
+ description: "鍒犻櫎璁惧澶辫触!",
+ solution: "",
+ updateTime: 1546422886000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380425",
+ description: "",
+ solution: "",
+ updateTime: 1546407694000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120097",
+ description: "",
+ solution: "",
+ updateTime: 1546085995000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10059",
+ description: "requestId宸插瓨鍦�",
+ solution: "",
+ updateTime: 1545824509000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1154723",
+ description: "",
+ solution: "",
+ updateTime: 1545795209000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60043",
+ description: "娣诲姞鐨勮澶囪秴鍑烘渶澶ф暟閲�",
+ solution: "",
+ updateTime: 1545493607000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1152677",
+ description: "",
+ solution: "",
+ updateTime: 1545313404000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20097",
+ description: "璁惧娣诲姞寮傚父,璁惧楠岃瘉鐮佷负ABCDEF鎴栬澶囪N1锛孯1鍏宠仈",
+ solution: "",
+ updateTime: 1545310795000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10060",
+ description: "璁惧涓嶆敮鎸佽浜戝瓨鍌ㄧ被鍨�",
+ solution: "",
+ updateTime: 1545309064000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20102",
+ description: "鏃犵浉搴旈個璇蜂俊鎭紝鏃犳硶鎺ュ彈閭�璇�",
+ solution: "",
+ updateTime: 1545204966000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10053",
+ description: "浜戝瓨鍌ㄥ紑閫氫腑",
+ solution: "",
+ updateTime: 1545100293000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20401",
+ description: "鐢ㄦ埛浜戠┖闂翠俊鎭笉瀛樺湪",
+ solution: "",
+ updateTime: 1545017880000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20600",
+ description: "涓存椂瀵嗙爜鏁板凡杈句笂闄�",
+ solution: "",
+ updateTime: 1544873457000
+ },
+ {
+ moduleCode: "",
+ detailCode: "901",
+ description: "",
+ solution: "",
+ updateTime: 1544693519000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60210",
+ description: "鍥剧墖鏁版嵁閿欒",
+ solution: "",
+ updateTime: 1544604457000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10013",
+ description: "鎮ㄧ殑搴旂敤娌℃湁鏉冮檺璋冪敤",
+ solution: "",
+ updateTime: 1544416237000
+ },
+ {
+ moduleCode: "",
+ detailCode: "70007",
+ description: "鎺堟潈鐮佷笉瀛樺湪",
+ solution: "",
+ updateTime: 1544179533000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10015",
+ description: "鎺堟潈鍦板潃涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1544163240000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320423",
+ description: "",
+ solution: "",
+ updateTime: 1544100685000
+ },
+ {
+ moduleCode: "",
+ detailCode: "370009",
+ description: "",
+ solution: "",
+ updateTime: 1544077151000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10031",
+ description: "瀛愯处鎴锋垨钀ょ煶鐢ㄦ埛娌℃湁鏉冮檺",
+ solution: "",
+ updateTime: 1543990462000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10055",
+ description: "璁惧涓嶆敮鎸佽瘯鐢ㄤ簯瀛樺偍鏈嶅姟",
+ solution: "",
+ updateTime: 1543986292000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60042",
+ description: "娣诲姞鐨勮澶囧瘑鐮侀敊璇�",
+ solution: "",
+ updateTime: 1543710913000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60082",
+ description: "璁惧姝e湪鍝嶅簲鏈澹版簮瀹氫綅",
+ solution: "",
+ updateTime: 1543647426000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10056",
+ description: "璁惧涓嶆敮鎸佷簯瀛樺偍鏈嶅姟杞嚭",
+ solution: "",
+ updateTime: 1543558342000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20104",
+ description: "濂藉弸涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1543492403000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20111",
+ description: "濂藉弸涓嶆槸绛夊緟楠岃瘉鐘舵�侊紝鏃犳硶鎺ュ彈閭�璇�",
+ solution: "",
+ updateTime: 1543492365000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20107",
+ description: "涓嶈兘娣诲姞鑷繁涓哄ソ鍙�",
+ solution: "",
+ updateTime: 1543480986000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1",
+ description: "璁惧杩斿洖鍏朵粬閿欒",
+ solution: "",
+ updateTime: 1543459921000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60084",
+ description: "褰撳墠姝e湪鍏抽棴闅愮閬斀",
+ solution: "",
+ updateTime: 1543456515000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380255",
+ description: "",
+ solution: "",
+ updateTime: 1543411652000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20015",
+ description: "璁惧涓嶆敮鎸�",
+ solution: "",
+ updateTime: 1543390936000
+ },
+ {
+ moduleCode: "",
+ detailCode: "30003",
+ description: "鎵嬫満楠岃瘉鐮侀敊璇�",
+ solution: "",
+ updateTime: 1543389137000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20615",
+ description: "閿佺敤鎴峰凡瀛樺湪",
+ solution: "",
+ updateTime: 1543388325000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60061",
+ description: "璐︽埛娴侀噺宸茶秴鍑烘垨鏈喘涔帮紝闄愬埗寮�閫�",
+ solution: "",
+ updateTime: 1543372581000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60020",
+ description: "璁惧涓嶆敮鎸佽淇′护",
+ solution: "",
+ updateTime: 1543321636000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320146",
+ description: "",
+ solution: "",
+ updateTime: 1543318472000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60018",
+ description: "璁惧鍗囩骇澶辫触",
+ solution: "",
+ updateTime: 1543304928000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60044",
+ description: "娣诲姞鐨勮澶囩綉缁滀笉鍙揪瓒呮椂",
+ solution: "",
+ updateTime: 1543304102000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20619",
+ description: "涓荤敤鎴锋棤娉曞垹闄�",
+ solution: "",
+ updateTime: 1543290219000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20608",
+ description: "閿佺敤鎴蜂笉瀛樺湪",
+ solution: "",
+ updateTime: 1543281950000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20609",
+ description: "璁惧鍝嶅簲瓒呮椂,闂ㄩ攣閫氫俊鏁呴殰鎴栬�呯數閲忎笉瓒�,璇烽噸璇�.",
+ solution: "",
+ updateTime: 1543281601000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1049954",
+ description: "鍗囩骇璁惧澶辫触",
+ solution: "",
+ updateTime: 1543279264000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60009",
+ description: "姝e湪璋冪敤棰勭疆鐐�",
+ solution: "",
+ updateTime: 1543238114000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1052677",
+ description: "鑾峰彇鏈湴褰曞儚澶辫触",
+ solution: "",
+ updateTime: 1543207604000
+ },
+ {
+ moduleCode: "",
+ detailCode: "327000",
+ description: "",
+ solution: "",
+ updateTime: 1543196609000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20021",
+ description: "璁惧鍦ㄧ嚎锛屾湭琚敤鎴锋坊鍔�",
+ solution: "",
+ updateTime: 1543193436000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20202",
+ description: "鎿嶄綔鐣欒█淇℃伅澶辫触",
+ solution: "",
+ updateTime: 1543191562000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1052678",
+ description: "鑾峰彇鏈湴褰曞儚澶辫触",
+ solution: "",
+ updateTime: 1543132218000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1054723",
+ description: "鏍煎紡鍖栬澶囧け璐�",
+ solution: "",
+ updateTime: 1543129833000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20109",
+ description: "瀵瑰簲鍒嗕韩涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1543129111000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60026",
+ description: "璁惧澶勪簬闅愮閬斀鐘舵��",
+ solution: "",
+ updateTime: 1543110403000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60083",
+ description: "褰撳墠姝e湪寮�鍚殣绉侀伄钄�",
+ solution: "",
+ updateTime: 1543071148000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60001",
+ description: "鐢ㄦ埛鏃犱簯鍙版帶鍒舵潈闄�",
+ solution: "",
+ updateTime: 1543059167000
+ },
+ {
+ moduleCode: "",
+ detailCode: "2003",
+ description: "璁惧涓嶅湪绾�",
+ solution: "",
+ updateTime: 1543051046000
+ },
+ {
+ moduleCode: "",
+ detailCode: "-24",
+ description: "璁剧疆璁惧enable閿欒",
+ solution: "",
+ updateTime: 1543042701000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10018",
+ description: "",
+ solution: "",
+ updateTime: 1543041564000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20103",
+ description: "濂藉弸宸插瓨鍦�",
+ solution: "",
+ updateTime: 1543038430000
+ },
+ {
+ moduleCode: "",
+ detailCode: "70010",
+ description: "鎺堟潈寮傚父璇烽噸璇�",
+ solution: "",
+ updateTime: 1543035590000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60056",
+ description: "鍒犻櫎璁惧澶辫触",
+ solution: "",
+ updateTime: 1543031275000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60040",
+ description: "娣诲姞鐨勮澶囦笉鍦ㄥ悓涓�灞�鍩熺綉",
+ solution: "",
+ updateTime: 1543031210000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60019",
+ description: "鍔犲瘑宸插紑鍚�",
+ solution: "",
+ updateTime: 1543029931000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1054722",
+ description: "鏍煎紡鍖栬澶囧け璐�",
+ solution: "",
+ updateTime: 1543028537000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20016",
+ description: "褰撳墠璁惧姝e湪鏍煎紡鍖�",
+ solution: "",
+ updateTime: 1543028537000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10024",
+ description: "閫忔槑閫氶亾鏉冮檺鏍¢獙涓嶉�氳繃",
+ solution: "",
+ updateTime: 1543025540000
+ },
+ {
+ moduleCode: "",
+ detailCode: "6002",
+ description: "鍒犻櫎璁惧澶辫触!",
+ solution: "",
+ updateTime: 1543025026000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1011",
+ description: "楠岃瘉鐮侀敊璇紒",
+ solution: "",
+ updateTime: 1543016865000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60032",
+ description: "鍗″瘑宸蹭娇鐢�",
+ solution: "",
+ updateTime: 1543006668000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10034",
+ description: "瀛愯处鍙峰凡瀛樺湪",
+ solution: "",
+ updateTime: 1542989194000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20301",
+ description: "鏍规嵁uuid鏌ヨ鑱斿姩淇℃伅涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1542988651000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1041",
+ description: "鑾峰彇楠岃瘉鐮佽繃浜庨绻�",
+ solution: "",
+ updateTime: 1542980953000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10012",
+ description: "璇ppkey涓嬪凡缁戝畾閲嶅鐨刾hone锛�",
+ solution: "",
+ updateTime: 1542980800000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1008",
+ description: "phone涓嶅悎娉曪紒",
+ solution: "",
+ updateTime: 1542979812000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60023",
+ description: "璁㈤槄鎿嶄綔澶辫触",
+ solution: "",
+ updateTime: 1542979006000
+ },
+ {
+ moduleCode: "",
+ detailCode: "5",
+ description: "璁惧杩斿洖鍏朵粬閿欒",
+ solution: "",
+ updateTime: 1542977828000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60006",
+ description: "浜戝彴褰撳墠鎿嶄綔澶辫触",
+ solution: "",
+ updateTime: 1542977598000
+ },
+ {
+ moduleCode: "",
+ detailCode: "131",
+ description: "淇敼瑙嗛娓呮櫚搴﹀け璐�!",
+ solution: "",
+ updateTime: 1542977246000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10019",
+ description: "瀵嗙爜閿欒",
+ solution: "",
+ updateTime: 1542976628000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10004",
+ description: "鐢ㄦ埛涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1542976268000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20201",
+ description: "鎿嶄綔鎶ヨ淇℃伅澶辫触",
+ solution: "",
+ updateTime: 1542975906000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20024",
+ description: "璁惧涓嶅湪绾匡紝宸茬粡琚埆鐨勭敤鎴锋坊鍔�",
+ solution: "",
+ updateTime: 1542975858000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60004",
+ description: "璁惧浜戝彴鏃嬭浆杈惧埌宸﹂檺浣�",
+ solution: "",
+ updateTime: 1542975207000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1052679",
+ description: "淇敼瑙嗛娓呮櫚搴﹀け璐�!",
+ solution: "",
+ updateTime: 1542974886000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20031",
+ description: "璇峰湪钀ょ煶瀹㈡埛绔叧闂粓绔粦瀹�",
+ solution: "",
+ updateTime: 1542974756000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1053825",
+ description: "鑾峰彇鏈湴褰曞儚澶辫触",
+ solution: "",
+ updateTime: 1542974692000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60011",
+ description: "棰勭疆鐐逛笉瀛樺湪",
+ solution: "",
+ updateTime: 1542974414000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1052936",
+ description: "淇敼瑙嗛娓呮櫚搴﹀け璐�!",
+ solution: "",
+ updateTime: 1542974390000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1016",
+ description: "",
+ solution: "",
+ updateTime: 1542974273000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10032",
+ description: "瀛愯处鍙蜂笉瀛樺湪",
+ solution: "",
+ updateTime: 1542973906000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20013",
+ description: "璁惧宸茶鍒汉娣诲姞",
+ solution: "",
+ updateTime: 1542973817000
+ },
+ {
+ moduleCode: "",
+ detailCode: "50000",
+ description: "鏈嶅姟鍣ㄩ敊璇�!",
+ solution: "",
+ updateTime: 1542973801000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60010",
+ description: "璇ラ缃偣宸茬粡鏄綋鍓嶄綅缃�",
+ solution: "",
+ updateTime: 1542973800000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60003",
+ description: "璁惧浜戝彴鏃嬭浆杈惧埌涓嬮檺浣�",
+ solution: "",
+ updateTime: 1542973770000
+ },
+ {
+ moduleCode: "",
+ detailCode: "4",
+ description: "璁惧杩斿洖鍏朵粬閿欒",
+ solution: "",
+ updateTime: 1542973755000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60016",
+ description: "鍔犲瘑鏈紑鍚紝鏃犻渶鍏抽棴",
+ solution: "",
+ updateTime: 1542973753000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60002",
+ description: "璁惧浜戝彴鏃嬭浆杈惧埌涓婇檺浣�",
+ solution: "",
+ updateTime: 1542973742000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20023",
+ description: "璁惧涓嶅湪绾匡紝鏈鐢ㄦ埛娣诲姞",
+ solution: "",
+ updateTime: 1542973685000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10008",
+ description: "",
+ solution: "",
+ updateTime: 1542973676000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20010",
+ description: "璁惧楠岃瘉鐮侀敊璇�",
+ solution: "",
+ updateTime: 1542973658000
+ },
+ {
+ moduleCode: "",
+ detailCode: "60005",
+ description: "璁惧浜戝彴鏃嬭浆杈惧埌鍙抽檺浣�",
+ solution: "",
+ updateTime: 1542973657000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20017",
+ description: "璁惧宸茬粡琚嚜宸辨坊鍔�",
+ solution: "",
+ updateTime: 1542973648000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20020",
+ description: "璁惧鍦ㄧ嚎锛屽凡缁忚鑷繁娣诲姞",
+ solution: "",
+ updateTime: 1542973533000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20029",
+ description: "璁惧涓嶅湪绾匡紝宸茬粡琚嚜宸辨坊鍔�",
+ solution: "",
+ updateTime: 1542973530000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10014",
+ description: "APPKEY涓嬪搴旂殑绗笁鏂箄serId鍜宲hone鏈粦瀹氾紒",
+ solution: "",
+ updateTime: 1542973499000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20002",
+ description: "璁惧涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1542973499000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10030",
+ description: "appkey鍜宎ppsecret涓嶅尮閰�",
+ solution: "",
+ updateTime: 1542973490000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20022",
+ description: "璁惧鍦ㄧ嚎锛屽凡缁忚鍒殑鐢ㄦ埛娣诲姞",
+ solution: "",
+ updateTime: 1542973486000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20008",
+ description: "璁惧鍝嶅簲瓒呮椂",
+ solution: "",
+ updateTime: 1542973484000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20032",
+ description: "璇ョ敤鎴蜂笅閫氶亾涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1542973481000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20006",
+ description: "缃戠粶寮傚父",
+ solution: "",
+ updateTime: 1542973475000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20014",
+ description: "deviceSerial涓嶅悎娉�!",
+ solution: "",
+ updateTime: 1542973454000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20007",
+ description: "璁惧涓嶅湪绾�",
+ solution: "",
+ updateTime: 1542973454000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20018",
+ description: "璇ョ敤鎴蜂笉鎷ユ湁璇ヨ澶�",
+ solution: "",
+ updateTime: 1542973453000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10010",
+ description: "",
+ solution: "",
+ updateTime: 1542973453000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10011",
+ description: "鏈粦瀹氾紒",
+ solution: "",
+ updateTime: 1542973453000
+ },
+ {
+ moduleCode: "",
+ detailCode: "20001",
+ description: "閫氶亾涓嶅瓨鍦�!",
+ solution: "",
+ updateTime: 1542973452000
+ },
+ {
+ moduleCode: "",
+ detailCode: "10017",
+ description: "appKey涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1542973451000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400259",
+ description: "",
+ solution: "",
+ updateTime: 1542875643000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400004",
+ description: "",
+ solution: "",
+ updateTime: 1542873364000
+ },
+ {
+ moduleCode: "",
+ detailCode: "3840",
+ description: "",
+ solution: "",
+ updateTime: 1541860000000
+ },
+ {
+ moduleCode: "",
+ detailCode: "-1017",
+ description: "",
+ solution: "",
+ updateTime: 1541733663000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320025",
+ description: "",
+ solution: "",
+ updateTime: 1541078281000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320024",
+ description: "",
+ solution: "",
+ updateTime: 1540801374000
+ },
+ {
+ moduleCode: "",
+ detailCode: "321002",
+ description: "",
+ solution: "",
+ updateTime: 1540631734000
+ },
+ {
+ moduleCode: "",
+ detailCode: "321000",
+ description: "",
+ solution: "",
+ updateTime: 1540609178000
+ },
+ {
+ moduleCode: "",
+ detailCode: "321022",
+ description: "",
+ solution: "",
+ updateTime: 1540548345000
+ },
+ {
+ moduleCode: "",
+ detailCode: "321016",
+ description: "",
+ solution: "",
+ updateTime: 1540287187000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320023",
+ description: "",
+ solution: "",
+ updateTime: 1539825993000
+ },
+ {
+ moduleCode: "",
+ detailCode: "-1016",
+ description: "",
+ solution: "",
+ updateTime: 1539584931000
+ },
+ {
+ moduleCode: "",
+ detailCode: "8",
+ description: "",
+ solution: "",
+ updateTime: 1539391812000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1075127593",
+ description: "",
+ solution: "",
+ updateTime: 1538959251000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380421",
+ description: "",
+ solution: "",
+ updateTime: 1537288465000
+ },
+ {
+ moduleCode: "",
+ detailCode: "322000",
+ description: "楹﹀厠椋庢潈闄愭湭寮�鍚�",
+ solution: "",
+ updateTime: 1536820136000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1152678",
+ description: "",
+ solution: "",
+ updateTime: 1536738348000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320047",
+ description: "",
+ solution: "",
+ updateTime: 1536664472000
+ },
+ {
+ moduleCode: "",
+ detailCode: "327006",
+ description: "",
+ solution: "",
+ updateTime: 1536136120000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1074807593",
+ description: "",
+ solution: "",
+ updateTime: 1536135035000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320291",
+ description: "",
+ solution: "",
+ updateTime: 1536110836000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320045",
+ description: "",
+ solution: "",
+ updateTime: 1535963775000
+ },
+ {
+ moduleCode: "",
+ detailCode: "370004",
+ description: "",
+ solution: "",
+ updateTime: 1535883699000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1149954",
+ description: "",
+ solution: "",
+ updateTime: 1535700674000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320053",
+ description: "",
+ solution: "",
+ updateTime: 1535681079000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400000",
+ description: "",
+ solution: "",
+ updateTime: 1535532332000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110028",
+ description: "涓汉鐗堟姄鍥炬帴鍙f棩璋冪敤娆℃暟瓒呭嚭闄愬埗",
+ solution: "璇峰崌绾т紒涓氱増锛歨ttps://open.ys7.com/price.html",
+ updateTime: 1535348756000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110027",
+ description: "涓汉鐗堝笎鍙锋暟閲忚秴鍑哄畨鍏ㄩ檺鍒讹紝鏃犳硶璋冪敤",
+ solution: "璇峰崌绾т紒涓氱増锛歨ttps://open.ys7.com/price.html",
+ updateTime: 1535348734000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110026",
+ description: "璁惧鏁伴噺瓒呭嚭涓汉鐗堥檺鍒讹紝褰撳墠璁惧鏃犳硶鎿嶄綔",
+ solution: "璇峰崌绾т紒涓氱増锛歨ttps://open.ys7.com/price.html",
+ updateTime: 1535348588000
+ },
+ {
+ moduleCode: "",
+ detailCode: "100000",
+ description: "",
+ solution: "",
+ updateTime: 1534980008000
+ },
+ {
+ moduleCode: "",
+ detailCode: "324004",
+ description: "",
+ solution: "",
+ updateTime: 1534927762000
+ },
+ {
+ moduleCode: "",
+ detailCode: "360104",
+ description: "",
+ solution: "",
+ updateTime: 1534761006000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320204",
+ description: "",
+ solution: "",
+ updateTime: 1534584221000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380001",
+ description: "",
+ solution: "",
+ updateTime: 1534404715000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380204",
+ description: "",
+ solution: "",
+ updateTime: 1534401682000
+ },
+ {
+ moduleCode: "",
+ detailCode: "328006",
+ description: "",
+ solution: "",
+ updateTime: 1534144407000
+ },
+ {
+ moduleCode: "",
+ detailCode: "321703",
+ description: "",
+ solution: "",
+ updateTime: 1534127274000
+ },
+ {
+ moduleCode: "",
+ detailCode: "321510",
+ description: "",
+ solution: "",
+ updateTime: 1533428892000
+ },
+ {
+ moduleCode: "",
+ detailCode: "321006",
+ description: "",
+ solution: "",
+ updateTime: 1533036916000
+ },
+ {
+ moduleCode: "",
+ detailCode: "50009",
+ description: "",
+ solution: "",
+ updateTime: 1532078548000
+ },
+ {
+ moduleCode: "",
+ detailCode: "50007",
+ description: "",
+ solution: "",
+ updateTime: 1531991720000
+ },
+ {
+ moduleCode: "",
+ detailCode: "50018",
+ description: "",
+ solution: "",
+ updateTime: 1531912829000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380451",
+ description: "",
+ solution: "",
+ updateTime: 1531615700000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380336",
+ description: "",
+ solution: "",
+ updateTime: 1531231721000
+ },
+ {
+ moduleCode: "",
+ detailCode: "360020",
+ description: "",
+ solution: "",
+ updateTime: 1531117554000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380418",
+ description: "",
+ solution: "",
+ updateTime: 1531107070000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1153445",
+ description: "璁惧鍦ㄨ鏃堕棿娈靛唴娌℃湁褰曞儚",
+ solution: "",
+ updateTime: 1530944007000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110007",
+ description: "璋冪敤鎺ュ彛鎬绘鏁拌揪鍒颁笂闄�",
+ solution: "璇峰崌绾т紒涓氱増锛岃幏鍙栨洿楂樿兘鍔�",
+ updateTime: 1530935584000
+ },
+ {
+ moduleCode: "",
+ detailCode: "360019",
+ description: "",
+ solution: "",
+ updateTime: 1530869771000
+ },
+ {
+ moduleCode: "",
+ detailCode: "360100",
+ description: "",
+ solution: "",
+ updateTime: 1530786188000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380042",
+ description: "",
+ solution: "",
+ updateTime: 1530775199000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320355",
+ description: "",
+ solution: "",
+ updateTime: 1530716074000
+ },
+ {
+ moduleCode: "",
+ detailCode: "100003",
+ description: "",
+ solution: "",
+ updateTime: 1530232541000
+ },
+ {
+ moduleCode: "",
+ detailCode: "371026",
+ description: "",
+ solution: "",
+ updateTime: 1530192600000
+ },
+ {
+ moduleCode: "",
+ detailCode: "102",
+ description: "",
+ solution: "",
+ updateTime: 1529895641000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380201",
+ description: "",
+ solution: "",
+ updateTime: 1529740929000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320054",
+ description: "",
+ solution: "",
+ updateTime: 1529544875000
+ },
+ {
+ moduleCode: "",
+ detailCode: "500101",
+ description: "",
+ solution: "",
+ updateTime: 1529485953000
+ },
+ {
+ moduleCode: "",
+ detailCode: "321001",
+ description: "",
+ solution: "",
+ updateTime: 1529411048000
+ },
+ {
+ moduleCode: "",
+ detailCode: "321508",
+ description: "",
+ solution: "",
+ updateTime: 1529393279000
+ },
+ {
+ moduleCode: "",
+ detailCode: "405991",
+ description: "",
+ solution: "",
+ updateTime: 1529380238000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380461",
+ description: "",
+ solution: "",
+ updateTime: 1529130941000
+ },
+ {
+ moduleCode: "",
+ detailCode: "-1019",
+ description: "",
+ solution: "",
+ updateTime: 1529057245000
+ },
+ {
+ moduleCode: "",
+ detailCode: "322009",
+ description: "",
+ solution: "",
+ updateTime: 1528965717000
+ },
+ {
+ moduleCode: "",
+ detailCode: "324005",
+ description: "",
+ solution: "",
+ updateTime: 1528950153000
+ },
+ {
+ moduleCode: "",
+ detailCode: "325000",
+ description: "",
+ solution: "",
+ updateTime: 1528947143000
+ },
+ {
+ moduleCode: "",
+ detailCode: "326032",
+ description: "",
+ solution: "",
+ updateTime: 1528872971000
+ },
+ {
+ moduleCode: "",
+ detailCode: "325032",
+ description: "",
+ solution: "",
+ updateTime: 1528863189000
+ },
+ {
+ moduleCode: "",
+ detailCode: "328000",
+ description: "",
+ solution: "",
+ updateTime: 1528794505000
+ },
+ {
+ moduleCode: "",
+ detailCode: "53",
+ description: "",
+ solution: "",
+ updateTime: 1528693249000
+ },
+ {
+ moduleCode: "",
+ detailCode: "-1020",
+ description: "",
+ solution: "",
+ updateTime: 1528499440000
+ },
+ {
+ moduleCode: "",
+ detailCode: "329032",
+ description: "",
+ solution: "",
+ updateTime: 1528446301000
+ },
+ {
+ moduleCode: "",
+ detailCode: "-1202",
+ description: "",
+ solution: "",
+ updateTime: 1528439820000
+ },
+ {
+ moduleCode: "",
+ detailCode: "2",
+ description: "",
+ solution: "",
+ updateTime: 1528434175000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1152936",
+ description: "",
+ solution: "",
+ updateTime: 1528345986000
+ },
+ {
+ moduleCode: "",
+ detailCode: "328011",
+ description: "",
+ solution: "",
+ updateTime: 1528338600000
+ },
+ {
+ moduleCode: "",
+ detailCode: "28",
+ description: "",
+ solution: "",
+ updateTime: 1528337530000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320356",
+ description: "",
+ solution: "",
+ updateTime: 1528188693000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320357",
+ description: "",
+ solution: "",
+ updateTime: 1528188517000
+ },
+ {
+ moduleCode: "",
+ detailCode: "405800",
+ description: "",
+ solution: "",
+ updateTime: 1528168732000
+ },
+ {
+ moduleCode: "",
+ detailCode: "405996",
+ description: "",
+ solution: "",
+ updateTime: 1528168686000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380357",
+ description: "",
+ solution: "",
+ updateTime: 1528011565000
+ },
+ {
+ moduleCode: "",
+ detailCode: "328022",
+ description: "",
+ solution: "",
+ updateTime: 1527929065000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380003",
+ description: "",
+ solution: "",
+ updateTime: 1527927819000
+ },
+ {
+ moduleCode: "",
+ detailCode: "50004",
+ description: "",
+ solution: "",
+ updateTime: 1527770643000
+ },
+ {
+ moduleCode: "",
+ detailCode: "50011",
+ description: "",
+ solution: "",
+ updateTime: 1527770635000
+ },
+ {
+ moduleCode: "",
+ detailCode: "370017",
+ description: "",
+ solution: "",
+ updateTime: 1527739514000
+ },
+ {
+ moduleCode: "",
+ detailCode: "327032",
+ description: "",
+ solution: "",
+ updateTime: 1527726704000
+ },
+ {
+ moduleCode: "",
+ detailCode: "324001",
+ description: "",
+ solution: "",
+ updateTime: 1527681892000
+ },
+ {
+ moduleCode: "",
+ detailCode: "405997",
+ description: "",
+ solution: "",
+ updateTime: 1527653408000
+ },
+ {
+ moduleCode: "",
+ detailCode: "405995",
+ description: "",
+ solution: "",
+ updateTime: 1527647283000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1153825",
+ description: "",
+ solution: "",
+ updateTime: 1527601747000
+ },
+ {
+ moduleCode: "",
+ detailCode: "328002",
+ description: "",
+ solution: "",
+ updateTime: 1527495292000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1152679",
+ description: "",
+ solution: "",
+ updateTime: 1527486665000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380356",
+ description: "",
+ solution: "",
+ updateTime: 1527125669000
+ },
+ {
+ moduleCode: "",
+ detailCode: "328032",
+ description: "",
+ solution: "",
+ updateTime: 1527069382000
+ },
+ {
+ moduleCode: "",
+ detailCode: "22",
+ description: "",
+ solution: "",
+ updateTime: 1527049826000
+ },
+ {
+ moduleCode: "",
+ detailCode: "9",
+ description: "",
+ solution: "",
+ updateTime: 1527006778000
+ },
+ {
+ moduleCode: "",
+ detailCode: "89",
+ description: "",
+ solution: "",
+ updateTime: 1526622784000
+ },
+ {
+ moduleCode: "",
+ detailCode: "328016",
+ description: "",
+ solution: "",
+ updateTime: 1526452365000
+ },
+ {
+ moduleCode: "",
+ detailCode: "368005",
+ description: "",
+ solution: "",
+ updateTime: 1525921264000
+ },
+ {
+ moduleCode: "",
+ detailCode: "0",
+ description: "",
+ solution: "",
+ updateTime: 1525920242000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380006",
+ description: "",
+ solution: "",
+ updateTime: 1525918868000
+ },
+ {
+ moduleCode: "",
+ detailCode: "310",
+ description: "",
+ solution: "",
+ updateTime: 1525834436000
+ },
+ {
+ moduleCode: "",
+ detailCode: "360011",
+ description: "",
+ solution: "",
+ updateTime: 1525681552000
+ },
+ {
+ moduleCode: "",
+ detailCode: "170005",
+ description: "",
+ solution: "",
+ updateTime: 1525433900000
+ },
+ {
+ moduleCode: "",
+ detailCode: "50023",
+ description: "",
+ solution: "",
+ updateTime: 1525403338000
+ },
+ {
+ moduleCode: "",
+ detailCode: "100131",
+ description: "",
+ solution: "",
+ updateTime: 1525229691000
+ },
+ {
+ moduleCode: "",
+ detailCode: "-1018",
+ description: "",
+ solution: "",
+ updateTime: 1525142341000
+ },
+ {
+ moduleCode: "",
+ detailCode: "362026",
+ description: "",
+ solution: "",
+ updateTime: 1524882677000
+ },
+ {
+ moduleCode: "",
+ detailCode: "368007",
+ description: "",
+ solution: "",
+ updateTime: 1524832269000
+ },
+ {
+ moduleCode: "",
+ detailCode: "54",
+ description: "",
+ solution: "",
+ updateTime: 1524793646000
+ },
+ {
+ moduleCode: "",
+ detailCode: "1154722",
+ description: "",
+ solution: "",
+ updateTime: 1524620807000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320229",
+ description: "",
+ solution: "",
+ updateTime: 1524551682000
+ },
+ {
+ moduleCode: "",
+ detailCode: "360012",
+ description: "",
+ solution: "",
+ updateTime: 1524472094000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380229",
+ description: "",
+ solution: "",
+ updateTime: 1524110755000
+ },
+ {
+ moduleCode: "",
+ detailCode: "360016",
+ description: "",
+ solution: "",
+ updateTime: 1523933518000
+ },
+ {
+ moduleCode: "",
+ detailCode: "-1003",
+ description: "",
+ solution: "",
+ updateTime: 1523584804000
+ },
+ {
+ moduleCode: "",
+ detailCode: "410026",
+ description: "",
+ solution: "",
+ updateTime: 1523517430000
+ },
+ {
+ moduleCode: "",
+ detailCode: "360102",
+ description: "TTS鍒濆鍖栧け璐�",
+ solution: "",
+ updateTime: 1523503528000
+ },
+ {
+ moduleCode: "",
+ detailCode: "360013",
+ description: "璁惧寮�鍚簡闅愮淇濇姢",
+ solution: "",
+ updateTime: 1523503507000
+ },
+ {
+ moduleCode: "",
+ detailCode: "360010",
+ description: "璁惧姝e湪瀵硅涓�",
+ solution: "",
+ updateTime: 1523503491000
+ },
+ {
+ moduleCode: "",
+ detailCode: "360007",
+ description: "TTS鍏抽棴浜嗕笌瀹㈡埛绔殑杩炴帴",
+ solution: "",
+ updateTime: 1523503475000
+ },
+ {
+ moduleCode: "",
+ detailCode: "360006",
+ description: "瀹㈡埛绔帴鏀跺彂鐢熼敊璇�",
+ solution: "",
+ updateTime: 1523503457000
+ },
+ {
+ moduleCode: "",
+ detailCode: "360005",
+ description: "瀹㈡埛绔彂閫佺殑娑堟伅閿欒",
+ solution: "",
+ updateTime: 1523503437000
+ },
+ {
+ moduleCode: "",
+ detailCode: "360004",
+ description: "TTS鍐呴儴鍙戠敓閿欒",
+ solution: "",
+ updateTime: 1523503421000
+ },
+ {
+ moduleCode: "",
+ detailCode: "360003",
+ description: "TTS鐨勮澶囩鍙戠敓閿欒",
+ solution: "",
+ updateTime: 1523503397000
+ },
+ {
+ moduleCode: "",
+ detailCode: "360002",
+ description: "瀵硅鍙戣捣瓒呮椂",
+ solution: "",
+ updateTime: 1523503376000
+ },
+ {
+ moduleCode: "",
+ detailCode: "360001",
+ description: "瀹㈡埛绔姹傝秴鏃�",
+ solution: "",
+ updateTime: 1523503357000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320077",
+ description: "",
+ solution: "",
+ updateTime: 1523444274000
+ },
+ {
+ moduleCode: "",
+ detailCode: "370047",
+ description: "",
+ solution: "",
+ updateTime: 1523440480000
+ },
+ {
+ moduleCode: "",
+ detailCode: "100002",
+ description: "",
+ solution: "",
+ updateTime: 1523413964000
+ },
+ {
+ moduleCode: "",
+ detailCode: "-1004",
+ description: "",
+ solution: "",
+ updateTime: 1523336653000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380000",
+ description: "",
+ solution: "",
+ updateTime: 1523180856000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380213",
+ description: "",
+ solution: "",
+ updateTime: 1523180623000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380101",
+ description: "",
+ solution: "",
+ updateTime: 1522834231000
+ },
+ {
+ moduleCode: "",
+ detailCode: "50047",
+ description: "",
+ solution: "",
+ updateTime: 1522833243000
+ },
+ {
+ moduleCode: "",
+ detailCode: "-999",
+ description: "",
+ solution: "",
+ updateTime: 1522831034000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320418",
+ description: "",
+ solution: "",
+ updateTime: 1522829072000
+ },
+ {
+ moduleCode: "",
+ detailCode: "-1009",
+ description: "",
+ solution: "",
+ updateTime: 1522746247000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320209",
+ description: "",
+ solution: "",
+ updateTime: 1522744395000
+ },
+ {
+ moduleCode: "",
+ detailCode: "368006",
+ description: "",
+ solution: "",
+ updateTime: 1522744300000
+ },
+ {
+ moduleCode: "",
+ detailCode: "369003",
+ description: "",
+ solution: "",
+ updateTime: 1522736355000
+ },
+ {
+ moduleCode: "",
+ detailCode: "405989",
+ description: "",
+ solution: "",
+ updateTime: 1522726571000
+ },
+ {
+ moduleCode: "",
+ detailCode: "-1012",
+ description: "",
+ solution: "",
+ updateTime: 1522726203000
+ },
+ {
+ moduleCode: "",
+ detailCode: "322016",
+ description: "",
+ solution: "",
+ updateTime: 1522722918000
+ },
+ {
+ moduleCode: "",
+ detailCode: "500103",
+ description: "",
+ solution: "",
+ updateTime: 1522655556000
+ },
+ {
+ moduleCode: "",
+ detailCode: "405999",
+ description: "",
+ solution: "",
+ updateTime: 1522654716000
+ },
+ {
+ moduleCode: "",
+ detailCode: "321032",
+ description: "",
+ solution: "",
+ updateTime: 1522647732000
+ },
+ {
+ moduleCode: "",
+ detailCode: "381101",
+ description: "",
+ solution: "",
+ updateTime: 1522392414000
+ },
+ {
+ moduleCode: "",
+ detailCode: "399999",
+ description: "",
+ solution: "",
+ updateTime: 1522379834000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380103",
+ description: "",
+ solution: "",
+ updateTime: 1522312724000
+ },
+ {
+ moduleCode: "",
+ detailCode: "360014",
+ description: "",
+ solution: "",
+ updateTime: 1522304341000
+ },
+ {
+ moduleCode: "",
+ detailCode: "-1005",
+ description: "",
+ solution: "",
+ updateTime: 1522288195000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395454",
+ description: "",
+ solution: "",
+ updateTime: 1522220180000
+ },
+ {
+ moduleCode: "",
+ detailCode: "100005",
+ description: "",
+ solution: "",
+ updateTime: 1522218849000
+ },
+ {
+ moduleCode: "",
+ detailCode: "100004",
+ description: "",
+ solution: "",
+ updateTime: 1522209053000
+ },
+ {
+ moduleCode: "",
+ detailCode: "106002",
+ description: "",
+ solution: "",
+ updateTime: 1522206200000
+ },
+ {
+ moduleCode: "",
+ detailCode: "410030",
+ description: "",
+ solution: "",
+ updateTime: 1522162252000
+ },
+ {
+ moduleCode: "",
+ detailCode: "-1002",
+ description: "",
+ solution: "",
+ updateTime: 1522150690000
+ },
+ {
+ moduleCode: "",
+ detailCode: "-1200",
+ description: "",
+ solution: "",
+ updateTime: 1522139025000
+ },
+ {
+ moduleCode: "",
+ detailCode: "-1001",
+ description: "",
+ solution: "",
+ updateTime: 1522046436000
+ },
+ {
+ moduleCode: "",
+ detailCode: "-1011",
+ description: "",
+ solution: "",
+ updateTime: 1522045931000
+ },
+ {
+ moduleCode: "",
+ detailCode: "381102",
+ description: "",
+ solution: "",
+ updateTime: 1522044953000
+ },
+ {
+ moduleCode: "",
+ detailCode: "381103",
+ description: "",
+ solution: "",
+ updateTime: 1522044953000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391205",
+ description: "vtdu瑙f瀽鏈嶅姟鍣╥p澶辫触",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391206",
+ description: "vtdu鎻忚堪绗elect澶辫触",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391207",
+ description: "vtdu鏂囦欢鎻忚堪绗︿笉鍦ㄥ彲璇讳腑",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391208",
+ description: "vtdu缃戠粶鍙戠敓閿欒getsockopt",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391209",
+ description: "vtdu鎻忚堪绗elect瓒呮椂",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395000",
+ description: "cas鍥炲淇′护锛屽彂鐜板唴瀛樺凡缁忛噴鏀撅紙鍜岃澶囦箣闂村紓甯告柇寮�锛�",
+ solution: "妫�鏌ヨ澶囩綉缁滐紱鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395400",
+ description: "绉佹湁鍖栧崗璁畍tm妫�娴嬬鏈夊寲鍗忚涓爜娴佺被鍨嬪皬浜�0鎴栬�呰澶囧簭鍒楀彿涓虹┖绛夐潪娉曞弬鏁板満鏅繑鍥�(app涓嶉噸璇曞彇娴�)",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395402",
+ description: "鍥炴斁鎵句笉鍒板綍鍍忔枃浠�",
+ solution: "妫�鏌ユ槸鍚︽湁瀛樺偍鍗″苟涓旀帴瑙﹁壇濂�",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395403",
+ description: "鎿嶄綔鐮佹垨淇′护瀵嗛挜涓庤澶囦笉鍖归厤",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395404",
+ description: "璁惧涓嶅湪绾�",
+ solution: "妫�鏌ヨ澶囩綉缁滐紱閲嶅惎璁惧鎺ュ叆钀ょ煶浜�",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395405",
+ description: "娴佸獟浣撳悜璁惧鍙戦�佹垨鎺ュ彈淇′护瓒呮椂/cas鍝嶅簲瓒呮椂",
+ solution: "妫�鏌ヨ澶囩綉缁滐紱閲嶅惎璁惧",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395406",
+ description: "token澶辨晥",
+ solution: "鍒锋柊閲嶈瘯鎴栬�呴噸鍚澶�",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395407",
+ description: "瀹㈡埛绔殑URL鏍煎紡閿欒",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395409",
+ description: "棰勮寮�鍚殣绉佷繚鎶�",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395410",
+ description: "璁惧杈惧埌鏈�澶ц繛鎺ユ暟",
+ solution: "璇峰崌绾ц澶囧浐浠剁増鏈�",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395411",
+ description: "token鏃犳潈闄�",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395412",
+ description: "session涓嶅瓨鍦� ",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395413",
+ description: "楠岃瘉token鐨勪粬寮傚父锛堜笉鍏蜂綋锛� ",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395415",
+ description: "璁惧閫氶亾閿�",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395451",
+ description: "璁惧涓嶆敮鎸佺殑鐮佹祦绫诲瀷",
+ solution: "鍒锋柊閲嶈瘯鎴栬�呭垏鎹㈠埌楂樻竻妯″紡",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395452",
+ description: "璁惧閾炬帴娴佸獟浣撴湇鍔″櫒澶辫触 ",
+ solution: "妫�鏌ヨ澶囩綉缁滐紝閲嶅惎璁惧锛屽埛鏂伴噸璇�",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395500",
+ description: "鏈嶅姟鍣ㄥ鐞嗗け璐� ",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395501",
+ description: "娴佸獟浣搗tdu杈惧埌鏈�澶ц礋杞斤紝璇锋墿瀹�",
+ solution: "鏈嶅姟鍣ㄨ礋杞借揪鍒颁笂闄愶紝璇风◢鍚庨噸璇�",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395503",
+ description: "vtm杩斿洖鍒嗛厤vtdu澶辫触",
+ solution: "鏈嶅姟鍣ㄨ礋杞借揪鍒颁笂闄愶紝璇风◢鍚庨噸璇�",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395544",
+ description: "璁惧杩斿洖鏃犺棰戞簮 ",
+ solution: "璁惧鏄惁鎺ヨЕ鑹ソ锛�",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395545",
+ description: "瑙嗛鍒嗕韩鏃堕棿宸茬粡缁撴潫",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395546",
+ description: "vtdu杩斿洖杈惧埌鍙栨祦骞跺彂璺暟闄愬埗",
+ solution: "璇峰崌绾т负浼佷笟鐗堬紝鏀惧紑骞跺彂闄愬埗",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395560",
+ description: "铓佸叺浠g悊涓嶆敮鎸佺殑鐢ㄦ埛鍙栨祦绫诲瀷锛屼細閲嶅畾鍚戝埌vtdu鍙栨祦",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395557",
+ description: "鍥炴斁鏈嶅姟鍣ㄧ瓑寰呮祦澶磋秴鏃�",
+ solution: "鍒锋柊閲嶈瘯锛屾娴嬭澶囩綉缁滐紝閲嶅惎璁惧",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395600",
+ description: "鍒嗕韩璁惧涓嶅湪鍒嗕韩鏃堕棿鍐�",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395601",
+ description: "缇ょ粍鍒嗕韩鐢ㄦ埛娌℃潈闄�",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395602",
+ description: "缇ょ粍鍒嗕韩鏉冮檺鍙樻洿",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395556",
+ description: "ticket鍙栨祦楠岃瘉澶辫触",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395530",
+ description: "鏈烘埧鏁呴殰涓嶅彲鐢�",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "395701",
+ description: "cas淇′护杩斿洖鏍煎紡閿欒",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396001",
+ description: "瀹㈡埛绔弬鏁板嚭閿�",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396099",
+ description: "瀹㈡埛绔粯璁ら敊璇�",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396101",
+ description: "涓嶆敮鎸佺殑鍛戒护",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396102",
+ description: "璁惧娴佸ご鍙戦�佸け璐�",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396103",
+ description: "cas/璁惧杩斿洖閿欒1",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396104",
+ description: "cas/璁惧杩斿洖閿欒-1",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396105",
+ description: "璁惧杩斿洖閿欒鐮�3",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396106",
+ description: "璁惧杩斿洖閿欒鐮�4",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396107",
+ description: "璁惧杩斿洖閿欒鐮�5",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396108",
+ description: "cas淇′护鍥炲簲閲嶅",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396109",
+ description: "瑙嗛骞垮満鍙栨秷鍒嗕韩",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396110",
+ description: "璁惧淇′护榛樿閿欒",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396501",
+ description: "璁惧鏁版嵁閾捐矾鍜屽疄闄呴摼璺笉鍖归厤",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396502",
+ description: "璁惧鏁版嵁閾捐矾閲嶅寤虹珛杩炴帴",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396503",
+ description: "璁惧鏁版嵁閾捐矾绔彛涓嶅尮閰�",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396504",
+ description: "缂撳瓨璁惧鏁版嵁閾捐矾澶辫触(鍐呭瓨鍧椾笉瓒�)",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396505",
+ description: "璁惧鍙戦�佺‘璁ゅご娑堟伅閲嶅",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396506",
+ description: "璁惧鏁版嵁鍏堜簬纭畾澶撮儴鍒拌揪",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396508",
+ description: "璁惧鏁版嵁澶撮儴闀垮害闈炴硶",
+ solution: "鍒锋柊閲嶈瘯锛屾垨鑰呴噸鍚澶�",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396509",
+ description: "绱㈠紩鎵句笉鍒拌澶囨暟鎹鐞嗗潡",
+ solution: "鍒锋柊閲嶈瘯",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396510",
+ description: "璁惧鏁版嵁閾捐矾vtdu鍐呭瓨鍧楀崗璁姸鎬佷笉鍖归厤",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396511",
+ description: "璁惧鏁版嵁澶撮儴娌℃湁streamkey閿欒",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396512",
+ description: "璁惧鏁版嵁澶撮儴闈炴硶(杈冪缁�)",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396513",
+ description: "璁惧鏁版嵁闀垮害杩囧皬",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396514",
+ description: "璁惧鑰佸崗璁帹娴佸ご閮ㄦ病鏈塻treamkey閿欒",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396515",
+ description: "璁惧鑰佸崗璁帹娴佹暟鎹潪娉�",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396516",
+ description: "璁惧鑰佸崗璁储寮曟壘涓嶅埌鍐呭瓨绠$悊鍧�",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396517",
+ description: "璁惧鑰佸崗璁帹娴佹暟鎹潪娉�",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396518",
+ description: "璁惧鏁版嵁鍖呰繃澶�",
+ solution: "鍒锋柊閲嶈瘯锛屾垨鑰呴噸鍚澶�",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396519",
+ description: "璁惧鎺ㄦ祦閾捐矾缃戠粶涓嶇ǔ瀹�",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "396520",
+ description: "璁惧鎺ㄦ祦閾捐矾缃戠粶涓嶇ǔ瀹�(榛樿)",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "170003",
+ description: "refreshToken涓嶅瓨鍦�",
+ solution: "寤鸿鐢ㄦ埛閲嶆柊璋冪敤logout鎺ュ彛锛岀劧鍚庤皟鐢╫penLoginPage鎺ュ彛閲嶆柊鍚姩鐧诲綍椤甸潰鐧诲綍",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "170004",
+ description: "refreshToken宸茶繃鏈�",
+ solution: "寤鸿鐢ㄦ埛閲嶆柊璋冪敤logout鎺ュ彛锛岀劧鍚庤皟鐢╫penLoginPage鎺ュ彛閲嶆柊鍚姩鐧诲綍椤甸潰鐧诲綍",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380011",
+ description: "璁惧闅愮淇濇姢涓�",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380045",
+ description: "璁惧鐩磋繛鍙栨祦杩炴帴鏁伴噺杩囧ぇ",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380047",
+ description: "璁惧涓嶆敮鎸佽鍛戒护",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380077",
+ description: "璁惧姝e湪瀵硅涓�",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380102",
+ description: "鏁版嵁鎺ユ敹寮傚父",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380205",
+ description: "璁惧妫�娴嬪叆鍙傚紓甯�",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380209",
+ description: "缃戠粶杩炴帴瓒呮椂",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380212",
+ description: "璁惧绔綉缁滆繛鎺ヨ秴鏃�",
+ solution: "",
+ updateTime: 1522034841000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101007",
+ description: "鎵嬫満鍙锋湭娉ㄥ唽",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120503",
+ description: "姝e湪鍝嶉搩",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390016",
+ description: "vtdu鎴愬姛鍝嶅簲鏈惡甯︽祦澶�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101008",
+ description: "鎵嬫満鍙风爜涓嶅悎娉�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120504",
+ description: "瀹ゅ唴鏈烘鍦ㄩ�氳瘽",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390017",
+ description: "鏃犳暟鎹祦锛屽皻鏈娇鐢�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101009",
+ description: "鐢ㄦ埛鍚嶄笌鎵嬫満涓嶅尮閰�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120505",
+ description: "璁惧鎿嶄綔澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390018",
+ description: "淇′护娑堟伅浣揚B瑙f瀽澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101010",
+ description: "鑾峰彇楠岃瘉鐮佸け璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120506",
+ description: "闈炴硶鍛戒护",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390019",
+ description: "淇′护娑堟伅浣揚B灏佽澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101011",
+ description: "楠岃瘉鐮侀敊璇�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120507",
+ description: "鏅鸿兘閿佸瘑鐮侀敊璇�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390020",
+ description: "鐢宠绯荤粺鍐呭瓨璧勬簮澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101012",
+ description: "楠岃瘉鐮佸け鏁�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120508",
+ description: "寮�鍏抽攣澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390021",
+ description: "vtdu鍦板潃灏氭湭鑾峰彇鍒�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101013",
+ description: "鐢ㄦ埛涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120509",
+ description: "寮�鍏抽攣瓒呮椂",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390022",
+ description: "瀹㈡埛绔皻鏈敮鎸�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101014",
+ description: "瀵嗙爜涓嶆纭垨鑰卆ppKey涓嶆纭�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120510",
+ description: "鏅鸿兘閿佽澶囩箒蹇�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390023",
+ description: "鑾峰彇绯荤粺socket璧勬簮澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101015",
+ description: "鐢ㄦ埛琚攣浣�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120511",
+ description: "杩滅▼寮�閿佸姛鑳芥湭鎵撳紑",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390024",
+ description: "涓婂眰濉厖鐨凷treamSsnId涓嶅尮閰�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101021",
+ description: "楠岃瘉鍙傛暟寮傚父",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120600",
+ description: "涓存椂瀵嗙爜鏁板凡杈句笂闄�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390025",
+ description: "閾炬帴鏈嶅姟鍣ㄥけ璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101026",
+ description: "閭宸茬粡琚敞鍐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120601",
+ description: "娣诲姞涓存椂瀵嗙爜澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390026",
+ description: "瀹㈡埛绔姹傛湭鏀跺埌鏈嶅姟绔簲绛�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101031",
+ description: "閭鏈敞鍐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120602",
+ description: "鍒犻櫎涓存椂瀵嗙爜澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390027",
+ description: "閾捐矾鏂紑",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101032",
+ description: "閭涓嶅悎娉�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120603",
+ description: "璇ヤ复鏃跺瘑鐮佷笉瀛樺湪",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390028",
+ description: "娌℃湁鍙栨祦閾炬帴",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101041",
+ description: "鑾峰彇楠岃瘉鐮佽繃浜庨绻�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120604",
+ description: "鎸囩汗閿佸皠棰戦�氫俊澶辫触,璇风◢鍚庡啀璇�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390029",
+ description: "娴佹垚鍔熷仠姝�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101043",
+ description: "鎵嬫満楠岃瘉鐮佽緭鍏ラ敊璇秴杩囪瀹氭鏁�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120605",
+ description: "鍏朵粬鐢ㄦ埛姝e湪璁よ瘉涓�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390030",
+ description: "瀹㈡埛绔槻涓叉祦鏍¢獙澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "102000",
+ description: "璁惧涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120606",
+ description: "楠岃瘉宸插惎鍔�,璇峰湪120s鍐呰繘琛屾湰鍦伴獙璇佸拰璋冪敤娣诲姞璁惧鎺ュ彛",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390031",
+ description: "搴旂敤灞倀cp绮樺寘澶勭悊缂撳啿鍖烘弧",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "102001",
+ description: "鎽勫儚鏈轰笉瀛樺湪",
+ solution: "鎽勫儚鏈烘湭娉ㄥ唽鍒拌悿鐭充簯骞冲彴锛岃浠旂粏妫�鏌ユ憚鍍忔満鐨勭綉缁滈厤缃紝纭繚杩炴帴鍒扮綉缁�",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120607",
+ description: "鍒犻櫎鐢ㄦ埛澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390032",
+ description: "鏃犳晥鐘舵�佽縼绉�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "102003",
+ description: "璁惧涓嶅湪绾�",
+ solution: "鍙傝�冩湇鍔′腑蹇冩帓鏌ユ柟娉�",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120608",
+ description: "鐢ㄦ埛涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390033",
+ description: "鏃犳晥瀹㈡埛绔姸鎬�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "102004",
+ description: "璁惧寮傚父",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120609",
+ description: "璁惧鍝嶅簲瓒呮椂,闂ㄩ攣閫氫俊鏁呴殰鎴栬�呯數閲忎笉瓒�,璇烽噸璇�.",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390034",
+ description: "鍚憊tm鍙栨祦娴佸獟浣撲俊鎭姹傝秴鏃�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "102007",
+ description: "璁惧搴忓垪鍙蜂笉姝g‘",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120610",
+ description: "鑾峰彇涓存椂瀵嗙爜鍒楄〃澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390035",
+ description: "鍚戜唬鐞嗗彇娴佽姹傝秴鏃�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "102009",
+ description: "璁惧璇锋眰鍝嶅簲瓒呮椂寮傚父",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "130001",
+ description: "鐢ㄦ埛涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390036",
+ description: "鍚戜唬鐞嗕繚娲诲彇娴佽姹傝秴鏃�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "105000",
+ description: "璁惧宸茶鑷繁娣诲姞",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "130002",
+ description: "鎵嬫満鍙风爜宸茬粡娉ㄥ唽",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390037",
+ description: "鍚憊tdu鍙栨祦璇锋眰瓒呮椂",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "105001",
+ description: "璁惧宸茶鍒汉娣诲姞",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "130003",
+ description: "鎵嬫満楠岃瘉鐮侀敊璇�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390038",
+ description: "鍚憊tdu淇濇椿鍙栨祦璇锋眰瓒呮椂",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "105002",
+ description: "璁惧楠岃瘉鐮侀敊璇�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "130004",
+ description: "缁堢缁戝畾鎿嶄綔澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391001",
+ description: "vtm鍦板潃鎴栫鍙i潪娉�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "107001",
+ description: "閭�璇蜂笉瀛樺湪",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "149999",
+ description: "鏁版嵁寮傚父",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391002",
+ description: "vtm鐢熸垚鏂囦欢鎻忚堪绗﹀け璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "107002",
+ description: "閭�璇烽獙璇佸け璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "150000",
+ description: "鏈嶅姟鍣ㄥ紓甯�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391003",
+ description: "vtm璁剧疆鏂囦欢鎻忚堪绗﹂潪闃诲澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "107003",
+ description: "閭�璇风敤鎴蜂笉鍖归厤",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160000",
+ description: "璁惧涓嶆敮鎸佷簯鍙版帶鍒�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391004",
+ description: "vtm璁剧疆鏂囦欢鎻忚堪绗﹂樆濉炲け璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "107004",
+ description: "浜戝瓨鍌ㄨ繛鎺ュけ璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160001",
+ description: "鐢ㄦ埛鏃犱簯鍙版帶鍒舵潈闄�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391005",
+ description: "vtm瑙f瀽鏈嶅姟鍣╥p澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "7005",
+ description: "VTDU涓诲姩鏂紑杩炴帴",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "107005",
+ description: "VTDU涓诲姩鏂紑杩炴帴",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160002",
+ description: "璁惧浜戝彴鏃嬭浆杈惧埌涓婇檺浣�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391006",
+ description: "vtm鎻忚堪绗elect澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "107006",
+ description: "涓嶈兘閭�璇疯嚜宸�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160003",
+ description: "璁惧浜戝彴鏃嬭浆杈惧埌涓嬮檺浣�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391007",
+ description: "vtm鏂囦欢鎻忚堪绗︿笉鍦ㄥ彲璇讳腑",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "107007",
+ description: "閲嶅閭�璇�",
+ solution: "鍒嗕韩鍜屽垹闄ゅ垎浜繀椤诲叏閮ㄧ敱鎺ュ彛褰㈠紡鎿嶄綔锛屽鏋滀笌钀ょ煶瀹㈡埛绔贩鐢ㄤ細閫犳垚杩欎釜闂锛岃В鍐冲姙娉曪細鍦ㄨ悿鐭冲鎴风娓呯┖鎵�鏈夌浉鍏冲垎浜暟鎹苟閲嶆柊娣诲姞璁惧锛屽啀閫氳繃鎺ュ彛鎿嶄綔鍗冲彲",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160004",
+ description: "璁惧浜戝彴鏃嬭浆杈惧埌宸﹂檺浣�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391008",
+ description: "vtm缃戠粶鍙戠敓閿欒getsockopt",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110001",
+ description: "鍙傛暟閿欒",
+ solution: "鍙傛暟涓虹┖鎴栬�呮牸寮忎笉瀵�",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160005",
+ description: "璁惧浜戝彴鏃嬭浆杈惧埌鍙抽檺浣�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391009",
+ description: "vtm鎻忚堪绗elect瓒呮椂",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110002",
+ description: "accessToken寮傚父鎴栬繃鏈�",
+ solution: "accessToken鏈夋晥鏈熶负涓冨ぉ锛屽缓璁湪accessToken鍗冲皢杩囨湡鎴栬�呭嚭鐜�10002閿欒鐮佺殑鏃跺�欓噸鏂拌幏鍙朼ccessToken",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160006",
+ description: "浜戝彴褰撳墠鎿嶄綔澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391101",
+ description: "proxy鍦板潃鎴栫鍙i潪娉�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110004",
+ description: "鐢ㄦ埛涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160007",
+ description: "棰勭疆鐐逛釜鏁拌秴杩囨渶澶у��",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391102",
+ description: "proxy鐢熸垚鏂囦欢鎻忚堪绗﹀け璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110005",
+ description: "appKey寮傚父",
+ solution: "纭appKey鐘舵�侊紝涓嶉�氳繃鎴栬�呭喕缁撶姸鎬佷細杩斿洖璇ラ敊璇爜",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160009",
+ description: "姝e湪璋冪敤棰勭疆鐐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391103",
+ description: "proxy璁剧疆鏂囦欢鎻忚堪绗﹂潪闃诲澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110006",
+ description: "ip鍙楅檺",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160010",
+ description: "璇ラ缃偣宸茬粡鏄綋鍓嶄綅缃�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391104",
+ description: "proxy璁剧疆鏂囦欢鎻忚堪绗﹂樆濉炲け璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160011",
+ description: "棰勭疆鐐逛笉瀛樺湪",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391105",
+ description: "proxy瑙f瀽鏈嶅姟鍣╥p澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110008",
+ description: "绛惧悕閿欒",
+ solution: "鈶犺幏鍙栫鍚嶆柟寮忚瑙乤pidemo鍙奫鏃API鏂囨。 鈶℃敞鎰忕紪鐮佹牸寮忎负UTF-8",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160013",
+ description: "璁惧鐗堟湰宸叉槸鏈�鏂�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391106",
+ description: "proxy鎻忚堪绗elect澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110009",
+ description: "绛惧悕鍙傛暟閿欒",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160014",
+ description: "璁惧姝e湪鍗囩骇",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391107",
+ description: "proxy鏂囦欢鎻忚堪绗︿笉鍦ㄥ彲璇讳腑",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110010",
+ description: "绛惧悕瓒呮椂",
+ solution: "璇疯皟鐢ㄥ悓姝ユ湇鍔″櫒鏃堕棿鎺ュ彛杩涜鏍℃椂",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160015",
+ description: "璁惧姝e湪閲嶅惎",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391108",
+ description: "proxy缃戠粶鍙戠敓閿欒getsockopt",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110011",
+ description: "鏈紑閫氳悿鐭充簯鏈嶅姟",
+ solution: "鍙傜収缁戝畾娴佺▼",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160016",
+ description: "鍔犲瘑鏈紑鍚紝鏃犻』鍏抽棴",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391109",
+ description: "proxy鎻忚堪绗elect瓒呮椂",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110012",
+ description: "绗笁鏂硅处鎴蜂笌钀ょ煶璐﹀彿宸茬粡缁戝畾",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160017",
+ description: "璁惧鎶撳浘澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391201",
+ description: "vtdu鍦板潃鎴栫鍙i潪娉�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110013",
+ description: "搴旂敤娌℃湁鏉冮檺璋冪敤姝ゆ帴鍙�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160018",
+ description: "璁惧鍗囩骇澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391202",
+ description: "vtdu鐢熸垚鏂囦欢鎻忚堪绗﹀け璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110014",
+ description: "APPKEY涓嬪搴旂殑绗笁鏂箄serId鍜宲hone鏈粦瀹�",
+ solution: "鑾峰彇AccessToken鏃舵墍鐢╝ppKey涓嶴DK鎵�鐢╝ppKey涓嶄竴鑷�",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160019",
+ description: "鍔犲瘑宸插紑鍚�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391203",
+ description: "vtdu璁剧疆鏂囦欢鎻忚堪绗﹂潪闃诲澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110017",
+ description: "appKey涓嶅瓨鍦�",
+ solution: "璇峰~鍐欏湪瀹樼綉鐢宠鐨勫簲鐢ㄧ閽�",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160020",
+ description: "涓嶆敮鎸佽鍛戒护",
+ solution: "璇风‘璁よ澶囨槸鍚︽敮鎸佽鍛戒护",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "391204",
+ description: "vtdu璁剧疆鏂囦欢鎻忚堪绗﹂樆濉炲け璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110018",
+ description: "AccessToken涓嶢ppkey涓嶅尮閰�",
+ solution: "璇锋鏌ヨ幏鍙朼ccessToken瀵瑰簲鐨刟ppKey鍜孲DK涓缃殑appKey鏄惁涓�鑷�",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160023",
+ description: "璁㈤槄鎿嶄綔澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110019",
+ description: "瀵嗙爜閿欒",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160024",
+ description: "鍙栨秷璁㈤槄鎿嶄綔澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110020",
+ description: "璇锋眰鏂规硶涓虹┖",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160025",
+ description: "瀹㈡祦缁熻閰嶇疆澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110021",
+ description: "ticket鏍¢獙澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160026",
+ description: "璁惧澶勪簬闅愮閬斀鐘舵��",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110022",
+ description: "閫忎紶鐩殑鍦伴潪娉�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160027",
+ description: "璁惧姝e湪闀滃儚鎿嶄綔",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110024",
+ description: "鏃犻�忎紶鏉冮檺",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160028",
+ description: "璁惧姝e湪閿帶鍔ㄤ綔",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110025",
+ description: "appKey琚姝娇鐢ㄩ�氭槑閫氶亾",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160029",
+ description: "璁惧澶勪簬璇煶瀵硅鐘舵��",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160030",
+ description: "鍗″瘑杈撳叆閿欒娆℃暟杩囧锛�24灏忔椂鍚庡啀杈撳叆",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160031",
+ description: "鍗″瘑淇℃伅涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160032",
+ description: "鍗″瘑鐘舵�佷笉瀵规垨宸茶繃鏈�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160033",
+ description: "鍗″瘑闈炲崠鍝侊紝鍙兘寮�閫氬搴旂殑缁戝畾璁惧",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110030",
+ description: "appKey鍜宎ppSecret涓嶅尮閰�",
+ solution: "璇锋鏌ppKey鍜宎ppSecret鏄惁瀵瑰簲",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160035",
+ description: "璐拱浜戝瓨鍌ㄦ湇鍔″け璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110031",
+ description: "瀛愯处鎴锋垨钀ょ煶鐢ㄦ埛娌℃湁鏉冮檺",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160040",
+ description: "娣诲姞鐨勮澶囦笉鍦ㄥ悓涓�灞�鍩熺綉",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110032",
+ description: "瀛愯处鎴蜂笉瀛樺湪",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160041",
+ description: "娣诲姞鐨勮澶囪鍏朵粬璁惧鍏宠仈鎴栧搷搴旇秴鏃�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110033",
+ description: "瀛愯处鎴锋湭璁剧疆鎺堟潈绛栫暐",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160042",
+ description: "娣诲姞鐨勮澶囧瘑鐮侀敊璇�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110034",
+ description: "瀛愯处鎴峰凡瀛樺湪",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160043",
+ description: "娣诲姞鐨勮澶囪秴鍑烘渶澶ф暟閲�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110035",
+ description: "鑾峰彇瀛愯处鎴稟ccessToken寮傚父",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160044",
+ description: "娣诲姞鐨勮澶囩綉缁滀笉鍙揪瓒呮椂",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110036",
+ description: "瀛愯处鎴疯绂佺敤",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160045",
+ description: "娣诲姞鐨勮澶囩殑IP鍜屽叾浠栭�氶亾鐨処P鍐茬獊",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "110051",
+ description: "鏃犳潈闄愯繘琛屾姄鍥�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160046",
+ description: "娣诲姞鐨勮澶囩殑IP鍜屾湰璁惧鐨処P鍐茬獊",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160047",
+ description: "鐮佹祦绫诲瀷涓嶆敮鎸�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120002",
+ description: "璁惧涓嶅瓨鍦�",
+ solution: "鈶犺澶囨病鏈夋敞鍐屽埌钀ょ煶浜戝钩鍙帮紝璇锋鏌ヤ笅璁惧缃戠粶鍙傛暟锛岀‘淇濊兘姝e父杩炴帴缃戠粶鈶¤澶囧簭鍒楀彿涓嶅瓨鍦�",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160048",
+ description: "甯﹀瓒呭嚭绯荤粺鎺ュ叆甯﹀",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120003",
+ description: "鍙傛暟寮傚父锛孲DK鐗堟湰杩囦綆",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160049",
+ description: "IP鎴栬�呯鍙d笉鍚堟硶",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120004",
+ description: "鍙傛暟寮傚父锛孲DK鐗堟湰杩囦綆",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160050",
+ description: "娣诲姞鐨勮澶囩増鏈笉鏀寔闇�瑕佸崌绾ф墠鑳芥帴鍏�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120005",
+ description: "瀹夊叏璁よ瘉澶辫触锛岄渶杩涜SDK瀹夊叏璁よ瘉",
+ solution: "宸插幓鎺夊畨鍏ㄩ獙璇�",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160051",
+ description: "娣诲姞鐨勮澶囦笉鏀寔鎺ュ叆",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120006",
+ description: "缃戠粶寮傚父",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160052",
+ description: "娣诲姞鐨勮澶囬�氶亾鍙峰嚭閿�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120007",
+ description: "璁惧涓嶅湪绾�",
+ solution: "鍙傝�冩湇鍔′腑蹇冩帓鏌ユ柟娉�",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160053",
+ description: "娣诲姞鐨勮澶囧垎杈ㄧ巼涓嶆敮鎸�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120008",
+ description: "璁惧鍝嶅簲瓒呮椂",
+ solution: "璁惧鍝嶅簲瓒呮椂锛岃妫�娴嬭澶囩綉缁滄垨閲嶈瘯",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160054",
+ description: "娣诲姞鐨勮澶囪处鍙疯閿佸畾",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120009",
+ description: "瀛愯处鍙蜂笉鑳芥坊鍔犺澶�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160055",
+ description: "娣诲姞鐨勮澶囧彇鐮佹祦鍑洪敊",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120010",
+ description: "璁惧楠岃瘉鐮侀敊璇�",
+ solution: "楠岃瘉鐮佸湪璁惧鏍囩涓婏紝鍏綅澶у啓瀛楁瘝锛屾敞鎰忓ぇ灏忓啓",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160056",
+ description: "鍒犻櫎璁惧澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120012",
+ description: "璁惧娣诲姞澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160057",
+ description: "鍒犻櫎鐨勮澶囨湭鍏宠仈",
+ solution: "妫�鏌PC涓嶯VR鏄惁鏈夊叧鑱斿叧绯�",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120013",
+ description: "璁惧宸茶鍒汉娣诲姞",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160060",
+ description: "鍦板潃鏈粦瀹�",
+ solution: "璇峰墠寰�瀹樼綉璁剧疆鐩存挱",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120014",
+ description: "璁惧搴忓垪鍙蜂笉姝g‘",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160061",
+ description: "璐︽埛娴侀噺宸茶秴鍑烘垨鏈喘涔帮紝闄愬埗寮�閫�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120015",
+ description: "璁惧涓嶆敮鎸佽鍔熻兘",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160062",
+ description: "璇ラ�氶亾鐩存挱宸插紑閫�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120016",
+ description: "褰撳墠璁惧姝e湪鏍煎紡鍖�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160063",
+ description: "鐩存挱鏈娇鐢ㄦ垨鐩存挱宸插叧闂�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120017",
+ description: "璁惧宸茶鑷繁娣诲姞",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160070",
+ description: "璁惧涓嶈兘杞Щ缁欒嚜宸�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120018",
+ description: "璇ョ敤鎴蜂笉鎷ユ湁璇ヨ澶�",
+ solution: "纭璁惧鏄惁灞炰簬鐢ㄦ埛",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160071",
+ description: "璁惧涓嶈兘杞Щ锛岃澶囦笌鍏朵粬璁惧瀛樺湪鍏宠仈鍏崇郴",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400001",
+ description: "鍙傛暟涓虹┖",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120019",
+ description: "璁惧涓嶆敮鎸佷簯瀛樺偍鏈嶅姟",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160072",
+ description: "璁惧涓嶈兘杞Щ锛岄�氶亾琚垎浜粰鍏朵粬鐢ㄦ埛鎴栬�呭垎浜埌瑙嗛骞垮満",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400002",
+ description: "鍙傛暟閿欒",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120020",
+ description: "璁惧鍦ㄧ嚎锛岃鑷繁娣诲姞",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160073",
+ description: "浜戝瓨鍌ㄨ浆绉诲け璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400025",
+ description: "璁惧涓嶆敮鎸佸璁�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120021",
+ description: "璁惧鍦ㄧ嚎锛屼絾鏄湭琚敤鎴锋坊鍔�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160080",
+ description: "褰撳墠姝e湪澹版簮瀹氫綅",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400029",
+ description: "娌℃湁鍒濆鍖栨垨璧勬簮琚噴鏀�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120022",
+ description: "璁惧鍦ㄧ嚎锛屼絾鏄凡缁忚鍒殑鐢ㄦ埛娣诲姞",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160081",
+ description: "褰撳墠姝e湪杞ㄨ抗宸¤埅",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400030",
+ description: "json瑙f瀽寮傚父",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120023",
+ description: "璁惧涓嶅湪绾匡紝鏈鐢ㄦ埛娣诲姞",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160082",
+ description: "璁惧姝e湪鍝嶅簲鏈澹版簮瀹氫綅",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400031",
+ description: "缃戠粶寮傚父",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120024",
+ description: "璁惧涓嶅湪绾匡紝浣嗘槸宸茬粡琚埆鐨勭敤鎴锋坊鍔�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160083",
+ description: "褰撳墠姝e湪寮�鍚殣绉侀伄钄�",
+ solution: "璁惧姝e湪鎿嶄綔闅愮閬斀锛屾棤娉曡繘琛屽綋鍓嶆搷浣�",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400032",
+ description: "璁惧淇℃伅寮傚父涓虹┖",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120025",
+ description: "閲嶅鐢宠鍒嗕韩",
+ solution: "纭璁惧鏄惁鐢辨坊鍔犺繃璇ヨ澶囦笖鐢宠杩囧垎浜殑璐︽埛涓嬫槸鍚﹁繕瀛樺湪鍒嗕韩璁板綍",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "160084",
+ description: "褰撳墠姝e湪鍏抽棴闅愮閬斀",
+ solution: "璁惧姝e湪鎿嶄綔闅愮閬斀锛屾棤娉曡繘琛屽綋鍓嶆搷浣�",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400034",
+ description: "鍙栨祦瓒呮椂",
+ solution: "涓�鑸槸鐢变簬缃戠粶鐘跺喌涓嶅ソ瀵艰嚧锛屽彲浠ュ皾璇曚笅璁╃敤鎴烽噸鏂版挱鏀�",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120026",
+ description: "瑙嗛骞垮満涓嶅瓨鍦ㄨ瑙嗛",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "380290",
+ description: "銆�杩炴帴CAS鏈嶅姟鍣ㄥけ璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400035",
+ description: "璁惧宸插姞瀵嗭紝闇�瑕佽緭鍏ラ獙璇佺爜",
+ solution: "鏀跺埌姝ら敊璇爜锛岄渶瑕佽鐢ㄦ埛杈撳叆楠岃瘉鐮佸悗锛岃皟鐢‥ZPlayer.setPlayKey浼犲叆楠岃瘉鐮侊紝骞堕噸鏂拌皟鐢ㄦ挱鏀惧嚱鏁�",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120027",
+ description: "瑙嗛杞爜澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361001",
+ description: "瀵硅鏈嶅姟绔帓闃熻秴鏃�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400036",
+ description: "鎾斁楠岃瘉鐮侀敊璇�",
+ solution: "鏀跺埌姝ら敊璇爜锛岄渶瑕佽鐢ㄦ埛杈撳叆楠岃瘉鐮佸悗锛岃皟鐢‥ZPlayer.setPlayKey浼犲叆楠岃瘉鐮侊紝骞堕噸鏂拌皟鐢ㄦ挱鏀惧嚱鏁�",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120028",
+ description: "璁惧鍥轰欢鍗囩骇鍖呬笉瀛樺湪",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361002",
+ description: "瀵硅鏈嶅姟绔鐞嗚秴鏃�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400037",
+ description: "surfacehold閿欒",
+ solution: "璇锋鏌ユ槸鍚︽槸鎾斁涔嬪墠閿�姣佷簡surface锛屾敹鍒版閿欒涔熷彲浠ラ噸鏂板缓绔媠urface鍚庢挱鏀�",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120029",
+ description: "璁惧涓嶅湪绾匡紝浣嗘槸宸茬粡琚嚜宸辨坊鍔�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361003",
+ description: "璁惧閾炬帴瀵硅鏈嶅姟鍣ㄨ秴鏃�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400100",
+ description: "鏈煡閿欒",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120030",
+ description: "璇ョ敤鎴蜂笉鎷ユ湁璇ヨ棰戝箍鍦鸿棰�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361004",
+ description: "鏈嶅姟鍣ㄥ唴閮ㄩ敊璇�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400200",
+ description: "player sdk鍑洪敊锛岃繖绉嶉敊璇竴鑸紑鍙戣�呬篃鏄棤娉曡В鍐筹紝涓嶅叿浣撳垎绫讳紶鍑猴紝浼犱竴涓粺涓�鐨刬nner閿欒鐮佸嚭鍘�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120031",
+ description: "寮�鍚粓绔粦瀹氾紝纭欢鐗瑰緛鐮侀獙璇佸け璐�",
+ solution: "璇峰湪钀ょ煶瀹㈡埛绔叧闂粓绔粦瀹氾紝鍙傝�冩姝ラ",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361005",
+ description: "瑙f瀽娑堟伅澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400300",
+ description: "鍐呭瓨婧㈠嚭",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120032",
+ description: "璇ョ敤鎴蜂笅閫氶亾涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361006",
+ description: "璇锋眰閲嶅畾鍚�--闇�瑕佸悜鍏朵粬鏈嶅姟鐢宠瀵硅",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400901",
+ description: "璁惧涓嶅湪绾匡紝鍙互鎻愮ず鐢ㄦ埛",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120033",
+ description: "鏃犳硶鏀惰棌鑷繁鍒嗕韩鐨勮棰�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361007",
+ description: "璇锋眰url闈炴硶",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400902",
+ description: "accesstoken寮傚父鎴栧け鏁堬紝闇�瑕侀噸鏂拌幏鍙朼ccesstoken锛屽苟浼犲叆鍒皊dk",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120034",
+ description: "璇ョ敤鎴蜂笅鏃犺澶�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361008",
+ description: "token澶辨晥",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400903",
+ description: "褰撳墠璐﹀彿寮�鍚簡缁堢缁戝畾锛屽彧鍏佽鎸囧畾璁惧鐧诲綍鎿嶄綔锛屾彁绀虹敤鎴风櫥褰昳.ys7.com瑙i櫎缁堢缁戝畾",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120090",
+ description: "鐢ㄦ埛鍙嶉澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361009",
+ description: "璁惧楠岃瘉鐮佹垨鑰呴�氫俊绉橀挜涓嶅尮閰�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400904",
+ description: "璁惧姝e湪瀵硅涓�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120095",
+ description: "APP鍖呬笅杞藉け璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361010",
+ description: "璁惧宸茬粡鍦ㄥ璁�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "400905",
+ description: "璁惧寮�鍚簡闅愮淇濇姢锛屼笉鍏佽棰勮銆佸璁茬瓑",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120096",
+ description: "APP鍖呬俊鎭垹闄ゅけ璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361011",
+ description: "璁惧10s鍝嶅簲瓒呮椂",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120101",
+ description: "瑙嗛涓嶆敮鎸佸垎浜粰鏈汉",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361012",
+ description: "璁惧涓嶅湪绾�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320002",
+ description: "鍙傛暟鏃犳晥",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120102",
+ description: "鏃犵浉搴旈個璇蜂俊鎭�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361013",
+ description: "璁惧寮�鍚殣绉佷繚鎶ゆ嫆缁濆璁�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320003",
+ description: "鏆備笉鏀寔姝ゆ搷浣�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120103",
+ description: "濂藉弸宸插瓨鍦�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361014",
+ description: "token鏃犳潈闄�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320004",
+ description: "鍐呭瓨婧㈠嚭",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120104",
+ description: "濂藉弸涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361015",
+ description: "璁惧杩斿洖session涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320005",
+ description: "鍒涘缓CAS session澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120105",
+ description: "濂藉弸鐘舵�侀敊璇�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361016",
+ description: "楠岃瘉token鍏朵粬寮傚父閿欒",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320006",
+ description: "鍒涘缓cloud session澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120106",
+ description: "瀵瑰簲缇ょ粍涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361017",
+ description: "鏈嶅姟绔洃鍚澶囧缓绔嬬鍙h秴鏃�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320007",
+ description: "token澶辨晥",
+ solution: "閲嶆柊璁剧疆token鍚庡啀閲嶈瘯",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120107",
+ description: "涓嶈兘娣诲姞鑷繁涓哄ソ鍙�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361018",
+ description: "璁惧閾捐矾寮傚父",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320008",
+ description: "token姹犻噷闈㈡病鏈塼oken,璇蜂紶鍏oken",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120108",
+ description: "褰撳墠鐢ㄦ埛鍜屾墍娣诲姞鐢ㄦ埛涓嶆槸濂藉弸鍏崇郴",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361019",
+ description: "瀵硅鏈嶅姟绔笉鏀寔鐨勪俊浠ゆ秷鎭�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320009",
+ description: "浼犲叆鏂扮殑INIT_PARAM骞秗eset(淇濈暀锛岀洰鍓嶆湭鐢�)",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120109",
+ description: "瀵瑰簲鍒嗕韩涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361020",
+ description: "瀵硅鏈嶅姟绔В鏋愬璁茶姹傛湭鎼哄甫浼氳瘽鎻忚堪鑳藉姏闆�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320010",
+ description: "璇烽噸璇�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120110",
+ description: "濂藉弸缇ょ粍涓嶅睘浜庡綋鍓嶇敤鎴�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361021",
+ description: "瀵硅鏈嶅姟绔紭鍏堣兘鍔涢泦缁撴灉涓虹┖",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320011",
+ description: "500姣鍚庤閲嶈瘯",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120111",
+ description: "濂藉弸涓嶆槸绛夊緟楠岃瘉鐘舵��",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361022",
+ description: "cas閾捐矾寮傚父",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320012",
+ description: "token姹犲凡婊�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120112",
+ description: "娣诲姞搴旂敤涓嬬殑鐢ㄦ埛涓哄ソ鍙嬪け璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361023",
+ description: "瀵硅鏈嶅姟绔垎閰嶅璁蹭細璇濊祫婧愬け璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320013",
+ description: "P2P client瓒呰繃闄愬埗",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120201",
+ description: "鎿嶄綔鎶ヨ淇℃伅澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "361024",
+ description: "瀵硅鏈嶅姟绔В鏋愪俊浠ゆ秷鎭け璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320014",
+ description: "sdk鏈垵濮嬪寲",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120202",
+ description: "鎿嶄綔鐣欒█淇℃伅澶辫触",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390001",
+ description: "閫氱敤閿欒杩斿洖",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320015",
+ description: "瓒呮椂",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120301",
+ description: "鏍规嵁UUID鏌ヨ鎶ヨ娑堟伅涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390002",
+ description: "鍏ュ弬涓虹┖鎸囬拡",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320016",
+ description: "姝e湪鎵撴礊涓�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120302",
+ description: "鏍规嵁UUID鏌ヨ鍥剧墖涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390003",
+ description: "鍏ュ弬鍊兼棤鏁�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320017",
+ description: "娌℃湁瑙嗛鏂囦欢澶�(鎾斁鍣ㄥ眰闈骇鐢熷拰澶勭悊姝ら敊璇�)",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120303",
+ description: "鏍规嵁FID鏌ヨ鍥剧墖涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390004",
+ description: "淇′护娑堟伅瑙f瀽闈炴硶",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320018",
+ description: "瑙g爜閿欒/瓒呮椂(鎾斁鍣ㄥ眰闈骇鐢熷拰澶勭悊姝ら敊璇�)",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120305",
+ description: "璁惧ip瑙f瀽閿欒",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390005",
+ description: "鍐呭瓨璧勬簮涓嶈冻",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320019",
+ description: "鍙栨秷(淇濈暀锛岀敤鎴蜂笉鐢ㄥ鐞�)",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120401",
+ description: "鐢ㄦ埛浜戠┖闂翠俊鎭笉瀛樺湪",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390006",
+ description: "鍗忚鏍煎紡涓嶅鎴栬�呮秷鎭綋闀垮害瓒呰繃STREAM_MAX_MSGBODY_LEN",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320020",
+ description: "鎾斁杩囩▼涓杩炴帴琚敤鎴锋竻闄ら鎿嶄綔淇℃伅",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120402",
+ description: "浜戠┖闂存搷浣滃け璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390007",
+ description: "璁惧搴忓垪鍙烽暱搴︿笉鍚堟硶",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320021",
+ description: "娴佸姞瀵嗙爜涓嶅",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120403",
+ description: "鐢ㄦ埛鐩綍涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390008",
+ description: "鍙栨祦url闀垮害涓嶅悎娉�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "320022",
+ description: "鏈紶鍏ユ挱鏀剧獥鍙�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120404",
+ description: "瑕佹搷浣滅殑鐩爣鐩綍涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390009",
+ description: "瑙f瀽vtm杩斿洖vtdu鍦板潃涓嶅悎娉�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "100200",
+ description: "鎿嶄綔鎴愬姛",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120405",
+ description: "瑕佸垹闄ょ殑鏂囦欢淇℃伅涓嶅瓨鍦�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390010",
+ description: "瑙f瀽vtm杩斿洖绾ц仈vtdu鍦板潃涓嶅悎娉�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101001",
+ description: "鐢ㄦ埛鍚嶄笉鍚堟硶",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120406",
+ description: "宸插紑閫氫簯瀛樺偍",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390011",
+ description: "瑙f瀽vtm杩斿洖浼氳瘽鏍囪瘑闀垮害涓嶅悎娉�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101002",
+ description: "鐢ㄦ埛鍚嶅凡琚崰鐢�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120407",
+ description: "寮�閫氳褰曞け璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390012",
+ description: "vtdu杩斿洖娴佸ご闀垮害涓嶅悎娉�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101003",
+ description: "瀵嗙爜涓嶅悎娉�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120500",
+ description: "鑾峰彇鏁版嵁閿欒",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390013",
+ description: "vtdu浼氳瘽闀垮害闈炴硶",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101004",
+ description: "瀵嗙爜涓哄悓涓�瀛楃",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120501",
+ description: "寮�閿佸け璐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390014",
+ description: "鍥炶皟鍑芥暟鏈敞鍐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "101006",
+ description: "鎵嬫満鍙风爜宸茬粡琚敞鍐�",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "120502",
+ description: "瀹ゅ唴鏈烘湭鏀跺埌鍛煎彨",
+ solution: "",
+ updateTime: 1522034840000
+ },
+ {
+ moduleCode: "",
+ detailCode: "390015",
+ description: "vtdu鎴愬姛鍝嶅簲鏈惡甯︿細璇濇爣璇�",
+ solution: "",
+ updateTime: 1522034840000
+ }
+];
+var code = "200";
+var msg$1 = "鎿嶄綔鎴愬姛!";
+var errorCode = {
+ data: data$8,
+ code: code,
+ msg: msg$1
+};
+
+var Code = /*#__PURE__*/function () {
+ function Code(x, y) {
+ _classCallCheck$1(this, Code);
+
+ this.coreX = x;
+ this.coreY = y;
+ console.log("ErrorCode", errorCode);
+ }
+
+ _createClass$1(Code, [{
+ key: "toString",
+ value: function toString() {
+ return "".concat(this.coreX, "-").concat(this.coreY);
+ }
+ }, {
+ key: "matchErrorInfo",
+ value: function matchErrorInfo(code) {
+ return errorCode.data.find(function (item) {
+ return item.detailCode.substr(-4) == code;
+ });
+ }
+ }]);
+
+ return Code;
+}();
+
+var header = {
+ color: "red",
+ backgroundColor: "red",
+ activeColor: "red",
+ btnList: [
+ {
+ btnKey: "ade5d065a113432e8091a1c5bc819c57-934f270c08b14e928bf0c2ae8e1a937d-header-0",
+ iconId: "deviceID",
+ part: "left",
+ defaultActive: 1,
+ isrender: 1,
+ themeId: "934f270c08b14e928bf0c2ae8e1a937d"
+ },
+ {
+ btnKey: "ade5d065a113432e8091a1c5bc819c57-934f270c08b14e928bf0c2ae8e1a937d-header-1",
+ iconId: "deviceName",
+ part: "left",
+ defaultActive: 1,
+ isrender: 1,
+ themeId: "934f270c08b14e928bf0c2ae8e1a937d"
+ }
+ ]
+};
+var footer = {
+ color: "blue",
+ backgroundColor: "blue",
+ activeColor: "blue",
+ btnList: [
+ {
+ btnKey: "ade5d065a113432e8091a1c5bc819c57-934f270c08b14e928bf0c2ae8e1a937d-footer-0",
+ iconId: "play",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0,
+ themeId: "934f270c08b14e928bf0c2ae8e1a937d"
+ }
+ ]
+};
+var defaultTheme = {
+ header: header,
+ footer: footer
+};
+
+// 閫氱敤璇锋眰鏂规硶
+
+var TimeLine$1 = function TimeLine(jsPlugin) {
+ this.jsPlugin = jsPlugin;
+ var status = {
+ isMouseDown: false,
+ // 榧犳爣鏄惁鎸変笅
+ isOver: false,
+ // 榧犳爣鏄惁鎮诞鍦ㄨ繘搴︽潯涓�
+ mousePosition: null,
+ oldTime: null,
+ nowTime: null,
+ moved: null,
+ hoverTime: '2018-12-07 12:00:00',
+ hoverLeft: 0,
+ timeTipShow: false,
+ randomNum: 123,
+ timeWidthTbls: [60, 1800, 3600, 86400],
+ // 鏃堕棿瀹藉害鍗曚綅锛堢锛�
+ timeUnits: ['鑼冨洿: 1鍒嗛挓; 鍗曚綅: 绉�', '鑼冨洿: 30鍒嗛挓; 鍗曚綅: 鍒嗛挓', '鑼冨洿: 1灏忔椂; 鍗曚綅: 鍒嗛挓', '鑼冨洿: 1澶�; 鍗曚綅: 灏忔椂', '鑼冨洿: 3澶�; 鍗曚綅: 灏忔椂'],
+ // 鏃堕棿鍗曚綅
+ drawPen: null,
+ timeSection: [],
+ canvasWidth: null,
+ canvasHeight: null,
+ timeTips: null
+ }; // Object.keys(status).forEach(element => {
+ // this[element] = status[element];
+ // });
+
+ var _this = this;
+
+ Object.keys(status).forEach(function (element) {
+ _this[element] = status[element];
+ });
+ this.options = {
+ width: this.canvasWidth,
+ height: 48,
+ time: new Date().getTime(),
+ //new Date("2019-10-31 00:00:00"),//
+ timeSection: [],
+ timeWidth: 0 // 0-3
+
+ };
+
+ TimeLine.prototype.subTime = function (time) {
+ if (time < 10) {
+ return '0' + time;
+ } else {
+ return time;
+ }
+ };
+
+ TimeLine.prototype.tranTime = function (time) {
+ var stringTime = time;
+
+ if (time) {
+ var newDate = new Date(time);
+ stringTime = newDate.getFullYear() + '/' + (newDate.getMonth() + 1) + '/' + newDate.getDate() + ' ' + this.subTime(newDate.getHours()) + ':' + this.subTime(newDate.getMinutes()) + ':' + this.subTime(newDate.getSeconds());
+ }
+
+ return stringTime;
+ };
+
+ TimeLine.prototype.init = function (params) {
+ // document.getElementsByTagName("html")[0].addEventListener("mouseup", this.mouseUpFn(e,params.));
+ if (params.width) {
+ document.getElementById(params.id).setAttribute("width", parseInt(params.width, 10) + 'px');
+ }
+
+ var that = this;
+ var opts = this.options;
+ that.randomNum = (Math.random() + '').split('.').join('');
+ that.timeWidthTblIndex = opts.timeWidth; // 褰撳墠浣跨敤鏃堕棿瀹藉害绱㈠紩
+ // 12-10
+ //that.drawPanal = this.$refs.drawPanal;
+
+ var canvas = document.querySelector("#".concat(this.jsPlugin.id, "-canvas"));
+ that.drawPen = canvas.getContext('2d');
+ that.nowTime = opts.time || Date.now(); // 褰撳墠鏃堕棿鐐�
+
+ that.timeSection = opts.timeSection || []; // 鏃堕棿娈佃褰曞尯闂�
+
+ that.canvasWidth = canvas.offsetWidth;
+ that.canvasHeight = canvas.offsetHeight;
+ that.updata(); // 灞曠ず杩涘害鏉�
+ // 浜嬩欢鐩戝惉
+
+ document.getElementById("".concat(this.jsPlugin.id, "-canvas")).addEventListener('mousemove', function (e) {
+ if (that.options.readOnly) {
+ return;
+ }
+
+ that.mousemove(e);
+ });
+ document.getElementById("".concat(this.jsPlugin.id, "-canvas")).addEventListener('mouseover', function (e) {
+ if (that.options.readOnly) {
+ return;
+ }
+
+ that.mouseover(e);
+ });
+ document.getElementById("".concat(this.jsPlugin.id, "-canvas")).addEventListener('mouseleave', function (e) {
+ if (that.options.readOnly) {
+ return;
+ }
+
+ that.mouseleave(e);
+ });
+ document.getElementById("".concat(this.jsPlugin.id, "-canvas")).addEventListener('mousedown', function (e) {
+ if (that.options.readOnly) {
+ return;
+ }
+
+ that.mousedown(e);
+ });
+ document.getElementById("".concat(this.jsPlugin.id, "-canvas")).addEventListener('mouseup', function (e) {
+ if (that.options.readOnly) {
+ return;
+ } //debugger
+
+
+ var callback = params.onChange;
+ that.mouseUpFn(e, callback);
+ });
+ };
+
+ TimeLine.prototype.mousemove = function (e) {
+ // console.log("榧犳爣绉诲姩",e)
+ if (this.isMouseDown && this.isOver) {
+ var mouseOffset = this.mousePosition - e.pageX; // fix鐐瑰嚮寮曡捣mousemove鐨勯棶棰�
+
+ if (mouseOffset === 0) {
+ return;
+ }
+
+ var timeOffsetUnit = 0;
+
+ switch (this.timeWidth) {
+ case 60:
+ timeOffsetUnit = 1 / 10;
+ break;
+
+ case 1800:
+ timeOffsetUnit = 1 / 20 * 60;
+ break;
+
+ case 3600:
+ timeOffsetUnit = 1 / 20 * 60;
+ break;
+
+ case 86400:
+ //timeOffset =
+ timeOffsetUnit = 1 / 30 * 60 * 60;
+ break;
+ }
+
+ var currentTime = new Date(this.oldTime).getTime() + mouseOffset * timeOffsetUnit * 1000; //console.log("rurrentTime",this.oldTime,mouseOffset,currentTime,new Date(currentTime))
+ //console.log("currentTime", new Date(currentTime))
+ // var currentTime =
+ // this.oldTime +
+ // (mouseOffset / this.canvasWidth) *
+ // this.timeWidth *
+ // 1000;
+ // console.log("currentTime",new Date(this.oldTime), new Date(currentTime))
+
+ this.updata({
+ time: currentTime
+ });
+ this.moved = true;
+ } else {
+ // 12-10
+ //var { left, top } = this.$utils.getOffset(this.$refs.drawPanal);
+ var left = parseInt(document.getElementById("".concat(this.jsPlugin.id, "-canvas-container")).offsetLeft, 10); //12 -10
+
+ this.mousePosition = e.pageX - left;
+ this.updata(); // 鏇存柊鐢婚潰
+ }
+ };
+
+ TimeLine.prototype.mousedown = function (e) {
+ this.isMouseDown = true;
+ this.mousePosition = e.pageX;
+ this.oldTime = this.nowTime; // this.$emit('drag', true);
+ };
+
+ TimeLine.prototype.mouseover = function (e) {
+ this.isOver = true;
+ };
+
+ TimeLine.prototype.mouseleave = function (e) {
+ this.isOver = false;
+ this.isMouseDown = false;
+ this.updata();
+ };
+
+ TimeLine.prototype.changeSize = function (timeWidth) {
+ console.log("changeSize", timeWidth); // if (w) {
+ // this.options.width = w;
+ // this.canvasWidth = w;
+ // }
+ // if (h) {
+ // this.options.height = h;
+ // this.canvasHeight = h;
+ // }
+ // console.log("tehis.optiosn",this.options)
+
+ this.options.timeWidth = timeWidth;
+ this.updata({
+ timeWidth: timeWidth
+ }); // this.$nextTick(() => {
+ // this.updata();
+ // });
+ };
+
+ TimeLine.prototype.mouseUpFn = function (e, callback) {
+ if (this.isMouseDown) {
+ this.isMouseDown = false;
+
+ if (this.moved) {
+ this.moved = false; // 闄愬埗鎷栧姩鍙洿鏀规椂鍒嗙
+
+ var newStringTime = // new Date(this.nowTime).getFullYear() +
+ // '/' +
+ // ( new Date(this.nowTime).getMonth() + 1) +
+ // '/' +
+ // new Date(this.nowTime).getDate() +
+ // ' ' +
+ this.subTime(new Date(this.nowTime).getHours()) + ':' + this.subTime(new Date(this.nowTime).getMinutes()) + ':' + this.subTime(new Date(this.nowTime).getSeconds());
+ var oldStringTime = new Date(this.oldTime).getFullYear() + '/' + (new Date(this.oldTime).getMonth() + 1) + '/' + new Date(this.oldTime).getDate(); // ' ' +
+ // this.subTime(new Date(this.oldTime).getHours()) +
+ // ':' +
+ // this.subTime( new Date(this.oldTime).getMinutes()) +
+ // ':' +
+ // this.subTime( new Date(this.oldTime).getSeconds());
+ // this.nowTime = new Date(`${oldStringTime.substring(0,11) + newStringTime.substring(11,19)}`).getTime();
+
+ this.nowTime = new Date("".concat(oldStringTime, " ").concat(newStringTime));
+ this.updata({
+ time: this.nowTime
+ });
+ this.oldTime = this.nowTime;
+ console.log("nowTime", new Date(this.nowTime), "".concat(oldStringTime, " ").concat(newStringTime)); // 闄愬埗鍙兘鎷栧姩褰撳ぉ;
+
+ callback(this.nowTime);
+ }
+ }
+ };
+
+ TimeLine.prototype.readOnly = function (data) {
+ console.log("鏇存敼涓哄彧璇�");
+ this.options.readOnly = true;
+ document.getElementById("".concat(this.jsPlugin.id, "-canvas")).style.cursor = "not-allowed";
+ };
+
+ TimeLine.prototype.unReadOnly = function (data) {
+ console.log("鏇存敼涓哄彧璇�");
+ this.options.readOnly = false;
+ document.getElementById("".concat(this.jsPlugin.id, "-canvas")).style.cursor = "pointer";
+ };
+
+ TimeLine.prototype.run = function (data) {
+ if (!this.isMouseDown) {
+ this.updata(data);
+ }
+ };
+
+ TimeLine.prototype.getTime = function (data) {
+ console.log("this", this);
+ console.log("褰撳墠鏃堕棿", new Date(this.nowTime));
+ };
+
+ TimeLine.prototype.updata = function (data) {
+ var that = this;
+ data = data || {};
+ that.nowTime = data.time || that.nowTime;
+ that.timeSection = data.timeSection || that.timeSection;
+ that.timeWidthTblIndex = data.timeWidth || that.timeWidthTblIndex;
+ that.timeWidth = that.timeWidthTbls[data.timeWidth || that.timeWidthTblIndex];
+ that.timeUnit = that.timeUnits[data.timeWidth || that.timeWidthTblIndex];
+
+ if (data.timeWidth === 0) {
+ that.timeWidthTblIndex = 0;
+ that.timeWidth = that.timeWidthTbls[0];
+ that.timeUnit = that.timeUnits[0];
+ }
+
+ that.drawPen.fillStyle = '#000000';
+ that.drawPen.fillRect(0, 0, that.canvasWidth, that.canvasHeight);
+ that.drawScale(); // 鐢诲埢搴�
+
+ that.drawRecord(); // 鐢诲綍鍍忓尯闂�
+
+ that.drawOtherMsg(); // 鐢诲綍鍍忕殑鍏朵粬淇℃伅
+ // 12-10
+ //that.$emit('update-time', that.nowTime);
+
+ document.getElementById("".concat(this.jsPlugin.id, "-canvas-container")).style.width = this.options.width + 'px';
+ document.getElementById("".concat(this.jsPlugin.id, "-canvas")).style.width = this.options.width + 'px';
+ document.getElementById("".concat(this.jsPlugin.id, "-canvas-container")).style.height = this.options.height + 'px';
+ document.getElementById("".concat(this.jsPlugin.id, "-canvas")).style.height = this.options.height + 'px';
+ };
+
+ TimeLine.prototype.drawSolidLine = function (startX, startY, endX, endY, lineWidth, color) {
+ this.drawPen.save();
+ this.drawPen.strokeStyle = color;
+ this.drawPen.lineWidth = lineWidth;
+ this.drawPen.beginPath();
+ this.drawPen.moveTo(startX, startY);
+ this.drawPen.lineTo(endX, endY);
+ this.drawPen.stroke();
+ this.drawPen.restore();
+ };
+
+ TimeLine.prototype.drawString = function (text, x, y, aling, color) {
+ this.drawPen.font = '12px serif';
+ this.drawPen.fillStyle = '#ffffff';
+ this.drawPen.textAlign = aling || 'left';
+ this.drawPen.fillText(text, x, y + 10);
+ };
+
+ TimeLine.prototype.drawScale = function () {
+ // console.log("drawScale",new Date(this.nowTime))
+ var that = this;
+ var lineColor = 'rgba(255,255,255)'; //that.nowTime = new Date("2019-12-31 01:50:00")
+
+ var startDate = new Date(that.nowTime); // 寮�濮嬫椂闂�
+
+ var startYears = startDate.getFullYear(); // 璧峰鐨勭鏁�
+
+ var starSecond = startDate.getSeconds(); // 璧峰鐨勭鏁�
+
+ var starMin = startDate.getMinutes(); // 璧峰鐨勫垎閽熸暟
+
+ var startHours = startDate.getHours(); // 璧峰鐨勫皬鏃�
+
+ var startDay = startDate.getDate(); // 璧峰鐨勬棩鏈�
+ // debugger;
+
+ var curScale = 0; // 璁$畻鏃堕棿鐐�
+
+ switch (that.timeWidth) {
+ case 60:
+ {
+ // debugger
+ var dotNum = parseInt(that.canvasWidth / 10); // 姣�10鍍忕礌涓�涓偣
+
+ startDate.setSeconds(startDate.getSeconds() - parseInt(dotNum / 2, 10)); // 浠庣幇鍦ㄦ椂闂寸殑涓�鍗婂紑濮嬬敾璧�
+
+ startDay = startDate.getDate();
+ startHours = startDate.getHours();
+ starMin = startDate.getMinutes();
+ starSecond = startDate.getSeconds(); // console.log("domNum",dotNum);
+ // console.log("starSecond",starSecond)
+
+ for (var i = 0; i < dotNum; i++) {
+ curScale = starSecond + i;
+ startDate.setSeconds(curScale); // debugger;
+ //debugger;
+ // console.log("startDate",startDate,curScale)
+ // 姣忎竴涓暣10绉掔敾涓�娆$嚎鍜屾枃瀛�
+
+ if (curScale % 10 === 0) {
+ that.drawSolidLine(i * that.canvasWidth / dotNum, 8, i * that.canvasWidth / dotNum, that.canvasHeight / 5 + 8, 1, lineColor);
+ var timeString = this.subTime(startDate.getHours()) + ':' + this.subTime(startDate.getMinutes()) + ':' + this.subTime(startDate.getSeconds());
+ that.drawString(timeString, i * that.canvasWidth / dotNum, that.canvasHeight / 5 * 2.5, 'center', 'rgba(255,255,255,0.3)'); // console.log("timeString",timeString)
+ } else {
+ // console.log("鐢荤煭绾�",(i * that.canvasWidth) / 60,0,(i * that.canvasWidth) / 60,(that.canvasHeight / 5) * 0.5,1)
+ // 鍙敾涓�娆$嚎
+ that.drawSolidLine(i * that.canvasWidth / dotNum, 8, i * that.canvasWidth / dotNum, that.canvasHeight / 5 * 0.5 + 8, 1, lineColor);
+ }
+ /**
+ * 鍋忕Щ璺濈瓒呰繃60锛宻etSeconds浼氭瘡娆$疮鍔�1鍒板垎閽燂紝鍥犳缁樺浘瀹屾垚鍚庨渶瑕佸鍘熷埌褰撳墠鍒嗛挓锛屽啀娆¤绠楀亸绉�
+ */
+
+
+ startDate.setDate(startDay);
+ startDate.setHours(startHours);
+ startDate.setMinutes(starMin);
+ }
+
+ break;
+ }
+
+ case 1800:
+ {
+ // 30鍒嗛挓
+ var dotNum = parseInt(that.canvasWidth / 20); // 姣�10鍍忕礌涓�涓偣
+
+ startDate.setMinutes(startDate.getMinutes() - parseInt(dotNum / 2, 10)); // starSecond = startDate.getSeconds();
+
+ startHours = startDate.getHours();
+ starMin = startDate.getMinutes(); //console.log("dotNum",dotNum,starMin)
+
+ for (var i = 0; i <= dotNum; i++) {
+ curScale = starMin + i;
+ startDate.setMinutes(curScale);
+
+ if (curScale % 5 === 0) {
+ that.drawSolidLine(i * that.canvasWidth / dotNum, 8, i * that.canvasWidth / dotNum, that.canvasHeight / 5 * 1.5 + 8, 1, lineColor);
+ var timeString = this.subTime(startDate.getHours()) + ':' + this.subTime(startDate.getMinutes());
+ that.drawString(timeString, i * that.canvasWidth / dotNum, that.canvasHeight / 5 * 2.5, 'center', 'rgba(255,255,255,0.3)');
+ } else {
+ // console.log("鐢荤煭绾�",((i - starMin) * that.canvasWidth) / dotNum)
+ that.drawSolidLine(i * that.canvasWidth / dotNum, 8, i * that.canvasWidth / dotNum, that.canvasHeight / 5 * 0.5 + 8, 1, lineColor);
+ }
+
+ startDate.setHours(startHours);
+ }
+
+ break;
+ }
+
+ case 3600:
+ {
+ // 60鍒嗛挓
+ var dotNum = parseInt(that.canvasWidth / 20); // 姣�10鍍忕礌涓�涓偣
+
+ startDate.setMinutes(startDate.getMinutes() - parseInt(dotNum / 2, 10));
+ startHours = startDate.getHours();
+ starMin = startDate.getMinutes();
+
+ for (var i = 0; i <= dotNum; i++) {
+ curScale = starMin + i; // if (curScale > 60) {
+ // curScale = curScale - 60;
+ // }
+
+ startDate.setMinutes(curScale);
+
+ if (curScale % 10 === 0) {
+ that.drawSolidLine(i * that.canvasWidth / dotNum, 8, i * that.canvasWidth / dotNum, that.canvasHeight / 5 * 1.5 + 8, 1, lineColor);
+ var timeString = this.subTime(startDate.getHours()) + ':' + this.subTime(startDate.getMinutes());
+ that.drawString(timeString, i * that.canvasWidth / dotNum, that.canvasHeight / 5 * 2.5, 'center', 'rgba(255,255,255,0.3)');
+ } else {
+ that.drawSolidLine(i * that.canvasWidth / dotNum, 8, i * that.canvasWidth / dotNum, that.canvasHeight / 5 * 0.5 + 8, 1, lineColor);
+ }
+
+ startDate.setHours(startHours);
+ }
+
+ break;
+ }
+
+ case 86400:
+ {
+ var dotNum = parseInt(that.canvasWidth / 30); // 姣�10鍍忕礌涓�涓偣
+ // 1澶╋紝24灏忔椂
+ //console.log("dotNum",dotNum);
+ //startDate.setDate(startDay - parseInt(dotNum / 2,10));
+
+ startDate.setHours(startDate.getHours() - parseInt(dotNum / 2, 10)); // console.log("startDat111e",startDate);
+ // debugger;
+
+ starSecond = startDate.getSeconds();
+ starMin = startDate.getMinutes();
+ startHours = startDate.getHours();
+ startDay = startDate.getDate();
+ startYears = startDate.getFullYear();
+
+ for (var i = 0; i <= dotNum; i++) {
+ curScale = startHours + i; // if (curScale >= 24) {
+ // curScale = curScale - 24;
+ // }
+
+ startDate.setHours(curScale);
+ var timeString; // 涓嶇瓑浜�24鐨勬椂鍊欙紝鐢荤煭绾�
+ //console.log("curScale",curScale)
+ //if (curScale % 24 !=0) {
+ // console.log("curScale",curScale)
+
+ timeString = this.subTime(startDate.getHours()) + ":00"; // timeString = startDate.toLocaleDateString();
+ // debugger
+
+ that.drawSolidLine(i * that.canvasWidth / dotNum, 8, i * that.canvasWidth / dotNum, that.canvasHeight / 5 * 0.5 + 8, 1, lineColor); // } else {
+ // // debugger;
+ // // console.log("鐢诲浘")
+ // // 涓嶇瓑浜�24鐨勬椂鍊欙紝鐢婚暱绾�
+ // timeString = startDate.toLocaleDateString();
+ // // console.log("startDatestartDate",startDate,i)
+ // // debugger;
+ // that.drawSolidLine(
+ // ((i ) * that.canvasWidth) /
+ // dotNum,
+ // 8,
+ // ((i) * that.canvasWidth) /
+ // dotNum,
+ // (that.canvasHeight / 5) * 1 + 8,
+ // 1,
+ // lineColor
+ // );
+ // }
+ // 姣�2涓皬鏃朵竴涓椂闂存枃瀛�
+
+ if (curScale % 2 === 0) {
+ that.drawString(timeString, i * that.canvasWidth / dotNum, that.canvasHeight / 5 * 2, 'center', 'rgba(255,255,255,0.3)');
+ }
+
+ startDate.setFullYear(startYears);
+ startDate.setDate(startDay);
+ startDate.setHours(startHours);
+ }
+
+ break;
+ }
+ }
+ };
+
+ TimeLine.prototype.getRecord = function (timeArr, startTime, endTime) {
+ this.timeSection = timeArr;
+ this.drawRecord();
+ };
+
+ TimeLine.prototype.drawRecord = function () {
+ var timeArr = this.timeSection || [];
+ var that = this;
+ var drawPen = that.drawPen; // var startDate = new Date(that.nowTime);
+ // var timeScale = that.canvasWidth / that.timeWidth;
+ // 鏍规嵁鏃堕棿鏌ユ壘褰撳墠浣嶇疆
+
+ for (var i = 0; i < timeArr.length; i++) {
+ //console.log("timeArr[i]",timeArr[i],findPosition(timeArr[i].startTime),findPosition(timeArr[i].endTime))
+ var startPosition = findPosition(timeArr[i].startTime);
+ var endPosition = findPosition(timeArr[i].endTime);
+ drawPen.fillStyle = '#1890ff80';
+ drawPen.fillRect(startPosition, 0, endPosition - startPosition, 48);
+ }
+
+ function findPosition(time) {
+ var scale = 10;
+
+ switch (that.timeWidth) {
+ case 60:
+ scale = 10;
+ break;
+
+ case 1800:
+ scale = 20 / 60;
+ break;
+
+ case 3600:
+ scale = 20 / 60;
+ break;
+
+ case 86400:
+ scale = 20 / 60 / 60;
+ break;
+ }
+
+ var nowTimePostion = that.canvasWidth / 2; //鎬诲搴︿竴鍗�
+
+ var position = nowTimePostion + (time - that.nowTime) / 1000 * scale;
+
+ if (position > that.canvasWidth) {
+ position = that.canvasWidth;
+ }
+
+ if (position <= 0) {
+ position = 0;
+ }
+
+ return position;
+ }
+ };
+
+ TimeLine.prototype.drawOtherMsg = function () {
+ // 鐢讳腑蹇冪嚎
+ this.drawSolidLine(this.canvasWidth / 2, 0, this.canvasWidth / 2, this.canvasHeight, 2, '#1890FF');
+ this.drawPen.shadowBlur = 0;
+
+ if (this.isOver && !this.isMouseDown) {
+ this.mouseTime = this.mousePosition / this.canvasWidth * this.timeWidth * 1000 + this.nowTime - this.timeWidth / 2 * 1000; // 榧犳爣鐨勬偓娴偣瀵瑰簲鐨勬椂闂�
+
+ this.mouseString = this.tranTime(this.mouseTime); // 榧犳爣鎮诞鐐规樉绀虹殑鏂囧瓧
+
+ this.hoverTime = this.mouseString;
+ this.hoverLeft = this.mousePosition - 60;
+ this.timeTipShow = true;
+ } else {
+ this.timeTipShow = false;
+ }
+ };
+};
+
+var Rec = /*#__PURE__*/function () {
+ function Rec(jSPlugin) {
+ var _this = this;
+
+ _classCallCheck$1(this, Rec);
+
+ this.jSPlugin = jSPlugin;
+
+ if (!document.getElementById("".concat(this.jSPlugin.id, "-audioControls"))) {
+ return false;
+ }
+
+ this.currentTimeWidth = 1; //鍥炴斁鏃堕棿杞村昂搴� 1~4
+
+ this.timer = null;
+ this.date = new Date();
+ this.datepickerVisible = false;
+ this.seekTimer = null;
+ this.disabled = false;
+ this.seekFrequency = 2000;
+
+ if (this.jSPlugin.params && this.jSPlugin.params.seekFrequency) {
+ this.seekFrequency = this.jSPlugin.params.seekFrequency;
+ }
+
+ var canvasItemWidth = parseInt(getComputedStyle(document.getElementById(jSPlugin.id)).width, 10) - 100;
+ var canvasContainer = document.createElement('div');
+ canvasContainer.style = "display:inline-block;height:48px;";
+ canvasContainer.id = this.jSPlugin.id + "-canvas-container";
+ var canvasItem = document.createElement('canvas');
+ canvasItem.id = this.jSPlugin.id + "-canvas";
+ canvasItem.className = "time-line-body";
+ canvasItem.height = "48";
+ canvasItem.width = canvasItemWidth;
+ canvasItem.style = "display:inline-block;";
+ canvasItem.innerHTML = "璇ユ祻瑙堝櫒涓嶆敮鎸乧anvas";
+ canvasContainer.appendChild(canvasItem);
+ insertAfter$1(canvasContainer, document.getElementById("".concat(this.jSPlugin.id, "-audioControls")));
+ var timeLineControlsContainer = document.createElement('div');
+ timeLineControlsContainer.className = "timeline-controls";
+ timeLineControlsContainer.style = "display:flex;width:100px;height:48px;text-align:center;line-height: 48px;vertical-align: top;background: #000000;";
+ var timeLineControls = "\n<div class=\"timeline-controls-scale\" style=\"display: inline-flex;flex-direction: column;justify-content: center;vertical-align: top;padding: 0 20px;\">\n <span style=\"vertical-Align: middle;line-height: 14px;height: 18px; width: 18px;cursor:pointer;\" id=\"".concat(this.jSPlugin.id, "-timeline-scale-add\">\n <svg fill=\"#2C2C2C\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\n viewBox=\"0 0 20 20\">\n <title>add</title>\n <g>\n <polygon points=\"0.1,0.5 15,0.5 15,15.4 0.1,15.4 \t\" />\n </g>\n <g>\n <path\n fill=\"#FFFFFF\";\n d=\"M7.6,12.4c-0.3,0-0.5-0.2-0.5-0.5v-8c0-0.3,0.2-0.5,0.5-0.5s0.5,0.2,0.5,0.5v8C8.1,12.2,7.9,12.4,7.6,12.4z\" />\n </g>\n <g>\n <path\n fill=\"#FFFFFF\";\n d=\"M11.6,8.4h-8c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h8c0.3,0,0.5,0.2,0.5,0.5S11.8,8.4,11.6,8.4z\" />\n </g>\n </svg>\n </span>\n <span style=\"vertical-Align: middle;line-height: 14px;height: 18px; width: 18px;cursor:pointer;\" id=\"").concat(this.jSPlugin.id, "-timeline-scale-sub\">\n <svg fill=\"#2C2C2C\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\n viewBox=\"0 0 20 20\">\n <title>reduce</title>\n <g>\n <polygon class=\"st0\" points=\"1,0.8 15.2,0.8 15.2,15 1,15 \t\" />\n </g>\n <g>\n <path class=\"st1\"\n fill=\"#FFFFFF\";\n d=\"M12.1,8.4h-8c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h8c0.3,0,0.5,0.2,0.5,0.5S12.4,8.4,12.1,8.4z\" />\n </g>\n </svg>\n </span>\n</div>\n<label for=\"").concat(this.jSPlugin.id, "-datepicker\">\n <div class=\"timeline-controls-date\">\n <span>\n <svg fill=\"#2C2C2C\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\n viewBox=\"0 0 20 20\">\n <title>ifttt</title>\n <g id=\"Rectangle\">\n <rect x=\"0.6\" y=\"0.9\" class=\"st0\" width=\"20\" height=\"20\" />\n </g>\n <g id=\"Stroke-1\">\n <path fill=\"#FFFFFF\"; class=\"st1\"\n d=\"M14,7.2c-0.3,0-0.5-0.2-0.5-0.5V3.4c0-0.3,0.2-0.5,0.5-0.5s0.5,0.2,0.5,0.5v3.3C14.5,7,14.2,7.2,14,7.2z\" />\n </g>\n <g id=\"Stroke-3\">\n <path fill=\"#FFFFFF\"; class=\"st1\"\n d=\"M7.3,7.2C7,7.2,6.8,7,6.8,6.7V3.4c0-0.3,0.2-0.5,0.5-0.5s0.5,0.2,0.5,0.5v3.3C7.8,7,7.6,7.2,7.3,7.2z\" />\n </g>\n <g id=\"Stroke-5\">\n <path fill=\"#FFFFFF\"; class=\"st1\"\n d=\"M18.1,9.7h-15c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h15c0.3,0,0.5,0.2,0.5,0.5S18.4,9.7,18.1,9.7z\" />\n </g>\n <g id=\"Stroke-7\">\n <path fill=\"#FFFFFF\"; class=\"st1\" d=\"M16.5,19.7H4.8c-1.2,0-2.2-1-2.2-2.2V6.7c0-1.2,1-2.2,2.2-2.2h11.7c1.2,0,2.2,1,2.2,2.2v10.8\nC18.6,18.8,17.7,19.7,16.5,19.7z M4.8,5.6c-0.6,0-1.2,0.5-1.2,1.2v10.8c0,0.6,0.5,1.2,1.2,1.2h11.7c0.6,0,1.2-0.5,1.2-1.2V6.7\nc0-0.6-0.5-1.2-1.2-1.2H4.8z\" />\n </g>\n <g id=\"Stroke-9\">\n <path fill=\"#FFFFFF\"; class=\"st1\" d=\"M10.6,13.3c-0.4,0-0.7-0.3-0.7-0.7c0-0.2,0.1-0.4,0.2-0.5s0.3-0.2,0.5-0.2h0h0c0.4,0,0.7,0.3,0.7,0.7\nS11,13.3,10.6,13.3z\" />\n </g>\n <g id=\"Stroke-11\">\n <path fill=\"#FFFFFF\"; class=\"st1\" d=\"M14.8,13.3c-0.4,0-0.7-0.3-0.7-0.7c0-0.2,0.1-0.4,0.2-0.5c0.1-0.1,0.3-0.2,0.5-0.2c0.4,0,0.7,0.3,0.7,0.7\nS15.2,13.3,14.8,13.3z M14.8,12.3c-0.2,0-0.3,0.1-0.3,0.3c0,0.2,0.3,0.4,0.5,0.2c0.1-0.1,0.1-0.1,0.1-0.2\nC15.1,12.4,15,12.3,14.8,12.3z\" />\n </g>\n <g id=\"Stroke-13\">\n <path fill=\"#FFFFFF\"; class=\"st1\" d=\"M6.5,16.6c-0.4,0-0.7-0.3-0.7-0.7c0-0.2,0.1-0.4,0.2-0.5c0.1-0.1,0.3-0.2,0.5-0.2h0h0c0.4,0,0.7,0.3,0.7,0.7\nC7.2,16.3,6.9,16.6,6.5,16.6z\" />\n </g>\n <g id=\"Stroke-15\">\n <path fill=\"#FFFFFF\"; class=\"st1\" d=\"M10.6,16.6c-0.4,0-0.7-0.3-0.7-0.7c0-0.2,0.1-0.4,0.2-0.5c0.1-0.1,0.3-0.2,0.5-0.2h0h0c0.4,0,0.7,0.3,0.7,0.7\nC11.4,16.3,11,16.6,10.6,16.6z\" />\n </g>\n </svg>\n </span>\n </div>\n</label>\n<input data-toggle=\"").concat(this.jSPlugin.id, "-datepicker\" id=\"").concat(this.jSPlugin.id, "-datepicker\" name=\"").concat(this.jSPlugin.id, "-datepicker\" style=\"opacity:0;width:24px;margin-left:-24px;cursor:pointer;\" />\n");
+ timeLineControlsContainer.innerHTML = timeLineControls;
+ insertAfter$1(timeLineControlsContainer, canvasContainer);
+ this.timeLine = new TimeLine$1(this.jSPlugin);
+ this.timeLine.init({
+ id: this.jSPlugin.id + '-canvas',
+ width: canvasItemWidth,
+ onChange: function onChange(time) {
+ console.log("time", time, new Date(time).Format('yyyyMMddhhmmss'));
+ var newBegin = new Date(time).Format('yyyyMMddhhmmss');
+
+ if (matchEzopenUrl(_this.jSPlugin.url).type === 'cloud.rec') {
+ var cloudSeek = function cloudSeek() {
+ _this.jSPlugin.seek(newBegin.substr(8, 6), "235959");
+
+ _this.unSyncTimeLine();
+
+ setTimeout(function () {
+ _this.syncTimeLine();
+ }, 6000);
+ };
+
+ if (_this.seekTimer) {
+ clearTimeout(_this.seekTimer);
+ } else {
+ cloudSeek();
+ } // 闄愬埗姣�2绉掑彧瑙﹀彂涓�娆℃嫋鍔�
+
+
+ _this.seekTimer = setTimeout(function () {
+ cloudSeek();
+ clearTimeout(_this.seekTimer);
+ _this.seekTimer = null;
+ }, _this.seekFrequency);
+ } else {
+ var callback = function callback() {
+ setTimeout(function () {
+ _this.disabled = false;
+ }, _this.seekFrequency);
+ };
+
+ var localRecSeek = function localRecSeek(callback) {
+ _this.disabled = true;
+
+ _this.jSPlugin.pause().then(function () {
+ console.log("鏆傚仠鎴愬姛");
+
+ _this.jSPlugin.resume(newBegin).then(function (data) {
+ console.log("鎭㈠鎴愬姛");
+
+ if (_this.jSPlugin.Theme) {
+ _this.jSPlugin.Theme.setDecoderState({
+ play: true
+ });
+ }
+
+ if (callback) {
+ callback();
+ }
+ })["catch"](function (err) {
+ console.log("鎭㈠澶辫触", err);
+ });
+ })["catch"](function () {
+ console.log("鏆傚仠澶辫触");
+
+ _this.jSPlugin.resume(newBegin).then(function (data) {
+ console.log("鎭㈠鎴愬姛");
+
+ if (_this.jSPlugin.Theme) {
+ _this.jSPlugin.Theme.setDecoderState({
+ play: true
+ });
+ }
+
+ if (callback) {
+ callback();
+ }
+ })["catch"](function (err) {
+ console.log("鎭㈠澶辫触", err);
+ });
+ });
+ };
+
+ if (_this.disabled) {
+ console.log("鎿嶄綔棰戠箒锛岀瓑寰�2绉掑悗鎵ц"); // 闄愬埗姣�2绉掑彧瑙﹀彂涓�娆℃嫋鍔�
+
+ if (_this.seekTimer) {
+ clearTimeout(_this.seekTimer);
+ }
+
+ _this.seekTimer = setTimeout(function () {
+ localRecSeek(callback);
+ }, _this.seekFrequency);
+ } else {
+ localRecSeek(callback);
+ }
+ }
+ }
+ });
+ this.syncTimeLine(); // 鍔犺浇鏃ユ湡閫夋嫨鍣�
+
+ addCss("".concat(this.jSPlugin.staticPath, "/rec/datepicker.min.css"));
+ addJs("".concat(this.jSPlugin.staticPath, "/rec/jquery.min.js"), function () {
+ addJs("".concat(_this.jSPlugin.staticPath, "/rec/datepicker.js"), function () {
+ addJs("".concat(_this.jSPlugin.staticPath, "/rec/datepicker.zh-CN.js"), function () {
+ // 鏃ユ湡閫夋嫨锛�
+ if (!document.getElementsByClassName("datepicker-container")[0]) {
+ $("#".concat(_this.jSPlugin.id, "-datepicker")).datepicker({
+ autoShow: false,
+ autoHide: true,
+ autoPick: true,
+ language: 'zh-CN',
+ defaultDate: new Date(),
+ format: 'yyyy-mm-dd',
+ endDate: new Date(),
+ inline: true,
+ container: document.getElementById("".concat(_this.jSPlugin.id, "-wrap"))
+ });
+ }
+
+ if (document.getElementsByClassName("datepicker-container")[0]) {
+ document.getElementsByClassName("datepicker-container")[0].style.display = "none";
+ }
+
+ _this.datepickerVisible = false;
+ $("#".concat(_this.jSPlugin.id, "-datepicker")).on('pick.datepicker', function (e) {
+ console.log("閲嶆柊閫夋嫨鏃ユ湡", e.date, new Date(e.date).Format('yyyyMMdd'), new Date(document.getElementById("".concat(_this.jSPlugin.id, "-datepicker")).value).Format('yyyyMMdd'));
+
+ if (e.date > new Date() || new Date(e.date).Format('yyyyMMdd') === new Date(document.getElementById("".concat(_this.jSPlugin.id, "-datepicker")).value).Format('yyyyMMdd')) {
+ e.preventDefault(); // Prevent to pick the date
+ } else {
+ _this.renderRec(e.date);
+
+ _this.jSPlugin.changePlayUrl({
+ begin: new Date(e.date).Format('yyyyMMdd')
+ });
+ }
+
+ if (document.getElementsByClassName("datepicker-container")[0]) {
+ document.getElementsByClassName("datepicker-container")[0].style.display = "none";
+ }
+
+ _this.datepickerVisible = false;
+ });
+ $("#".concat(_this.jSPlugin.id, "-datepicker")).off('click').on("click", function (e) {
+ console.log("鐐瑰嚮鏃ユ湡");
+
+ if (!_this.datepickerVisible) {
+ if (document.getElementsByClassName("datepicker-container")[0]) {
+ document.getElementsByClassName("datepicker-container")[0].style.display = "inline";
+ }
+ } else {
+ if (document.getElementsByClassName("datepicker-container")[0]) {
+ document.getElementsByClassName("datepicker-container")[0].style.display = "none";
+ }
+ }
+
+ _this.datepickerVisible = !_this.datepickerVisible;
+ });
+ });
+ });
+ }); // 灏哄害鍙樺寲鐩戝惉
+
+ document.getElementById("".concat(this.jSPlugin.id, "-timeline-scale-add")).onclick = function () {
+ var currentTimeWidth = _this.currentTimeWidth;
+
+ if (currentTimeWidth < 3) {
+ _this.timeLine.changeSize(++_this.currentTimeWidth);
+ }
+ };
+
+ document.getElementById("".concat(this.jSPlugin.id, "-timeline-scale-sub")).onclick = function () {
+ var currentTimeWidth = _this.currentTimeWidth;
+
+ if (currentTimeWidth > 0) {
+ _this.timeLine.changeSize(--_this.currentTimeWidth);
+ }
+ }; // 娓叉煋鍥炴斁
+
+
+ var initDate = getQueryString("begin", this.jSPlugin.url) || new Date().Format('yyyyMMdd');
+ this.renderRec("".concat(initDate.slice(0, 4), "-").concat(initDate.slice(4, 6), "-").concat(initDate.slice(6, 8)));
+ this.observer = new MutationObserver(function (mutations, observer) {
+ _this.recAutoSize();
+ });
+ var config = {
+ attributes: true,
+ attributeOldValue: true,
+ attributeFilter: ['style']
+ };
+ var el = document.getElementById("".concat(this.jSPlugin.id));
+ this.observer.observe(el, config);
+ }
+
+ _createClass$1(Rec, [{
+ key: "recAutoSize",
+ value: function recAutoSize() {
+ var _this2 = this;
+
+ if (document.getElementById("".concat(this.jSPlugin.id, "-canvas"))) {
+ var canvasItemWidth = parseInt(getComputedStyle(document.getElementById(this.jSPlugin.id)).width, 10) - 100;
+
+ if (canvasItemWidth !== parseInt(document.getElementById("".concat(this.jSPlugin.id, "-canvas")).width)) {
+ document.getElementById("".concat(this.jSPlugin.id, "-canvas")).width = canvasItemWidth;
+ this.timeLine.init({
+ id: "".concat(this.jSPlugin.id, "-canvas"),
+ width: canvasItemWidth,
+ onChange: function onChange(time) {
+ console.log("time", time, new Date(time).Format('yyyyMMddhhmmss'));
+ console.log("jSPlugin", _this2.jSPlugin);
+ var newBegin = new Date(time).Format('yyyyMMddhhmmss');
+
+ _this2.jSPlugin.changePlayUrl({
+ begin: newBegin
+ });
+ }
+ });
+ this.renderRec(this.date);
+ }
+ }
+ }
+ }, {
+ key: "renderRec",
+ value: function renderRec(date) {
+ var _this3 = this;
+
+ this.date = date;
+ var dateStart = new Date(new Date(date).Format('yyyy-MM-dd 00:00:00').replace(/-/g, "/")).getTime();
+ var dateEnd = new Date(new Date(date).Format('yyyy-MM-dd 23:59:59').replace(/-/g, "/")).getTime();
+ this.timeLine.getRecord([], dateStart, dateEnd);
+ var recSliceParams = {
+ accessToken: this.jSPlugin.accessToken,
+ recType: matchEzopenUrl(this.jSPlugin.url).type === 'cloud.rec' ? 1 : 2,
+ deviceSerial: matchEzopenUrl(this.jSPlugin.url).deviceSerial,
+ channelNo: matchEzopenUrl(this.jSPlugin.url).channelNo,
+ startTime: dateStart,
+ endTime: dateEnd,
+ version: '2.0'
+ };
+
+ var recAPISuccess = function recAPISuccess(data) {
+ if (data.data && data.data.files && data.data.files.length > 0) {
+ var dataArr = data.data.files;
+ var nextFileTime = new Date().getTime();
+ var isAll = data.data.isAll;
+
+ if (isAll) {
+ _this3.timeLine.getRecord(dataArr, dateStart, dateEnd);
+ } else {
+ // 浜戝瓨鍌ㄥ洖璋冧簨鍔�
+ var recTransaction = function recTransaction() {
+ function recAPIV2Success(data) {
+ if (data.data && data.data.files && data.data.files.length > 0) {
+ if (data.data.isAll == false) {
+ if (data.data.files) {
+ dataArr = dataArr.concat(data.data.files);
+ }
+
+ nextFileTime = data.data.nextFileTime > 0 ? data.data.nextFileTime : new Date().getTime();
+ recTransaction();
+ } else {
+ console.log("浜戝瓨鍌ㄦ墽琛屾覆鏌撶墖娈�");
+ this.timeLine.getRecord(dataArr, dateStart, dateEnd);
+ }
+ } else {
+ this.timeLine.getRecord(dataArr, dateStart, dateEnd);
+ }
+ }
+
+ recSliceParams.startTime = nextFileTime;
+ request(this.jSPlugin.env.domain + "/api/lapp/video/by/time", 'POST', recSliceParams, '', recAPIV2Success);
+ };
+
+ recTransaction();
+ }
+
+ _this3.timeLine.run({
+ time: new Date(dateStart)
+ });
+ } else if (data.data && data.data.length > 0) {
+ console.log("鑾峰彇鏈湴褰曞儚鐗囨鎴愬姛", data);
+
+ _this3.timeLine.getRecord(data.data, dateStart, dateEnd);
+
+ _this3.timeLine.run({
+ time: new Date(dateStart)
+ });
+ } else ;
+ };
+
+ var recAPIUrl = this.jSPlugin.env.domain + "/api/lapp/video/by/time";
+ request(recAPIUrl, 'POST', recSliceParams, '', recAPISuccess);
+ }
+ }, {
+ key: "syncTimeLine",
+ value: function syncTimeLine() {
+ var _this4 = this;
+
+ if (this.timer) {
+ clearInterval(this.timer);
+ }
+
+ this.timer = setInterval(function () {
+ var getOSDTimePromise = _this4.jSPlugin.getOSDTime();
+
+ getOSDTimePromise.then(function (data) {
+ var v = data.data;
+
+ if (v === -1) {
+ console.log("鑾峰彇鎾斁鏃堕棿閿欒");
+ } else {
+ if (v > 0) {
+ //console.log("鑾峰彇鎾斁鏃堕棿", v, this.timeLine.run);
+ _this4.timeLine.run({
+ time: new Date(v > 1000000000000 ? v : v * 1000)
+ }); //$(".current-time").text(new Date(new Date(v > 1000000000000 ? v : v * 1000)).Format('yyyy-MM-dd hh:mm:ss'))
+
+ }
+ }
+ })["catch"](function (err) {});
+ }, 1000);
+ }
+ }, {
+ key: "unSyncTimeLine",
+ value: function unSyncTimeLine() {
+ if (this.timer) {
+ clearInterval(this.timer);
+ }
+ }
+ }]);
+
+ return Rec;
+}();
+
+var TimeLine = function TimeLine(params) {
+ console.log("鎵цTimeLine - params", params);
+ this.state = {
+ id: params.id,
+ start: '00:00:00',
+ // 浼犲叆鏈�杩戠墖娈佃捣濮嬫椂鍒�
+ end: '24:00:00',
+ // 浼犲叆鏈�杩戠墖娈电粨鏉熸椂鍒� 榛樿缁撴潫鏃堕棿涓�24锛�00锛�00, 1440 24
+ current: 0,
+ // 褰撳墠鎾斁鏃跺埢
+ // rate: 1, // 1锛�2灏忔椂锛� 2锛�1灏忔椂锛� 3锛氬崐灏忔椂锛� 4锛�10鍒嗛挓锛� 5锛�1鍒嗛挓
+ timelag: 30,
+ // 120: 2灏忔椂锛� 60锛�1灏忔椂锛� 30锛氬崐灏忔椂锛�10锛�10鍒嗛挓锛�1锛�1鍒嗛挓
+ timeArr: [],
+ // 鏃堕棿杞村垪琛�
+ availTimeLine: [],
+ // 鐢卞疄闄呭瓨鍦ㄨ棰戠墖娈电殑鏃堕棿缁勬垚锛孾{st: '', et: ''}, {st: '', et: ''}, ...]
+ scrollTop: 0,
+ // 椤甸潰婊氬姩鍋忕Щ閲� 椤甸潰鍋忕Щ閲忕敱浼犲叆鏃跺埢鍐冲畾
+ // currentTimer: '', // 鏃跺埢瀹氭椂鍣�
+ // timelineTimer: '', //鏃堕棿杞村畾鏃跺櫒,
+ index: 0,
+ // 鍒濆鏃跺埢鍦╝vailtimeLine涓殑index
+ // playCode: 0, // 褰撳墠鎾斁鐘舵�佸��
+ date: '',
+ noTimeLineTxt: '',
+ disabled: false // 绂佺敤鎷栧姩杞�
+
+ };
+
+ var _this = this;
+
+ this.setState = function (obj) {
+ Object.keys(obj).forEach(function (key) {
+ _this.state[key] = obj[key];
+
+ if (key === 'scrollTop') {
+ document.getElementById('time-line-item').parentNode.scrollTo(0, obj[key]);
+ }
+
+ if (key === 'current') {
+ document.getElementById('time-line-current').innerHTML = obj[key];
+ }
+ });
+ };
+
+ this.setDisabled = function (value) {
+ this.setState({
+ disabled: value
+ });
+ document.getElementById('time-line-item').parentNode.style.overflowY = value ? 'hidden' : 'scroll'; // console.log(" document.getElementById('time-line-item').parentNode.style", document.getElementById('time-line-item').parentNode)
+ };
+
+ this.timeToSecond = function (time) {
+ var e = time.split(':');
+ var h = Number(e[0]);
+ var m = Number(e[1]);
+ var s = Number(e[2]);
+ return h * 60 * 60 + m * 60 + (s ? s : 0);
+ };
+
+ this.minuteToTime = function (minute) {
+ var hour = Math.floor(minute / 60);
+ var m = minute % 60;
+ return (hour > 9 ? hour : '0' + hour) + ':' + (m > 9 ? m : '0' + m);
+ };
+
+ this.timeToMinute = function (time) {
+ var e = time.split(':');
+ var h = Number(e[0]);
+ var m = Number(e[1]); // const s = Number(e[2]);
+
+ return h * 60 + m;
+ };
+
+ this.getPalyParam = params.getPalyParam; // 鐩戝惉鎵嬪姩婊氬姩鏃堕棿杞存椂锛屽仠姝㈡椂闂磋酱婊氬姩锛屾椂鍒讳粛鐒跺彉鍖�
+
+ document.getElementById('time-line-item').parentNode.ontouchstart = function () {
+ if (_this.state.disabled) {
+ return false;
+ }
+
+ params.ontouchstart();
+ }; // 鐩戝惉鎵嬪姩婊氬姩鏃堕棿杞存椂锛屽仠姝㈡椂闂磋酱婊氬姩锛屾椂鍒讳粛鐒跺彉鍖�
+
+
+ document.getElementById('time-line-item').parentNode.ontouchmove = function () {
+ if (_this.state.disabled) {
+ return false;
+ }
+
+ params.ontouchmove();
+ }; // 鎵嬪姩婊氬姩鍋滄锛岄�夊畾鏃跺埢鑷姩鎾斁
+
+
+ document.getElementById('time-line-item').parentNode.ontouchend = function () {
+ // var _this = this;
+ if (_this.state.disabled) {
+ return false;
+ } //
+
+
+ var timer;
+ var scollPromise = new Promise(function (resolve, reject) {
+ var preTop = -1;
+ timer = setInterval(function () {
+ // debugger
+ var reactTop = document.getElementById('time-line-item').parentNode.scrollTop; // 瀹為檯鍋忕Щ楂樺害
+
+ if (reactTop !== preTop) {
+ console.log("scolling", reactTop, preTop);
+ preTop = reactTop;
+ } else {
+ console.log("scoll stop", reactTop, preTop);
+ clearInterval(timer);
+ resolve(reactTop);
+ }
+ }, 100);
+ }); //
+
+ scollPromise.then(function (reactTop) {
+ console.log("scollPromise: then", reactTop, _this);
+
+ _this.rectTopTotime(reactTop);
+
+ console.log('椤甸潰婊氬姩瀹為檯楂樺害', reactTop, _this.state);
+
+ _this.getPalyParam({
+ current: _this.state.current
+ });
+ });
+ params.ontouchend();
+ };
+
+ this.matchTimeDot();
+};
+
+TimeLine.prototype.changeScale = function (value) {
+ this.setState({
+ timelag: value // 120: 2灏忔椂锛� 60锛�1灏忔椂锛� 30锛氬崐灏忔椂锛�10锛�10鍒嗛挓锛�1锛�1鍒嗛挓
+
+ });
+ this.matchTimeDot();
+};
+
+TimeLine.prototype.setDateLine = function (news, defaultIndex) {
+ // if( news.length > 0 ){
+ // if(!defaultIndex){
+ // defaultIndex = 0;
+ // }
+ // this.setState({
+ // availTimeLine: news,
+ // start: news[defaultIndex].st,
+ // end: news[defaultIndex].et,
+ // current: news[defaultIndex].st,
+ // })
+ // console.log("this.state", this.state);
+ // this.matchTimeDot();
+ // this.primaryOffsetH();
+ // // 灏嗗綋鍓嶆挱鏀炬椂闂寸墖娈典紶缁欑埗缁勪欢
+ // this.getPalyParam(news[defaultIndex]);
+ // }
+ if (news.length > 0) {
+ if (typeof defaultIndex === 'undefined') {
+ defaultIndex = news.length - 1;
+ }
+
+ this.setState({
+ availTimeLine: news,
+ start: news[defaultIndex].st,
+ end: news[defaultIndex].et,
+ current: news[defaultIndex].st
+ });
+ console.log("this.state", this.state);
+ this.matchRecTimeDot();
+ this.primaryOffsetH(); // 灏嗗綋鍓嶆挱鏀炬椂闂寸墖娈典紶缁欑埗缁勪欢
+ //this.getPalyParam({ current: news[defaultIndex].st });
+ } else {
+ this.setState({
+ availTimeLine: []
+ });
+ console.log("this.state", this.state);
+ this.matchRecTimeDot();
+ }
+};
+
+TimeLine.prototype.matchTimeDot = function () {
+ var _this$state = this.state,
+ start = _this$state.start,
+ end = _this$state.end,
+ timelag = _this$state.timelag;
+ _this$state.availTimeLine;
+ console.log("start", start, 'end', end);
+ var timeArr = []; // // 鎾斁鏃堕棿鐗囨鏃跺埢杞垎閽�
+ // let availArr = [];
+ // let len = availTimeLine.length;
+ // for (let i = 0; i < len; i++) {
+ // const temp = availTimeLine[i];
+ // let st = this.timeToSecond(temp.st);
+ // let et = this.timeToSecond(temp.et);
+ // // console.log('st: ', st, 'et:', et);
+ // let stminute;
+ // let etminute;
+ // let stAvailPercent = 0;
+ // let etAvailPercent = 0;
+ // stminute = Math.floor(st / (timelag * 60)) * timelag;
+ // stAvailPercent = (st - (stminute * 60)) / timelag;
+ // etminute = Math.floor(et / (timelag * 60)) * timelag;
+ // etAvailPercent = (et - (etminute * 60)) / timelag;
+ // availArr[i] = {
+ // st: stminute,
+ // et: etminute,
+ // stAvailPercent: stAvailPercent,
+ // etAvailPercent: etAvailPercent
+ // }
+ // }
+ // console.log('availArr: ', availArr);
+ // 鏃堕棿杞垎閽�
+
+ var minute = this.timeToMinute(end); // // 妫�娴嬫槸鍚﹀寘鍚,鍒欏疄闄呭垎閽熷姞1
+ // const e = end.split(':');
+ // const s = Number(e[2]);
+ // if (s > 0) {
+ // minute = minute + 1
+ // }
+
+ minute = Math.floor(minute / timelag) * timelag;
+
+ for (var i = minute; i >= 0;) {
+ var marginTop = 0;
+ var marginBottom = 0; // 瑙嗛鐗囨
+
+ var recArr = [];
+
+ if (i == minute) {
+ marginTop = 70;
+ }
+
+ if (i == 0) {
+ marginBottom = 230;
+ } // for (let j = 0; j < len; j++) {
+ // if (i >= availArr[j].st && i <= availArr[j].et) {
+ // // borderColor = '#f7a670';
+ // // console.log("i",i,availArr[j])
+ // if (i == availArr[j].st && i == availArr[j].et) {
+ // var height = availArr[j].etAvailPercent - availArr[j].stAvailPercent;
+ // var top = 60 - availArr[j].etAvailPercent;
+ // recArr.push({
+ // height: height,
+ // top: top
+ // })
+ // } else {
+ // if (i == availArr[j].st) {
+ // recArr.push({
+ // height: 60 - availArr[j].stAvailPercent,
+ // top: 0
+ // })
+ // } else if (i == availArr[j].et) {
+ // recArr.push({
+ // height: availArr[j].etAvailPercent,
+ // top: 60 - availArr[j].etAvailPercent,
+ // })
+ // } else if (i > availArr[j].st && i < availArr[j].et) {
+ // // 璺ㄨ秺澶氫釜鍖哄煙
+ // recArr.push({
+ // height: 60,
+ // top: 0,
+ // })
+ // }
+ // }
+ // }
+ // }
+
+
+ var time = this.minuteToTime(i);
+ timeArr.push({
+ id: i,
+ current: time,
+ label: "a" + i,
+ marginTop: marginTop,
+ marginBottom: marginBottom,
+ recArr: recArr
+ });
+ i = i - timelag;
+ }
+
+ this.setState({
+ timeArr: timeArr
+ });
+ this.renderDateLine();
+};
+
+TimeLine.prototype.matchRecTimeDot = function () {
+ var _this$state2 = this.state,
+ start = _this$state2.start,
+ end = _this$state2.end,
+ timelag = _this$state2.timelag,
+ availTimeLine = _this$state2.availTimeLine,
+ timeArr = _this$state2.timeArr;
+ console.log("start", start, 'end', end); // 鎾斁鏃堕棿鐗囨鏃跺埢杞垎閽�
+
+ var availArr = [];
+ var len = availTimeLine.length;
+
+ if (len === 0) {
+ for (var j = 0; j < timeArr.length; j++) {
+ timeArr[j].recArr = [];
+ }
+ } else {
+ for (var i = 0; i < len; i++) {
+ var temp = availTimeLine[i];
+ var st = this.timeToSecond(temp.st);
+ var et = this.timeToSecond(temp.et); // console.log('st: ', st, 'et:', et);
+
+ var stminute = void 0;
+ var etminute = void 0;
+ var stAvailPercent = 0;
+ var etAvailPercent = 0;
+ stminute = Math.floor(st / (timelag * 60)) * timelag;
+ stAvailPercent = (st - stminute * 60) / timelag;
+ etminute = Math.floor(et / (timelag * 60)) * timelag;
+ etAvailPercent = (et - etminute * 60) / timelag;
+ availArr[i] = {
+ st: stminute,
+ et: etminute,
+ stAvailPercent: stAvailPercent,
+ etAvailPercent: etAvailPercent
+ };
+
+ for (var j = 0; j < timeArr.length; j++) {
+ if (timeArr[j].id == stminute && timeArr[j].id == etminute) {
+ var height = etAvailPercent - stAvailPercent;
+ var top = 60 - etAvailPercent;
+ timeArr[j].recArr.push({
+ height: height,
+ top: top
+ });
+ } else {
+ if (timeArr[j].id == stminute) {
+ timeArr[j].recArr.push({
+ height: 60 - stAvailPercent,
+ top: 0
+ });
+ } else if (timeArr[j].id == etminute) {
+ timeArr[j].recArr.push({
+ height: etAvailPercent,
+ top: 60 - etAvailPercent
+ });
+ } else if (timeArr[j].id > stminute && timeArr[j].id < etminute) {
+ timeArr[j].recArr.push({
+ height: 60,
+ top: 0
+ });
+ }
+ }
+ }
+ }
+ }
+
+ console.log('availArr: ', availArr);
+ this.setState({
+ timeArr: timeArr
+ });
+ console.log('timeArr:', this.state);
+ this.renderDateLine();
+};
+
+TimeLine.prototype.renderDateLine = function () {
+ var _this$state3 = this.state,
+ id = _this$state3.id,
+ timeArr = _this$state3.timeArr;
+ console.log("id,timeArr", id, timeArr);
+ var container = document.getElementById("time-line-item");
+ container.innerHTML = "";
+ timeArr.forEach(function (item, index) {
+ var timeItemDOM = document.createElement('div');
+ timeItemDOM.setAttribute("class", "time-item");
+ timeItemDOM.style = "margin-top: ".concat(item.marginTop, "px; margin-bottom: ").concat(item.marginBottom, "px; border-right-color: ").concat(item.borderColor, ";");
+ var scaleDOM = document.createElement('div');
+ scaleDOM.setAttribute("class", "scale");
+ var timeItemHtml = '<div class="scale"></div><div class="scale"></div><div class="scale"></div><div class="scale"></div><div class="scale"></div><div class="scale" style="width:10px"></div>';
+ item.recArr.forEach(function (i, j) {
+ timeItemHtml += "<div class=\"item-unavail\" style=\"height: ".concat(i.height, "px;background-color:#A8B9ED; top: ").concat(i.top, "px\"></div>");
+ }); //timeItemHtml += `<div class="item-unavail" style="height: ${item.availPercent}px; top: ${item.availTop}px"></div>`
+
+ timeItemHtml += "<div id=".concat(item.label, " style=\"position: relative; top: 51px; left: 40%\"> ").concat(item.current, "</div>");
+ timeItemDOM.innerHTML = timeItemHtml;
+ container.appendChild(timeItemDOM);
+ });
+}; // 璁$畻鍒濆鍋忕Щ閲�
+
+
+TimeLine.prototype.primaryOffsetH = function () {
+ var _this$state4 = this.state,
+ start = _this$state4.start,
+ timelag = _this$state4.timelag,
+ timeArr = _this$state4.timeArr;
+ var currentItem = timeArr[0].current;
+ var currentTime = this.timeToSecond(currentItem);
+ var startSecond = this.timeToSecond(start);
+ var offsetS = currentTime - startSecond;
+ var offsetH = Math.ceil(offsetS / timelag) + 60; // offsetS / (timelag * 60) * 60
+
+ this.setState({
+ scrollTop: offsetH
+ });
+ console.log('璧峰鍋忕Щ閲�', offsetH);
+}; // 璁$畻褰撳墠鍋忕Щ閲�
+
+
+TimeLine.prototype.currentOffsetH = function () {
+ var _this$state5 = this.state,
+ current = _this$state5.current,
+ timelag = _this$state5.timelag,
+ timeArr = _this$state5.timeArr;
+ var startItem = timeArr[0].current;
+ var startSecond = this.timeToSecond(startItem);
+ var currentSecond = this.timeToSecond(current);
+ var offsetS = startSecond - currentSecond;
+ var offsetH = Math.ceil(offsetS / timelag) + 60; // offsetS / (timelag * 60) * 60
+
+ this.setState({
+ scrollTop: offsetH
+ });
+}; // 閫氳繃鏃堕棿杞翠綅缃幏鍙栧綋鍓嶆椂闂�
+
+
+TimeLine.prototype.rectTopTotime = function (reactTop) {
+ var timelag = this.state.timelag; // let rectTop = rect.top; // 鑾峰彇褰撳墠鍏冪礌璺濈鐖跺厓绱犻《閮ㄧ殑楂樺害
+ // let reactTop = 0 - rectTop; // 瀹為檯鍋忕Щ楂樺害
+
+ var index = Math.floor(reactTop / 60); // 浠ュ垎閽熶负鍒诲害鏃讹紝姣忎釜鍏冪礌鍒濆楂樺害涓�60px, 鍚戜笅鍙栨暣骞堕櫎浠ユ椂鍒诲�嶆暟寰楀嚭鍋忕Щitem;
+
+ var offsetH = reactTop - index * 60; // 鍋忕Щ楂樺害
+
+ var current;
+ var offsetSecond;
+ console.log('index锛�', index, 'offsetH:', offsetH);
+
+ if (offsetH == 0) {
+ current = this.state.timeArr[index - 1].current;
+ offsetSecond = 0;
+ } else {
+ // 褰搕imelag==120,timelag==60,timelag==30,timelag==10,timelag==1
+ var time = this.state.timeArr[index].current;
+ var minute = this.timeToMinute(time); // 鐩稿浜庝笅涓�鍏冪礌鍋忕Щ
+
+ var offsetY = 60 - offsetH;
+ var offsetS = offsetY * timelag; // offsetY / 60 * timelag * 60
+
+ var offsetM = Math.floor(offsetS / 60) + minute;
+ var second = Math.floor(offsetS / 60) * 60;
+ offsetSecond = Math.ceil(offsetS - second); // 淇濈暀涓や綅灏忔暟
+
+ current = this.minuteToTime(offsetM);
+ }
+
+ this.setState({
+ current: current + ':' + (offsetSecond > 9 ? offsetSecond : '0' + offsetSecond),
+ scrollTop: reactTop
+ }); // console.log("rectLeft", reactTop);
+ // console.log("currentTime", current + ':' + (offsetSecond > 9 ? offsetSecond : '0' + offsetSecond));
+}; // 鏃堕棿杞存粴鍔紝鏍规嵁浼犲弬鍙樺寲
+
+
+TimeLine.prototype.stepScrollTimeLine = function (time) {
+ this.setState({
+ current: time
+ });
+ this.currentOffsetH();
+};
+
+TimeLine.prototype.secondCountDown = function (time) {
+ var current = this.state.current; // console.log('currentTime', current);
+
+ var temp = current.split(':');
+ var hour = Number(temp[0]);
+ var minute = Number(temp[1]);
+ var second = Number(temp[2]);
+ var t = hour * 60 * 60 + minute * 60 + second + 1;
+ var h = Math.floor(t / 3600);
+ var m = Math.floor((t - h * 3600) / 60);
+ var s = t - h * 3600 - m * 60;
+ this.setState({
+ current: (h > 9 ? h : '0' + h) + ':' + (m > 9 ? m : '0' + m) + ':' + (s > 9 ? s : '0' + s)
+ });
+};
+
+var MobileTimeLine = TimeLine;
+
+Date.prototype.Format = function (fmt) {
+ //author: meizz
+ var o = {
+ "M+": this.getMonth() + 1,
+ //鏈堜唤
+ "d+": this.getDate(),
+ //鏃�
+ "h+": this.getHours(),
+ //灏忔椂
+ "m+": this.getMinutes(),
+ //鍒�
+ "s+": this.getSeconds(),
+ //绉�
+ "q+": Math.floor((this.getMonth() + 3) / 3),
+ //瀛e害
+ "S": this.getMilliseconds() //姣
+
+ };
+
+ if (/(y+)/.test(fmt)) {
+ fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
+ }
+
+ for (var k in o) {
+ if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
+ }
+
+ return fmt;
+};
+
+function format(now) {
+ var time = new Date(now);
+ var h = time.getHours(); //杩斿洖鏃ユ湡涓殑灏忔椂鏁帮紙0鍒�23锛�
+
+ var m = time.getMinutes(); //杩斿洖鏃ユ湡涓殑鍒嗛挓鏁帮紙0鍒�59锛�
+
+ var s = time.getSeconds(); //杩斿洖鏃ユ湡涓殑绉掓暟锛�0鍒�59锛�
+
+ return (h > 9 ? h : '0' + h) + ':' + (m > 9 ? m : '0' + m) + ':' + (s > 9 ? s : '0' + s);
+}
+
+var MobileRec = /*#__PURE__*/function () {
+ function MobileRec(jSPlugin) {
+ var _this = this;
+
+ _classCallCheck$1(this, MobileRec);
+
+ this.jSPlugin = jSPlugin;
+ this.timer = null;
+ this.date = new Date().Format('yyyy-MM-dd');
+ this.begin = (new Date().Format('yyyy-MM-dd') + ' 00:00:00').replace(/-/g, "/");
+ this.end = (new Date().Format('yyyy-MM-dd') + ' 23:59:59').replace(/-/g, "/");
+ this.initBegin = null;
+ this.initEnd = null;
+ this.type = matchEzopenUrl(this.jSPlugin.url).type;
+ this.operating = false;
+ this.seekTimer = null;
+ this.disabled = false;
+ this.seekFrequency = 2000;
+
+ if (this.jSPlugin.params && this.jSPlugin.params.seekFrequency) {
+ this.seekFrequency = this.jSPlugin.params.seekFrequency;
+ }
+
+ var oS = document.createElement('style');
+ oS.innerHTML = "\n body{\n padding: 0;\n margin: 0;\n }\n .time-line-container {\n text-align: left;\n height: 300px;\n /* outline: 1px solid red; */\n /* background: gray; */\n position: relative;\n /* padding-top: 60px; */\n margin-top: 20px;\n }\n\n .time-line-container .time-line-item-container {\n display: inline-block;\n /* height: 400px; */\n width: 30%;\n /* background: indianred; */\n overflow-y: scroll;\n overflow-x: hidden;\n /* padding-top: 60px; */\n height: 300px;\n box-sizing: border-box;\n white-space: nowrap;\n position: relative;\n }\n\n .time-line-container .time-line-item-container::-webkit-scrollbar {\n width: 0px;\n /*\u6EDA\u52A8\u6761\u5BBD\u5EA6*/\n height: 0px;\n /*\u6EDA\u52A8\u6761\u9AD8\u5EA6*/\n }\n\n .time-line-item .time-item {\n position: relative;\n box-sizing: border-box;\n height: 60px;\n font-size: 12px;\n color: rgb(150, 150, 150);\n border-right: 6px solid;\n border-right-color: #ddd;\n }\n\n .time-line-item .time-item .scale {\n width: 6px;\n height: 9px;\n border-bottom: 1px solid #ccc;\n float: right;\n clear: both;\n }\n\n .time-line-item .time-item .item-unavail {\n width: 6px;\n position: absolute;\n left: 100%;\n background-color: #ddd;\n }\n\n .time-line-container .current-time {\n position: absolute;\n left: 0;\n top: 40px;\n height: 29px;\n /* line-height: 58px; */\n border-bottom: 1px solid #648FFC;\n width: 60%;\n margin-left: 26%;\n }\n\n .time-line-container .current-time .current-time-bg {\n position: relative;\n top: 15px;\n width: 100px;\n height: 29px;\n line-height: 29px;\n left: -70px;\n font-size: 12px;\n color: #2C2C2C;\n }\n\n .time-line-container .current-time .current-time-bg::before {\n content: '';\n display: inline-block;\n width: 6px;\n height: 6px;\n border-radius: 100%;\n background: #648FFC;\n top: 11px;\n position: absolute;\n right: 30px;\n }\n\n .date-switch-container {\n height: 40px;\n position: relative;\n text-align: center;\n margin: 20px 10px;\n }\n\n .date-switch-container .current-date {\n line-height: 40px;\n height: 22px;\n font-size: 16px;\n color: #2C2C2C;\n text-align: center;\n font-weight: bold;\n }\n\n .date-container {\n width: 40px;\n height: 40px;\n position: absolute;\n right: 0;\n top: 0;\n }\n\n .rec-type-container {\n display: flex;\n justify-content: space-between;\n }\n\n .rec-type-container .rec-type-text {\n padding: 0 15px;\n font-size: 12px;\n color: #2C2C2C;\n }\n\n .rec-type-container .rec-type-switch {\n padding: 0 20px;\n }\n\n .date-container input {\n position: absolute;\n opacity: 0;\n display: inline-block;\n width: 40px;\n height: 40px;\n z-index: 10;\n left: 0;\n }\n\n .date-container label {\n position: absolute;\n left: 0;\n top: 0;\n /* display: none; */\n z-index: 0;\n }\n\n .date-icon {\n display: inline-block;\n width: 40px;\n height: 40px;\n background: url('https://resource.eziot.com/group2/M00/00/6A/CtwQF2F6VieAQrU9AAABP-_Nsqo949.png') no-repeat 100% 100%;\n }\n .select-container {\n padding: 10px;\n display: flex;\n justify-content: space-between;\n }\n\n .advice {\n height: 24px;\n width: 70px;\n display: flex;\n justify-content: space-between;\n line-height: 24px;\n background: #F8F8F8;\n border-radius: 8px;\n }\n\n .advice span {\n width: 40px;\n display: inline-block;\n }\n\n input[type=\"checkbox\"]:not(:checked)+.advice span:first-child {\n box-shadow: 0px 2px 5px 0px rgb(23 45 101 / 20%);\n border-radius: 8px;\n text-align: center;\n\n }\n\n input[type=\"checkbox\"]:checked+.advice span:last-child {\n box-shadow: 0px 2px 5px 0px rgb(23 45 101 / 20%);\n border-radius: 8px;\n text-align: center;\n }\n\n input[type=\"checkbox\"]:not(:checked)+.advice span:first-child svg {\n fill: #648FFC !important;\n }\n\n input[type=\"checkbox\"]:checked+.advice span:last-child svg {\n fill: #648FFC !important;\n }";
+ document.getElementsByTagName("head")[0].appendChild(oS);
+
+ if (getQueryString("begin", this.jSPlugin.url)) {
+ var begin = getQueryString("begin", this.jSPlugin.url);
+ this.date = begin.slice(0, 4) + '/' + begin.slice(4, 6) + '/' + begin.slice(6, 8);
+ this.begin = this.date + " ".concat(begin.slice(8, 10) || "00", ":").concat(begin.slice(10, 12) || "00", ":").concat(begin.slice(12, 14) || "00");
+ this.end = this.date + ' 23:59:59';
+ this.initBegin = this.begin;
+ }
+
+ if (getQueryString("end", this.jSPlugin.url)) {
+ var end = getQueryString("end", this.jSPlugin.url);
+ this.end = this.date + " ".concat(end.slice(8, 10) || "23", ":").concat(end.slice(10, 12) || "59", ":").concat(end.slice(12, 14) || "59");
+ this.initEnd = this.end;
+ } // 鍥炴斁鏃堕棿鏍囬
+
+
+ var mobileRecTitleWrap = document.createElement('div');
+ mobileRecTitleWrap.id = "date-switch-container-wrap";
+ mobileRecTitleWrap.className = "date-switch-container-wrap";
+ mobileRecTitleWrap.style = "";
+ mobileRecTitleWrap.innerHTML = "\n <div class=\"date-switch-container\">\n <div class=\"current-date\" id=\"current-date\">\u4ECA\u65E5\u5F55\u50CF</div>\n <div class=\"date-container\">\n <label for=\"date\">\n <div class=\"date-icon\"></div>\n </label>\n <input type=\"date\" name=\"date\" id=\"date\" />\n </div>\n </div>\n ";
+ insertAfter$1(mobileRecTitleWrap, document.getElementById("".concat(this.jSPlugin.id, "-wrap"))); // 鍥炴斁鏃堕棿绫诲瀷閫夋嫨
+
+ var mobileRecSwitchWrap = document.createElement('div');
+ mobileRecSwitchWrap.id = "rec-type-container-wrap";
+ mobileRecSwitchWrap.className = "rec-type-container-wrap";
+ mobileRecSwitchWrap.style = "";
+ mobileRecSwitchWrap.innerHTML = "\n <div class=\"rec-type-container\">\n <div class=\"rec-type-text\">\u5171\u4E2A<span id=\"recCount\">0</span>\u5F55\u50CF</div>\n <div class=\"rec-type-switch\">\n <label>\n <input type=\"checkbox\" name=\"type\" id=\"cloudType\" value=\"1\" hidden />\n <label for=\"cloudType\" class=\"advice\">\n <span>\n <svg fill=\"#CCCCCC\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"2 0 20 20\">\n <path class=\"st0\" d=\"M12.6,5c-2.3,0.1-4.3,1.4-5.3,3.3L7.2,8.6c-2.4,0.5-4.1,2.5-4.1,4.9c0,2.8,2.4,5,5.2,5h9.9\n c2.4,0,4.3-1.9,4.3-4.2l0-0.2c-0.1-2-1.6-3.5-3.5-3.9l-0.1,0l0-0.2c-0.4-2.8-3-5-6.1-5L12.6,5z\"/>\n </svg>\n </span>\n <span>\n <svg fill=\"#CCCCCC\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"2 0 20 20\">\n <path id=\"\u5F62\u72B6\u7ED3\u5408\" class=\"st0\" d=\"M14.3,4c0.6,0,1.2,0.2,1.7,0.7l0,0L18.3,7C18.7,7.4,19,8,19,8.6l0,0v9c0,1.3-1.1,2.3-2.4,2.3\n\tl0,0H8.4C7.1,20,6,19,6,17.7l0,0V6.3C6,5,7.1,4,8.4,4l0,0H14.3z M9.7,7.2C9.3,7.2,8.9,7.6,8.9,8l0,0v2.5l0,0.1\n\tc0,0.4,0.4,0.6,0.7,0.6c0.4,0,0.8-0.3,0.8-0.8l0,0V8l0-0.1C10.4,7.5,10,7.2,9.7,7.2z M12.2,7.2c-0.4,0-0.8,0.3-0.8,0.8l0,0v2.5\n\tl0,0.1c0,0.4,0.4,0.6,0.7,0.6c0.4,0,0.8-0.3,0.8-0.8l0,0V8l0-0.1C12.9,7.5,12.5,7.2,12.2,7.2z M14.7,7.2c-0.4,0-0.8,0.3-0.8,0.8l0,0\n\tv2.5l0,0.1c0,0.4,0.4,0.6,0.7,0.6c0.4,0,0.8-0.3,0.8-0.8l0,0V8l0-0.1C15.4,7.5,15,7.2,14.7,7.2z\"/>\n </svg>\n </span>\n </label>\n </label>\n </div>\n </div>\n ";
+ insertAfter$1(mobileRecSwitchWrap, mobileRecTitleWrap); // 鍥炴斁鏃堕棿杞�
+
+ var mobileRecWrap = document.createElement('div');
+ mobileRecWrap.id = "mobile-rec-wrap";
+ mobileRecWrap.className = "mobileRec-wrap";
+ mobileRecWrap.style = "";
+ mobileRecWrap.innerHTML = "\n <div class=\"time-line-container\">\n <div class=\"current-time\">\n <div class=\"current-time-bg\" id=\"time-line-current\">2020-01-01 00:00:00</div>\n </div>\n <div class=\"time-line-item-container\">\n <div class=\"time-line-item\" id=\"time-line-item\">\n </div>\n </div>\n </div>\n ";
+ insertAfter$1(mobileRecWrap, mobileRecSwitchWrap);
+
+ var getPalyParam = function getPalyParam(data) {
+ console.log("瀛愮粍浠朵紶鍊煎埌鐖剁粍浠�", data, data.current);
+ var st = data.current;
+ var date = new Date(_this.date).Format('yyyyMMdd').substr(0, 8) + (data.current ? st.replace(/:/g, "") : data.current.replace(/:/g, ""));
+
+ if (_this.initBegin && new Date("".concat(_this.date, " ").concat(data.current)).getTime() < new Date(_this.initBegin).getTime()) {
+ console.log("瓒呰繃闄愬埗鏈�浣庡��");
+ date = new Date(_this.initBegin).Format("yyyyMMddhhmmss");
+ }
+
+ if (_this.initEnd && new Date("".concat(_this.date, " ").concat(data.current)).getTime() > new Date(_this.initEnd).getTime()) {
+ console.log("瓒呰繃闄愬埗鏈�楂樺��");
+ date = new Date(_this.initBegin).Format("yyyyMMddhhmmss");
+ }
+
+ if (_this.type === 'cloud.rec') {
+ var cloudSeek = function cloudSeek() {
+ _this.jSPlugin.seek(date.substr(8, 6), "235959");
+
+ setTimeout(function () {
+ _this.syncTimeLine();
+ }, 6000);
+ };
+
+ if (_this.seekTimer) {
+ clearTimeout(_this.seekTimer);
+ } else {
+ cloudSeek();
+ }
+
+ console.log("this.jsPlug", _this.jSPlugin.params); // 闄愬埗姣�2绉掑彧瑙﹀彂涓�娆℃嫋鍔�
+
+ _this.seekTimer = setTimeout(function () {
+ cloudSeek();
+ clearTimeout(_this.seekTimer);
+ _this.seekTimer = null;
+ }, _this.seekFrequency);
+ } else {
+ var callback = function callback() {
+ setTimeout(function () {
+ _this.disabled = false;
+ }, _this.seekFrequency);
+ };
+
+ var localRecSeek = function localRecSeek(callback) {
+ _this.disabled = true;
+
+ _this.jSPlugin.pause().then(function () {
+ console.log("鏆傚仠鎴愬姛");
+
+ _this.jSPlugin.resume(date).then(function (data) {
+ console.log("鎭㈠鎴愬姛");
+
+ if (_this.jSPlugin.Theme) {
+ _this.jSPlugin.Theme.setDecoderState({
+ play: true
+ });
+ }
+
+ _this.syncTimeLine();
+
+ if (callback) {
+ callback();
+ }
+ });
+ })["catch"](function () {
+ console.log("鏆傚仠澶辫触");
+
+ _this.jSPlugin.resume(date).then(function (data) {
+ console.log("鎭㈠鎴愬姛");
+
+ if (_this.jSPlugin.Theme) {
+ _this.jSPlugin.Theme.setDecoderState({
+ play: true
+ });
+ }
+
+ _this.syncTimeLine();
+
+ if (callback) {
+ callback();
+ }
+ });
+ });
+ };
+
+ if (_this.disabled) {
+ console.log("鎿嶄綔棰戠箒锛岀瓑寰�2绉掑悗鎵ц");
+
+ if (_this.seekTimer) {
+ clearTimeout(_this.seekTimer);
+ }
+
+ _this.seekTimer = setTimeout(function () {
+ localRecSeek(callback);
+ }, _this.seekFrequency);
+ } else {
+ // 闄愬埗姣�2绉掑彧瑙﹀彂涓�娆℃嫋鍔�
+ localRecSeek(callback);
+ }
+ }
+ };
+
+ var ontouchstart = function ontouchstart() {
+ _this.operating = true;
+
+ _this.unSyncTimeLine(); // if (currentTimer) {
+ // clearInterval(currentTimer)
+ // }
+ // if (decoder) {
+ // var stopPromise = decoder.stop();
+ // stopPromise.then(() => {
+ // console.log("鍋滄鎴愬姛")
+ // });
+ // }
+
+ };
+
+ var ontouchmove = function ontouchmove() {// if (currentTimer) {
+ // clearInterval(currentTimer)
+ // }
+ };
+
+ var ontouchend = function ontouchend() {
+ _this.operating = false;
+ console.log("ontouchend"); // if (currentTimer) {
+ // clearInterval(currentTimer)
+ // }
+ };
+
+ this.TimeLineOBJ = new MobileTimeLine({
+ id: "time-line-item",
+ getPalyParam: getPalyParam,
+ ontouchstart: ontouchstart,
+ ontouchmove: ontouchmove,
+ ontouchend: ontouchend
+ });
+ this.fetchDeviceRec(); // 鐩戝惉鏃ユ湡鍙樺寲
+
+ document.getElementById("date").addEventListener('change', function (e) {
+ console.log("鏃ユ湡鍙樺寲", e.target.value); // if(this.initBegin && new Date(`${e.target.value}`.replace(/-/g, "/")).getTime() < new Date(this.initBegin.slice(0, 10)).getTime()) {
+ // console.log("瓒呰繃闄愬埗鏈�浣庡��")
+ // return false;
+ // }
+ // if(this.initEnd && new Date(`${e.target.value}`.replace(/-/g, "/")).getTime() > new Date(this.initEnd.slice(0, 10)).getTime()) {
+ // console.log("瓒呰繃闄愬埗鏈�楂樺��")
+ // return false;
+ // }
+
+ if (_this.initBegin || _this.initEnd) {
+ console.log("鎮ㄥ紑鍚簡鏃堕棿闄愬埗锛屾棤娉曞垏鎹㈡棩鏈�");
+ return false;
+ }
+
+ _this.date = new Date(e.target.value).Format("yyyy/MM/dd");
+ _this.begin = _this.date + ' 00:00:00';
+ _this.end = _this.date + ' 23:59:59';
+
+ _this.fetchDeviceRec();
+
+ _this.jSPlugin.changePlayUrl({
+ type: _this.type,
+ begin: "".concat(new Date(_this.date).Format('yyyyMMdd'), "000000")
+ });
+ });
+ document.getElementById("cloudType").checked = this.type === 'rec';
+ document.getElementById("cloudType").addEventListener('change', function (e) {
+ var recType = e.target.checked ? 2 : 1;
+ _this.type = e.target.checked ? "rec" : 'cloud.rec';
+ console.log("recType", recType);
+
+ _this.fetchDeviceRec();
+
+ _this.jSPlugin.changePlayUrl({
+ type: _this.type,
+ begin: "".concat(new Date(_this.date).Format('yyyyMMdd'), "000000")
+ }).then(function () {
+ console.log("鍒囨崲绫诲瀷鎴愬姛");
+
+ _this.syncTimeLine();
+ }, function (err) {
+ console.log("err", err);
+ })["catch"](function (err) {
+ console.log(err);
+ }); // document.getElementById("cloudType").setAttribute("checked", true);
+ // $("#cloudType").attr("checked", recType == '2');
+ // $("#cloudType .device svg").attr("checked", recType == '2');
+
+ });
+ this.syncTimeLine();
+ }
+
+ _createClass$1(MobileRec, [{
+ key: "fetchDeviceRec",
+ value: function fetchDeviceRec() {
+ var _this2 = this;
+
+ var doRender = function doRender(result) {
+ var len = result.length;
+ document.getElementById("recCount").innerHTML = len;
+ var availArr = [];
+
+ for (var i = len - 1; i >= 0; i--) {
+ var res = result[i];
+ var et = format(res.endTime);
+ var st = format(res.startTime);
+
+ availArr.push({
+ st: st,
+ et: et
+ });
+ } // document.getElementById("time-line-item").style.display = "block";
+
+
+ {
+ _this2.TimeLineOBJ.setDateLine(availArr);
+ }
+ };
+
+ var data = new FormData();
+ data.append("deviceSerial", matchEzopenUrl(this.jSPlugin.url).deviceSerial);
+ data.append("channelNo", matchEzopenUrl(this.jSPlugin.url).channelNo);
+ data.append("accessToken", this.jSPlugin.accessToken);
+ data.append("recType", this.type === 'cloud.rec' ? 1 : 2);
+ data.append("startTime", new Date(this.begin).getTime());
+ data.append("endTime", new Date(this.end).getTime());
+ fetch(this.jSPlugin.env.domain + '/api/lapp/video/by/time', {
+ method: "POST",
+ body: data
+ }).then(function (response) {
+ return response.json();
+ }).then(function (res) {
+ // 鏈湴鍥炴斁
+ if (res.code == 200 && res.data) {
+ var result = [];
+ result = res.data;
+ doRender(result);
+ } else {
+ doRender([]);
+ }
+ });
+ }
+ }, {
+ key: "syncTimeLine",
+ value: function syncTimeLine() {
+ var _this3 = this;
+
+ var dateFormat = function dateFormat(now) {
+ var time = new Date(now);
+ var h = time.getHours(); //杩斿洖鏃ユ湡涓殑灏忔椂鏁帮紙0鍒�23锛�
+
+ var m = time.getMinutes(); //杩斿洖鏃ユ湡涓殑鍒嗛挓鏁帮紙0鍒�59锛�
+
+ var s = time.getSeconds(); //杩斿洖鏃ユ湡涓殑绉掓暟锛�0鍒�59锛�
+
+ return (h > 9 ? h : '0' + h) + ':' + (m > 9 ? m : '0' + m) + ':' + (s > 9 ? s : '0' + s);
+ };
+
+ if (this.timer) {
+ clearInterval(this.timer);
+ }
+
+ this.timer = setInterval(function () {
+ // 瀹氭椂鍣�
+ if (_this3.operating) {
+ console.log("鎿嶄綔涓�");
+ return false;
+ }
+
+ _this3.jSPlugin.getOSDTime().then(function (res) {
+ if (res.data > 0) {
+ _this3.TimeLineOBJ.stepScrollTimeLine(dateFormat(res.data * 1000));
+ } else {
+ console.log("鏈壘鍒板綋鍓嶈幏鍙栨挱鏀炬椂闂达紝绛夊緟涓�...");
+ }
+ })["catch"](function (err) {
+ console.log("鏈壘鍒板綋鍓嶈幏鍙栨挱鏀炬椂闂达紝绛夊緟涓�...");
+ });
+ }, 1000);
+ }
+ }, {
+ key: "unSyncTimeLine",
+ value: function unSyncTimeLine() {
+ if (this.timer) {
+ clearInterval(this.timer);
+ }
+ }
+ }]);
+
+ return MobileRec;
+}();
+
+var Ptz = /*#__PURE__*/function () {
+ function Ptz(jSPlugin) {
+ var _this = this;
+
+ _classCallCheck$1(this, Ptz);
+
+ this.jSPlugin = jSPlugin;
+ console.log("浜戝彴鍒濆鍖�");
+
+ if (document.getElementById(this.jSPlugin.id + "-ez-ptz-item")) {
+ return false;
+ }
+
+ var ptzWrap = document.createElement('div');
+ ptzWrap.id = this.jSPlugin.id + "-ez-ptz-item";
+ ptzWrap.className = "ez-ptz-wrap";
+ ptzWrap.style = "display:none";
+ var oS = document.createElement('style');
+ oS.innerHTML = "\n .ez-ptz-container {\n position: relative;\n width: 80px;\n height: 80px;\n background: rgba(255, 255, 255, 0.80);\n box-shadow: 0px 0px 33px 4px rgb(0 0 0 / 15%);\n border: 1px solid rgba(255, 255, 255, 0.80);\n border-radius: 100%;\n cursor: pointer;\n overflow: hidden;\n user-select: none;\n }\n .ez-ptz-container .ez-ptz-icon.top {\n width: 0;\n height: 0;\n border-left: 3px solid transparent;\n border-right: 3px solid transparent;\n border-bottom: 6px solid #333333;\n position: absolute;\n display: inline-block;\n left: calc(50% - 3px);\n top: 2px;\n }\n\n .ez-ptz-container .ez-ptz-icon.top.active {\n border-bottom-color: #1890FF;\n }\n\n .ez-ptz-container .ez-ptz-icon.bottom {\n width: 0;\n height: 0;\n border-left: 3px solid transparent;\n border-right: 3px solid transparent;\n border-top: 6px solid #333333;\n position: absolute;\n display: inline-block;\n left: calc(50% - 3px);\n bottom: 2px;\n }\n\n .ez-ptz-container .ez-ptz-icon.bottom.active {\n border-top-color: #1890FF;\n }\n\n .ez-ptz-container .ez-ptz-icon.right {\n width: 0;\n height: 0;\n border-top: 3px solid transparent;\n border-bottom: 3px solid transparent;\n border-left: 6px solid #333333;\n position: absolute;\n display: inline-block;\n top: calc(50% - 3px);\n right: 2px;\n }\n\n .ez-ptz-container .ez-ptz-icon.right.active {\n border-left-color: #1890FF;\n }\n\n .ez-ptz-container .ez-ptz-icon.left {\n width: 0;\n height: 0;\n border-top: 3px solid transparent;\n border-bottom: 3px solid transparent;\n border-right: 6px solid #333333;\n position: absolute;\n display: inline-block;\n top: calc(50% - 3px);\n left: 2px;\n }\n\n .ez-ptz-container .ez-ptz-icon.left.active {\n border-right-color: #1890FF;\n }\n\n .ez-ptz-container .ez-ptz-main.center {\n width: 23px;\n height: 23px;\n background: #1890FF;\n border-radius: 100%;\n top: calc(50% - 12.3px);\n left: calc(50% - 12.3px);\n position: absolute;\n }\n\n .ez-ptz-wrap {\n position: absolute;\n right: 20px;\n top: calc(50% - 50px);\n width: 100px;\n height: 100px;\n z-index: 999;\n }\n\n .ez-ptz-close {\n position: absolute;\n color: #FFFFFF;\n top: 0;\n right: 0px;\n }";
+ document.getElementsByTagName("head")[0].appendChild(oS);
+ ptzWrap.innerHTML = "\n <div class=\"ez-ptz-container\" id=\"".concat(this.jSPlugin.id, "-ez-ptz-container\" style=\"position: relative;width: 80px;height: 80px;background: rgba(255, 255, 255, 0.80);box-shadow: 0px 0px 33px 4px rgba(0, 0, 0, 0.15);border: 1px solid rgba(255, 255, 255, 0.80);border-radius: 100%;cursor: pointer;overflow: hidden;user-select: none;\">\n <div class=\"ez-ptz-main center\"></div>\n <div class=\"ez-ptz-icon top active\"></div>\n <div class=\"ez-ptz-icon left active\"></div>\n <div class=\"ez-ptz-icon bottom active\"></div>\n <div class=\"ez-ptz-icon right active\"></div>\n ");
+ document.getElementById("".concat(jSPlugin.id, "-wrap")).appendChild(ptzWrap); // 浜戝彴鎺у埗浜嬩欢缁戝畾
+ // 浜戝彴鎺у埗
+
+ document.getElementById("".concat(this.jSPlugin.id, "-ez-ptz-container")).onmousedown = function (e) {
+ e.preventDefault();
+ console.log("瑙︽懜寮�濮�");
+
+ _this._handlePtzTouch(e, 'start');
+ };
+
+ document.getElementById("".concat(this.jSPlugin.id, "-ez-ptz-container")).onmouseup = function (e) {
+ e.preventDefault();
+ console.log("瑙︽懜缁撴潫");
+
+ _this._handlePtzTouch(e, 'stop');
+ };
+
+ document.getElementById("".concat(this.jSPlugin.id, "-ez-ptz-container")).ontouchstart = function (e) {
+ e.preventDefault();
+ console.log("瑙︽懜寮�濮�");
+
+ _this._handlePtzTouch(e, 'start');
+ };
+
+ document.getElementById("".concat(this.jSPlugin.id, "-ez-ptz-container")).ontouchend = function (e) {
+ e.preventDefault();
+ console.log("瑙︽懜缁撴潫", e);
+
+ _this._handlePtzTouch(e, 'stop');
+ };
+ }
+
+ _createClass$1(Ptz, [{
+ key: "show",
+ value: function show() {
+ document.getElementById("".concat(this.jSPlugin.id, "-ez-ptz-item")).style = "display: inline-block";
+ }
+ }, {
+ key: "hide",
+ value: function hide() {
+ document.getElementById("".concat(this.jSPlugin.id, "-ez-ptz-item")).style = "display: none";
+ }
+ }, {
+ key: "_handlePtzTouch",
+ value: function _handlePtzTouch(e, type) {
+ var _this2 = this;
+
+ var container = document.getElementById("".concat(this.jSPlugin.id, "-ez-ptz-container")).getBoundingClientRect();
+ var containerCenterX = container.left + 41;
+ var containerCenterY = container.top + 41;
+ var eventX = e.x || e.changedTouches[0].clientX;
+ var eventY = e.y || e.changedTouches[0].clientY;
+ var left = eventX - containerCenterX;
+ var top = eventY - containerCenterY;
+ var direction = 0; //鎿嶄綔鍛戒护锛�0-涓婏紝1-涓嬶紝2-宸︼紝3-鍙筹紝4-宸︿笂锛�5-宸︿笅锛�6-鍙充笂锛�7-鍙充笅锛�8-鏀惧ぇ锛�9-缂╁皬锛�10-杩戠劍璺濓紝11-杩滅劍璺�
+
+ var url = this.jSPlugin.env.domain + "/api/lapp/device/ptz/start"; // var nextPtzImg = ptzNormalImg;
+ // var nextPtzImgFailed = ptzNormalImg;
+ // 鍒よ鏂逛綅
+
+ if (Math.abs(left) > Math.abs(top)) {
+ if (left > 0) {
+ direction = 3; // nextPtzImg = ptzRightImgSuccess;
+ // nextPtzImgFailed = ptzRightImgFailed;
+ } else {
+ direction = 2; // nextPtzImg = ptzLeftImgSuccess;
+ // nextPtzImgFailed = ptzLeftImgFailed;
+ }
+ } else {
+ if (top > 0) {
+ direction = 1; // nextPtzImg = ptzDownImgSuccess;
+ // nextPtzImgFailed = ptzDownImgFailed;
+ } else {
+ direction = 0; // nextPtzImg = ptzTopImgSuccess;
+ // nextPtzImgFailed = ptzTopImgFailed;
+ }
+ } // 鍏煎鐢婚潰鏃嬭浆90搴�
+
+
+ if (/^rotate\(90/.test(document.getElementById("".concat(this.jSPlugin.id, "-wrap")).style.transform)) {
+ switch (direction) {
+ case 0:
+ direction = 2; // 涓婅浆鍖栦负宸�
+
+ break;
+
+ case 1:
+ direction = 3; // 涓嬭浆鍖栦负鍙�
+
+ break;
+
+ case 2:
+ direction = 1; // 宸﹁浆鍖栦负涓�
+
+ break;
+
+ case 3:
+ direction = 0; // 鍙宠浆鍖栦负涓�
+
+ break;
+ }
+ }
+
+ document.getElementById("".concat(this.jSPlugin.id, "-ez-ptz-container")).style = "background-image:linear-gradient(".concat(direction === 0 ? 180 : direction === 1 ? 0 : direction === 2 ? 90 : 270, "deg, #1d8dd8 0%, rgba(100,143,252,0.00) 30%)");
+
+ if (type === 'stop') {
+ url = this.jSPlugin.env.domain + '/api/lapp/device/ptz/stop';
+ document.getElementById("".concat(this.jSPlugin.id, "-ez-ptz-container")).style = "";
+ }
+
+ var data = new FormData();
+ data.append("deviceSerial", matchEzopenUrl(this.jSPlugin.url).deviceSerial);
+ data.append("channelNo", matchEzopenUrl(this.jSPlugin.url).channelNo);
+ data.append("speed", 1);
+ data.append("direction", direction);
+ data.append("accessToken", this.jSPlugin.accessToken);
+ fetch(url, {
+ method: "POST",
+ body: data
+ }).then(function (response) {
+ return response.json();
+ }).then(function (rt) {
+ if (rt.code == 200) ; else {
+ //document.getElementById('ptz-img-container').childNodes[0].src = nextPtzImgFailed;
+ // layer.msg(data.msg);
+ if (rt.code == 60005 || rt.code == 60002 || rt.code == 60003 || rt.code == 60004) {
+ document.getElementById("".concat(_this2.jSPlugin.id, "-ez-ptz-container")).style = "background-image:linear-gradient(".concat(direction === 0 ? 180 : direction === 1 ? 0 : direction === 2 ? 90 : 270, "deg, #f45656 0%, rgba(100,143,252,0.00) 30%)");
+ }
+ }
+ })["catch"](function (err) {
+ console.log("浜戝彴璋冪敤寮傚父", err);
+ });
+ }
+ }]);
+
+ return Ptz;
+}();
+
+(function (f) {
+ if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === "object" && typeof module !== "undefined") {
+ module.exports = f();
+ } else if (typeof define === "function" && define.amd) {
+ define([], f);
+ } else {
+ var g;
+
+ if (typeof window !== "undefined") {
+ g = window;
+ } else if (typeof global !== "undefined") {
+ g = global;
+ } else if (typeof self !== "undefined") {
+ g = self;
+ } else {
+ g = this;
+ }
+
+ g.adapter = f();
+ }
+})(function () {
+ return function () {
+ function r(e, n, t) {
+ function o(i, f) {
+ if (!n[i]) {
+ if (!e[i]) {
+ var c = "function" == typeof require && require;
+ if (!f && c) return c(i, !0);
+ if (u) return u(i, !0);
+ var a = new Error("Cannot find module '" + i + "'");
+ throw a.code = "MODULE_NOT_FOUND", a;
+ }
+
+ var p = n[i] = {
+ exports: {}
+ };
+ e[i][0].call(p.exports, function (r) {
+ var n = e[i][1][r];
+ return o(n || r);
+ }, p, p.exports, r, e, n, t);
+ }
+
+ return n[i].exports;
+ }
+
+ for (var u = "function" == typeof require && require, i = 0; i < t.length; i++) {
+ o(t[i]);
+ }
+
+ return o;
+ }
+
+ return r;
+ }()({
+ 1: [function (require, module, exports) {
+
+ var _adapter_factory = require('./adapter_factory.js');
+
+ var adapter = (0, _adapter_factory.adapterFactory)({
+ window: window
+ });
+ window.adapter = adapter;
+ module.exports = adapter; // this is the difference from adapter_core.
+ }, {
+ "./adapter_factory.js": 2
+ }],
+ 2: [function (require, module, exports) {
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+ exports.adapterFactory = adapterFactory;
+
+ var _utils = require('./utils');
+
+ var utils = _interopRequireWildcard(_utils);
+
+ var _chrome_shim = require('./chrome/chrome_shim');
+
+ var chromeShim = _interopRequireWildcard(_chrome_shim);
+
+ var _edge_shim = require('./edge/edge_shim');
+
+ var edgeShim = _interopRequireWildcard(_edge_shim);
+
+ var _firefox_shim = require('./firefox/firefox_shim');
+
+ var firefoxShim = _interopRequireWildcard(_firefox_shim);
+
+ var _safari_shim = require('./safari/safari_shim');
+
+ var safariShim = _interopRequireWildcard(_safari_shim);
+
+ var _common_shim = require('./common_shim');
+
+ var commonShim = _interopRequireWildcard(_common_shim);
+
+ function _interopRequireWildcard(obj) {
+ if (obj && obj.__esModule) {
+ return obj;
+ } else {
+ var newObj = {};
+
+ if (obj != null) {
+ for (var key in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];
+ }
+ }
+
+ newObj["default"] = obj;
+ return newObj;
+ }
+ } // Shimming starts here.
+
+ /*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree.
+ */
+
+
+ function adapterFactory() {
+ var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
+ window = _ref.window;
+
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
+ shimChrome: true,
+ shimFirefox: true,
+ shimEdge: true,
+ shimSafari: true
+ }; // Utils.
+
+ var logging = utils.log;
+ var browserDetails = utils.detectBrowser(window);
+ var adapter = {
+ browserDetails: browserDetails,
+ commonShim: commonShim,
+ extractVersion: utils.extractVersion,
+ disableLog: utils.disableLog,
+ disableWarnings: utils.disableWarnings
+ }; // Shim browser if found.
+
+ switch (browserDetails.browser) {
+ case 'chrome':
+ if (!chromeShim || !chromeShim.shimPeerConnection || !options.shimChrome) {
+ logging('Chrome shim is not included in this adapter release.');
+ return adapter;
+ }
+
+ logging('adapter.js shimming chrome.'); // Export to the adapter global object visible in the browser.
+
+ adapter.browserShim = chromeShim;
+ chromeShim.shimGetUserMedia(window);
+ chromeShim.shimMediaStream(window);
+ chromeShim.shimPeerConnection(window);
+ chromeShim.shimOnTrack(window);
+ chromeShim.shimAddTrackRemoveTrack(window);
+ chromeShim.shimGetSendersWithDtmf(window);
+ chromeShim.shimGetStats(window);
+ chromeShim.shimSenderReceiverGetStats(window);
+ chromeShim.fixNegotiationNeeded(window);
+ commonShim.shimRTCIceCandidate(window);
+ commonShim.shimConnectionState(window);
+ commonShim.shimMaxMessageSize(window);
+ commonShim.shimSendThrowTypeError(window);
+ commonShim.removeAllowExtmapMixed(window);
+ break;
+
+ case 'firefox':
+ if (!firefoxShim || !firefoxShim.shimPeerConnection || !options.shimFirefox) {
+ logging('Firefox shim is not included in this adapter release.');
+ return adapter;
+ }
+
+ logging('adapter.js shimming firefox.'); // Export to the adapter global object visible in the browser.
+
+ adapter.browserShim = firefoxShim;
+ firefoxShim.shimGetUserMedia(window);
+ firefoxShim.shimPeerConnection(window);
+ firefoxShim.shimOnTrack(window);
+ firefoxShim.shimRemoveStream(window);
+ firefoxShim.shimSenderGetStats(window);
+ firefoxShim.shimReceiverGetStats(window);
+ firefoxShim.shimRTCDataChannel(window);
+ firefoxShim.shimAddTransceiver(window);
+ firefoxShim.shimCreateOffer(window);
+ firefoxShim.shimCreateAnswer(window);
+ commonShim.shimRTCIceCandidate(window);
+ commonShim.shimConnectionState(window);
+ commonShim.shimMaxMessageSize(window);
+ commonShim.shimSendThrowTypeError(window);
+ break;
+
+ case 'edge':
+ if (!edgeShim || !edgeShim.shimPeerConnection || !options.shimEdge) {
+ logging('MS edge shim is not included in this adapter release.');
+ return adapter;
+ }
+
+ logging('adapter.js shimming edge.'); // Export to the adapter global object visible in the browser.
+
+ adapter.browserShim = edgeShim;
+ edgeShim.shimGetUserMedia(window);
+ edgeShim.shimGetDisplayMedia(window);
+ edgeShim.shimPeerConnection(window);
+ edgeShim.shimReplaceTrack(window); // the edge shim implements the full RTCIceCandidate object.
+
+ commonShim.shimMaxMessageSize(window);
+ commonShim.shimSendThrowTypeError(window);
+ break;
+
+ case 'safari':
+ if (!safariShim || !options.shimSafari) {
+ logging('Safari shim is not included in this adapter release.');
+ return adapter;
+ }
+
+ logging('adapter.js shimming safari.'); // Export to the adapter global object visible in the browser.
+
+ adapter.browserShim = safariShim;
+ safariShim.shimRTCIceServerUrls(window);
+ safariShim.shimCreateOfferLegacy(window);
+ safariShim.shimCallbacksAPI(window);
+ safariShim.shimLocalStreamsAPI(window);
+ safariShim.shimRemoteStreamsAPI(window);
+ safariShim.shimTrackEventTransceiver(window);
+ safariShim.shimGetUserMedia(window);
+ commonShim.shimRTCIceCandidate(window);
+ commonShim.shimMaxMessageSize(window);
+ commonShim.shimSendThrowTypeError(window);
+ commonShim.removeAllowExtmapMixed(window);
+ break;
+
+ default:
+ logging('Unsupported browser!');
+ break;
+ }
+
+ return adapter;
+ } // Browser shims.
+
+ }, {
+ "./chrome/chrome_shim": 3,
+ "./common_shim": 6,
+ "./edge/edge_shim": 7,
+ "./firefox/firefox_shim": 11,
+ "./safari/safari_shim": 14,
+ "./utils": 15
+ }],
+ 3: [function (require, module, exports) {
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+ exports.shimGetDisplayMedia = exports.shimGetUserMedia = undefined;
+
+ var _typeof$1 = 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);
+ };
+
+ var _getusermedia = require('./getusermedia');
+
+ Object.defineProperty(exports, 'shimGetUserMedia', {
+ enumerable: true,
+ get: function get() {
+ return _getusermedia.shimGetUserMedia;
+ }
+ });
+
+ var _getdisplaymedia = require('./getdisplaymedia');
+
+ Object.defineProperty(exports, 'shimGetDisplayMedia', {
+ enumerable: true,
+ get: function get() {
+ return _getdisplaymedia.shimGetDisplayMedia;
+ }
+ });
+ exports.shimMediaStream = shimMediaStream;
+ exports.shimOnTrack = shimOnTrack;
+ exports.shimGetSendersWithDtmf = shimGetSendersWithDtmf;
+ exports.shimGetStats = shimGetStats;
+ exports.shimSenderReceiverGetStats = shimSenderReceiverGetStats;
+ exports.shimAddTrackRemoveTrackWithNative = shimAddTrackRemoveTrackWithNative;
+ exports.shimAddTrackRemoveTrack = shimAddTrackRemoveTrack;
+ exports.shimPeerConnection = shimPeerConnection;
+ exports.fixNegotiationNeeded = fixNegotiationNeeded;
+
+ var _utils = require('../utils.js');
+
+ var utils = _interopRequireWildcard(_utils);
+
+ function _interopRequireWildcard(obj) {
+ if (obj && obj.__esModule) {
+ return obj;
+ } else {
+ var newObj = {};
+
+ if (obj != null) {
+ for (var key in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];
+ }
+ }
+
+ newObj["default"] = obj;
+ return newObj;
+ }
+ }
+
+ function _defineProperty(obj, key, value) {
+ if (key in obj) {
+ Object.defineProperty(obj, key, {
+ value: value,
+ enumerable: true,
+ configurable: true,
+ writable: true
+ });
+ } else {
+ obj[key] = value;
+ }
+
+ return obj;
+ }
+
+ function shimMediaStream(window) {
+ window.MediaStream = window.MediaStream || window.webkitMediaStream;
+ }
+
+ function shimOnTrack(window) {
+ if ((typeof window === 'undefined' ? 'undefined' : _typeof$1(window)) === 'object' && window.RTCPeerConnection && !('ontrack' in window.RTCPeerConnection.prototype)) {
+ Object.defineProperty(window.RTCPeerConnection.prototype, 'ontrack', {
+ get: function get() {
+ return this._ontrack;
+ },
+ set: function set(f) {
+ if (this._ontrack) {
+ this.removeEventListener('track', this._ontrack);
+ }
+
+ this.addEventListener('track', this._ontrack = f);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ var origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription;
+
+ window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription() {
+ var _this = this;
+
+ if (!this._ontrackpoly) {
+ this._ontrackpoly = function (e) {
+ // onaddstream does not fire when a track is added to an existing
+ // stream. But stream.onaddtrack is implemented so we use that.
+ e.stream.addEventListener('addtrack', function (te) {
+ var receiver = void 0;
+
+ if (window.RTCPeerConnection.prototype.getReceivers) {
+ receiver = _this.getReceivers().find(function (r) {
+ return r.track && r.track.id === te.track.id;
+ });
+ } else {
+ receiver = {
+ track: te.track
+ };
+ }
+
+ var event = new Event('track');
+ event.track = te.track;
+ event.receiver = receiver;
+ event.transceiver = {
+ receiver: receiver
+ };
+ event.streams = [e.stream];
+
+ _this.dispatchEvent(event);
+ });
+ e.stream.getTracks().forEach(function (track) {
+ var receiver = void 0;
+
+ if (window.RTCPeerConnection.prototype.getReceivers) {
+ receiver = _this.getReceivers().find(function (r) {
+ return r.track && r.track.id === track.id;
+ });
+ } else {
+ receiver = {
+ track: track
+ };
+ }
+
+ var event = new Event('track');
+ event.track = track;
+ event.receiver = receiver;
+ event.transceiver = {
+ receiver: receiver
+ };
+ event.streams = [e.stream];
+
+ _this.dispatchEvent(event);
+ });
+ };
+
+ this.addEventListener('addstream', this._ontrackpoly);
+ }
+
+ return origSetRemoteDescription.apply(this, arguments);
+ };
+ } else {
+ // even if RTCRtpTransceiver is in window, it is only used and
+ // emitted in unified-plan. Unfortunately this means we need
+ // to unconditionally wrap the event.
+ utils.wrapPeerConnectionEvent(window, 'track', function (e) {
+ if (!e.transceiver) {
+ Object.defineProperty(e, 'transceiver', {
+ value: {
+ receiver: e.receiver
+ }
+ });
+ }
+
+ return e;
+ });
+ }
+ }
+
+ function shimGetSendersWithDtmf(window) {
+ // Overrides addTrack/removeTrack, depends on shimAddTrackRemoveTrack.
+ if ((typeof window === 'undefined' ? 'undefined' : _typeof$1(window)) === 'object' && window.RTCPeerConnection && !('getSenders' in window.RTCPeerConnection.prototype) && 'createDTMFSender' in window.RTCPeerConnection.prototype) {
+ var shimSenderWithDtmf = function shimSenderWithDtmf(pc, track) {
+ return {
+ track: track,
+
+ get dtmf() {
+ if (this._dtmf === undefined) {
+ if (track.kind === 'audio') {
+ this._dtmf = pc.createDTMFSender(track);
+ } else {
+ this._dtmf = null;
+ }
+ }
+
+ return this._dtmf;
+ },
+
+ _pc: pc
+ };
+ }; // augment addTrack when getSenders is not available.
+
+
+ if (!window.RTCPeerConnection.prototype.getSenders) {
+ window.RTCPeerConnection.prototype.getSenders = function getSenders() {
+ this._senders = this._senders || [];
+ return this._senders.slice(); // return a copy of the internal state.
+ };
+
+ var origAddTrack = window.RTCPeerConnection.prototype.addTrack;
+
+ window.RTCPeerConnection.prototype.addTrack = function addTrack(track, stream) {
+ var sender = origAddTrack.apply(this, arguments);
+
+ if (!sender) {
+ sender = shimSenderWithDtmf(this, track);
+
+ this._senders.push(sender);
+ }
+
+ return sender;
+ };
+
+ var origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack;
+
+ window.RTCPeerConnection.prototype.removeTrack = function removeTrack(sender) {
+ origRemoveTrack.apply(this, arguments);
+
+ var idx = this._senders.indexOf(sender);
+
+ if (idx !== -1) {
+ this._senders.splice(idx, 1);
+ }
+ };
+ }
+
+ var origAddStream = window.RTCPeerConnection.prototype.addStream;
+
+ window.RTCPeerConnection.prototype.addStream = function addStream(stream) {
+ var _this2 = this;
+
+ this._senders = this._senders || [];
+ origAddStream.apply(this, [stream]);
+ stream.getTracks().forEach(function (track) {
+ _this2._senders.push(shimSenderWithDtmf(_this2, track));
+ });
+ };
+
+ var origRemoveStream = window.RTCPeerConnection.prototype.removeStream;
+
+ window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
+ var _this3 = this;
+
+ this._senders = this._senders || [];
+ origRemoveStream.apply(this, [stream]);
+ stream.getTracks().forEach(function (track) {
+ var sender = _this3._senders.find(function (s) {
+ return s.track === track;
+ });
+
+ if (sender) {
+ // remove sender
+ _this3._senders.splice(_this3._senders.indexOf(sender), 1);
+ }
+ });
+ };
+ } else if ((typeof window === 'undefined' ? 'undefined' : _typeof$1(window)) === 'object' && window.RTCPeerConnection && 'getSenders' in window.RTCPeerConnection.prototype && 'createDTMFSender' in window.RTCPeerConnection.prototype && window.RTCRtpSender && !('dtmf' in window.RTCRtpSender.prototype)) {
+ var origGetSenders = window.RTCPeerConnection.prototype.getSenders;
+
+ window.RTCPeerConnection.prototype.getSenders = function getSenders() {
+ var _this4 = this;
+
+ var senders = origGetSenders.apply(this, []);
+ senders.forEach(function (sender) {
+ return sender._pc = _this4;
+ });
+ return senders;
+ };
+
+ Object.defineProperty(window.RTCRtpSender.prototype, 'dtmf', {
+ get: function get() {
+ if (this._dtmf === undefined) {
+ if (this.track.kind === 'audio') {
+ this._dtmf = this._pc.createDTMFSender(this.track);
+ } else {
+ this._dtmf = null;
+ }
+ }
+
+ return this._dtmf;
+ }
+ });
+ }
+ }
+
+ function shimGetStats(window) {
+ if (!window.RTCPeerConnection) {
+ return;
+ }
+
+ var origGetStats = window.RTCPeerConnection.prototype.getStats;
+
+ window.RTCPeerConnection.prototype.getStats = function getStats() {
+ var _this5 = this;
+
+ var _arguments = Array.prototype.slice.call(arguments),
+ selector = _arguments[0],
+ onSucc = _arguments[1],
+ onErr = _arguments[2]; // If selector is a function then we are in the old style stats so just
+ // pass back the original getStats format to avoid breaking old users.
+
+
+ if (arguments.length > 0 && typeof selector === 'function') {
+ return origGetStats.apply(this, arguments);
+ } // When spec-style getStats is supported, return those when called with
+ // either no arguments or the selector argument is null.
+
+
+ if (origGetStats.length === 0 && (arguments.length === 0 || typeof selector !== 'function')) {
+ return origGetStats.apply(this, []);
+ }
+
+ var fixChromeStats_ = function fixChromeStats_(response) {
+ var standardReport = {};
+ var reports = response.result();
+ reports.forEach(function (report) {
+ var standardStats = {
+ id: report.id,
+ timestamp: report.timestamp,
+ type: {
+ localcandidate: 'local-candidate',
+ remotecandidate: 'remote-candidate'
+ }[report.type] || report.type
+ };
+ report.names().forEach(function (name) {
+ standardStats[name] = report.stat(name);
+ });
+ standardReport[standardStats.id] = standardStats;
+ });
+ return standardReport;
+ }; // shim getStats with maplike support
+
+
+ var makeMapStats = function makeMapStats(stats) {
+ return new Map(Object.keys(stats).map(function (key) {
+ return [key, stats[key]];
+ }));
+ };
+
+ if (arguments.length >= 2) {
+ var successCallbackWrapper_ = function successCallbackWrapper_(response) {
+ onSucc(makeMapStats(fixChromeStats_(response)));
+ };
+
+ return origGetStats.apply(this, [successCallbackWrapper_, selector]);
+ } // promise-support
+
+
+ return new Promise(function (resolve, reject) {
+ origGetStats.apply(_this5, [function (response) {
+ resolve(makeMapStats(fixChromeStats_(response)));
+ }, reject]);
+ }).then(onSucc, onErr);
+ };
+ }
+
+ function shimSenderReceiverGetStats(window) {
+ if (!((typeof window === 'undefined' ? 'undefined' : _typeof$1(window)) === 'object' && window.RTCPeerConnection && window.RTCRtpSender && window.RTCRtpReceiver)) {
+ return;
+ } // shim sender stats.
+
+
+ if (!('getStats' in window.RTCRtpSender.prototype)) {
+ var origGetSenders = window.RTCPeerConnection.prototype.getSenders;
+
+ if (origGetSenders) {
+ window.RTCPeerConnection.prototype.getSenders = function getSenders() {
+ var _this6 = this;
+
+ var senders = origGetSenders.apply(this, []);
+ senders.forEach(function (sender) {
+ return sender._pc = _this6;
+ });
+ return senders;
+ };
+ }
+
+ var origAddTrack = window.RTCPeerConnection.prototype.addTrack;
+
+ if (origAddTrack) {
+ window.RTCPeerConnection.prototype.addTrack = function addTrack() {
+ var sender = origAddTrack.apply(this, arguments);
+ sender._pc = this;
+ return sender;
+ };
+ }
+
+ window.RTCRtpSender.prototype.getStats = function getStats() {
+ var sender = this;
+ return this._pc.getStats().then(function (result) {
+ return (
+ /* Note: this will include stats of all senders that
+ * send a track with the same id as sender.track as
+ * it is not possible to identify the RTCRtpSender.
+ */
+ utils.filterStats(result, sender.track, true)
+ );
+ });
+ };
+ } // shim receiver stats.
+
+
+ if (!('getStats' in window.RTCRtpReceiver.prototype)) {
+ var origGetReceivers = window.RTCPeerConnection.prototype.getReceivers;
+
+ if (origGetReceivers) {
+ window.RTCPeerConnection.prototype.getReceivers = function getReceivers() {
+ var _this7 = this;
+
+ var receivers = origGetReceivers.apply(this, []);
+ receivers.forEach(function (receiver) {
+ return receiver._pc = _this7;
+ });
+ return receivers;
+ };
+ }
+
+ utils.wrapPeerConnectionEvent(window, 'track', function (e) {
+ e.receiver._pc = e.srcElement;
+ return e;
+ });
+
+ window.RTCRtpReceiver.prototype.getStats = function getStats() {
+ var receiver = this;
+ return this._pc.getStats().then(function (result) {
+ return utils.filterStats(result, receiver.track, false);
+ });
+ };
+ }
+
+ if (!('getStats' in window.RTCRtpSender.prototype && 'getStats' in window.RTCRtpReceiver.prototype)) {
+ return;
+ } // shim RTCPeerConnection.getStats(track).
+
+
+ var origGetStats = window.RTCPeerConnection.prototype.getStats;
+
+ window.RTCPeerConnection.prototype.getStats = function getStats() {
+ if (arguments.length > 0 && arguments[0] instanceof window.MediaStreamTrack) {
+ var track = arguments[0];
+ var sender = void 0;
+ var receiver = void 0;
+ var err = void 0;
+ this.getSenders().forEach(function (s) {
+ if (s.track === track) {
+ if (sender) {
+ err = true;
+ } else {
+ sender = s;
+ }
+ }
+ });
+ this.getReceivers().forEach(function (r) {
+ if (r.track === track) {
+ if (receiver) {
+ err = true;
+ } else {
+ receiver = r;
+ }
+ }
+
+ return r.track === track;
+ });
+
+ if (err || sender && receiver) {
+ return Promise.reject(new DOMException('There are more than one sender or receiver for the track.', 'InvalidAccessError'));
+ } else if (sender) {
+ return sender.getStats();
+ } else if (receiver) {
+ return receiver.getStats();
+ }
+
+ return Promise.reject(new DOMException('There is no sender or receiver for the track.', 'InvalidAccessError'));
+ }
+
+ return origGetStats.apply(this, arguments);
+ };
+ }
+
+ function shimAddTrackRemoveTrackWithNative(window) {
+ // shim addTrack/removeTrack with native variants in order to make
+ // the interactions with legacy getLocalStreams behave as in other browsers.
+ // Keeps a mapping stream.id => [stream, rtpsenders...]
+ window.RTCPeerConnection.prototype.getLocalStreams = function getLocalStreams() {
+ var _this8 = this;
+
+ this._shimmedLocalStreams = this._shimmedLocalStreams || {};
+ return Object.keys(this._shimmedLocalStreams).map(function (streamId) {
+ return _this8._shimmedLocalStreams[streamId][0];
+ });
+ };
+
+ var origAddTrack = window.RTCPeerConnection.prototype.addTrack;
+
+ window.RTCPeerConnection.prototype.addTrack = function addTrack(track, stream) {
+ if (!stream) {
+ return origAddTrack.apply(this, arguments);
+ }
+
+ this._shimmedLocalStreams = this._shimmedLocalStreams || {};
+ var sender = origAddTrack.apply(this, arguments);
+
+ if (!this._shimmedLocalStreams[stream.id]) {
+ this._shimmedLocalStreams[stream.id] = [stream, sender];
+ } else if (this._shimmedLocalStreams[stream.id].indexOf(sender) === -1) {
+ this._shimmedLocalStreams[stream.id].push(sender);
+ }
+
+ return sender;
+ };
+
+ var origAddStream = window.RTCPeerConnection.prototype.addStream;
+
+ window.RTCPeerConnection.prototype.addStream = function addStream(stream) {
+ var _this9 = this;
+
+ this._shimmedLocalStreams = this._shimmedLocalStreams || {};
+ stream.getTracks().forEach(function (track) {
+ var alreadyExists = _this9.getSenders().find(function (s) {
+ return s.track === track;
+ });
+
+ if (alreadyExists) {
+ throw new DOMException('Track already exists.', 'InvalidAccessError');
+ }
+ });
+ var existingSenders = this.getSenders();
+ origAddStream.apply(this, arguments);
+ var newSenders = this.getSenders().filter(function (newSender) {
+ return existingSenders.indexOf(newSender) === -1;
+ });
+ this._shimmedLocalStreams[stream.id] = [stream].concat(newSenders);
+ };
+
+ var origRemoveStream = window.RTCPeerConnection.prototype.removeStream;
+
+ window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
+ this._shimmedLocalStreams = this._shimmedLocalStreams || {};
+ delete this._shimmedLocalStreams[stream.id];
+ return origRemoveStream.apply(this, arguments);
+ };
+
+ var origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack;
+
+ window.RTCPeerConnection.prototype.removeTrack = function removeTrack(sender) {
+ var _this10 = this;
+
+ this._shimmedLocalStreams = this._shimmedLocalStreams || {};
+
+ if (sender) {
+ Object.keys(this._shimmedLocalStreams).forEach(function (streamId) {
+ var idx = _this10._shimmedLocalStreams[streamId].indexOf(sender);
+
+ if (idx !== -1) {
+ _this10._shimmedLocalStreams[streamId].splice(idx, 1);
+ }
+
+ if (_this10._shimmedLocalStreams[streamId].length === 1) {
+ delete _this10._shimmedLocalStreams[streamId];
+ }
+ });
+ }
+
+ return origRemoveTrack.apply(this, arguments);
+ };
+ }
+
+ function shimAddTrackRemoveTrack(window) {
+ if (!window.RTCPeerConnection) {
+ return;
+ }
+
+ var browserDetails = utils.detectBrowser(window); // shim addTrack and removeTrack.
+
+ if (window.RTCPeerConnection.prototype.addTrack && browserDetails.version >= 65) {
+ return shimAddTrackRemoveTrackWithNative(window);
+ } // also shim pc.getLocalStreams when addTrack is shimmed
+ // to return the original streams.
+
+
+ var origGetLocalStreams = window.RTCPeerConnection.prototype.getLocalStreams;
+
+ window.RTCPeerConnection.prototype.getLocalStreams = function getLocalStreams() {
+ var _this11 = this;
+
+ var nativeStreams = origGetLocalStreams.apply(this);
+ this._reverseStreams = this._reverseStreams || {};
+ return nativeStreams.map(function (stream) {
+ return _this11._reverseStreams[stream.id];
+ });
+ };
+
+ var origAddStream = window.RTCPeerConnection.prototype.addStream;
+
+ window.RTCPeerConnection.prototype.addStream = function addStream(stream) {
+ var _this12 = this;
+
+ this._streams = this._streams || {};
+ this._reverseStreams = this._reverseStreams || {};
+ stream.getTracks().forEach(function (track) {
+ var alreadyExists = _this12.getSenders().find(function (s) {
+ return s.track === track;
+ });
+
+ if (alreadyExists) {
+ throw new DOMException('Track already exists.', 'InvalidAccessError');
+ }
+ }); // Add identity mapping for consistency with addTrack.
+ // Unless this is being used with a stream from addTrack.
+
+ if (!this._reverseStreams[stream.id]) {
+ var newStream = new window.MediaStream(stream.getTracks());
+ this._streams[stream.id] = newStream;
+ this._reverseStreams[newStream.id] = stream;
+ stream = newStream;
+ }
+
+ origAddStream.apply(this, [stream]);
+ };
+
+ var origRemoveStream = window.RTCPeerConnection.prototype.removeStream;
+
+ window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
+ this._streams = this._streams || {};
+ this._reverseStreams = this._reverseStreams || {};
+ origRemoveStream.apply(this, [this._streams[stream.id] || stream]);
+ delete this._reverseStreams[this._streams[stream.id] ? this._streams[stream.id].id : stream.id];
+ delete this._streams[stream.id];
+ };
+
+ window.RTCPeerConnection.prototype.addTrack = function addTrack(track, stream) {
+ var _this13 = this;
+
+ if (this.signalingState === 'closed') {
+ throw new DOMException('The RTCPeerConnection\'s signalingState is \'closed\'.', 'InvalidStateError');
+ }
+
+ var streams = [].slice.call(arguments, 1);
+
+ if (streams.length !== 1 || !streams[0].getTracks().find(function (t) {
+ return t === track;
+ })) {
+ // this is not fully correct but all we can manage without
+ // [[associated MediaStreams]] internal slot.
+ throw new DOMException('The adapter.js addTrack polyfill only supports a single ' + ' stream which is associated with the specified track.', 'NotSupportedError');
+ }
+
+ var alreadyExists = this.getSenders().find(function (s) {
+ return s.track === track;
+ });
+
+ if (alreadyExists) {
+ throw new DOMException('Track already exists.', 'InvalidAccessError');
+ }
+
+ this._streams = this._streams || {};
+ this._reverseStreams = this._reverseStreams || {};
+ var oldStream = this._streams[stream.id];
+
+ if (oldStream) {
+ // this is using odd Chrome behaviour, use with caution:
+ // https://bugs.chromium.org/p/webrtc/issues/detail?id=7815
+ // Note: we rely on the high-level addTrack/dtmf shim to
+ // create the sender with a dtmf sender.
+ oldStream.addTrack(track); // Trigger ONN async.
+
+ Promise.resolve().then(function () {
+ _this13.dispatchEvent(new Event('negotiationneeded'));
+ });
+ } else {
+ var newStream = new window.MediaStream([track]);
+ this._streams[stream.id] = newStream;
+ this._reverseStreams[newStream.id] = stream;
+ this.addStream(newStream);
+ }
+
+ return this.getSenders().find(function (s) {
+ return s.track === track;
+ });
+ }; // replace the internal stream id with the external one and
+ // vice versa.
+
+
+ function replaceInternalStreamId(pc, description) {
+ var sdp = description.sdp;
+ Object.keys(pc._reverseStreams || []).forEach(function (internalId) {
+ var externalStream = pc._reverseStreams[internalId];
+ var internalStream = pc._streams[externalStream.id];
+ sdp = sdp.replace(new RegExp(internalStream.id, 'g'), externalStream.id);
+ });
+ return new RTCSessionDescription({
+ type: description.type,
+ sdp: sdp
+ });
+ }
+
+ function replaceExternalStreamId(pc, description) {
+ var sdp = description.sdp;
+ Object.keys(pc._reverseStreams || []).forEach(function (internalId) {
+ var externalStream = pc._reverseStreams[internalId];
+ var internalStream = pc._streams[externalStream.id];
+ sdp = sdp.replace(new RegExp(externalStream.id, 'g'), internalStream.id);
+ });
+ return new RTCSessionDescription({
+ type: description.type,
+ sdp: sdp
+ });
+ }
+
+ ['createOffer', 'createAnswer'].forEach(function (method) {
+ var nativeMethod = window.RTCPeerConnection.prototype[method];
+
+ var methodObj = _defineProperty({}, method, function () {
+ var _this14 = this;
+
+ var args = arguments;
+ var isLegacyCall = arguments.length && typeof arguments[0] === 'function';
+
+ if (isLegacyCall) {
+ return nativeMethod.apply(this, [function (description) {
+ var desc = replaceInternalStreamId(_this14, description);
+ args[0].apply(null, [desc]);
+ }, function (err) {
+ if (args[1]) {
+ args[1].apply(null, err);
+ }
+ }, arguments[2]]);
+ }
+
+ return nativeMethod.apply(this, arguments).then(function (description) {
+ return replaceInternalStreamId(_this14, description);
+ });
+ });
+
+ window.RTCPeerConnection.prototype[method] = methodObj[method];
+ });
+ var origSetLocalDescription = window.RTCPeerConnection.prototype.setLocalDescription;
+
+ window.RTCPeerConnection.prototype.setLocalDescription = function setLocalDescription() {
+ if (!arguments.length || !arguments[0].type) {
+ return origSetLocalDescription.apply(this, arguments);
+ }
+
+ arguments[0] = replaceExternalStreamId(this, arguments[0]);
+ return origSetLocalDescription.apply(this, arguments);
+ }; // TODO: mangle getStats: https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamstats-streamidentifier
+
+
+ var origLocalDescription = Object.getOwnPropertyDescriptor(window.RTCPeerConnection.prototype, 'localDescription');
+ Object.defineProperty(window.RTCPeerConnection.prototype, 'localDescription', {
+ get: function get() {
+ var description = origLocalDescription.get.apply(this);
+
+ if (description.type === '') {
+ return description;
+ }
+
+ return replaceInternalStreamId(this, description);
+ }
+ });
+
+ window.RTCPeerConnection.prototype.removeTrack = function removeTrack(sender) {
+ var _this15 = this;
+
+ if (this.signalingState === 'closed') {
+ throw new DOMException('The RTCPeerConnection\'s signalingState is \'closed\'.', 'InvalidStateError');
+ } // We can not yet check for sender instanceof RTCRtpSender
+ // since we shim RTPSender. So we check if sender._pc is set.
+
+
+ if (!sender._pc) {
+ throw new DOMException('Argument 1 of RTCPeerConnection.removeTrack ' + 'does not implement interface RTCRtpSender.', 'TypeError');
+ }
+
+ var isLocal = sender._pc === this;
+
+ if (!isLocal) {
+ throw new DOMException('Sender was not created by this connection.', 'InvalidAccessError');
+ } // Search for the native stream the senders track belongs to.
+
+
+ this._streams = this._streams || {};
+ var stream = void 0;
+ Object.keys(this._streams).forEach(function (streamid) {
+ var hasTrack = _this15._streams[streamid].getTracks().find(function (track) {
+ return sender.track === track;
+ });
+
+ if (hasTrack) {
+ stream = _this15._streams[streamid];
+ }
+ });
+
+ if (stream) {
+ if (stream.getTracks().length === 1) {
+ // if this is the last track of the stream, remove the stream. This
+ // takes care of any shimmed _senders.
+ this.removeStream(this._reverseStreams[stream.id]);
+ } else {
+ // relying on the same odd chrome behaviour as above.
+ stream.removeTrack(sender.track);
+ }
+
+ this.dispatchEvent(new Event('negotiationneeded'));
+ }
+ };
+ }
+
+ function shimPeerConnection(window) {
+ var browserDetails = utils.detectBrowser(window);
+
+ if (!window.RTCPeerConnection && window.webkitRTCPeerConnection) {
+ // very basic support for old versions.
+ window.RTCPeerConnection = window.webkitRTCPeerConnection;
+ }
+
+ if (!window.RTCPeerConnection) {
+ return;
+ } // shim implicit creation of RTCSessionDescription/RTCIceCandidate
+
+
+ if (browserDetails.version < 53) {
+ ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate'].forEach(function (method) {
+ var nativeMethod = window.RTCPeerConnection.prototype[method];
+
+ var methodObj = _defineProperty({}, method, function () {
+ arguments[0] = new (method === 'addIceCandidate' ? window.RTCIceCandidate : window.RTCSessionDescription)(arguments[0]);
+ return nativeMethod.apply(this, arguments);
+ });
+
+ window.RTCPeerConnection.prototype[method] = methodObj[method];
+ });
+ } // support for addIceCandidate(null or undefined)
+
+
+ var nativeAddIceCandidate = window.RTCPeerConnection.prototype.addIceCandidate;
+
+ window.RTCPeerConnection.prototype.addIceCandidate = function addIceCandidate() {
+ if (!arguments[0]) {
+ if (arguments[1]) {
+ arguments[1].apply(null);
+ }
+
+ return Promise.resolve();
+ } // Firefox 68+ emits and processes {candidate: "", ...}, ignore
+ // in older versions. Native support planned for Chrome M77.
+
+
+ if (browserDetails.version < 78 && arguments[0] && arguments[0].candidate === '') {
+ return Promise.resolve();
+ }
+
+ return nativeAddIceCandidate.apply(this, arguments);
+ };
+ }
+
+ function fixNegotiationNeeded(window) {
+ utils.wrapPeerConnectionEvent(window, 'negotiationneeded', function (e) {
+ var pc = e.target;
+
+ if (pc.signalingState !== 'stable') {
+ return;
+ }
+
+ return e;
+ });
+ }
+ }, {
+ "../utils.js": 15,
+ "./getdisplaymedia": 4,
+ "./getusermedia": 5
+ }],
+ 4: [function (require, module, exports) {
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+ exports.shimGetDisplayMedia = shimGetDisplayMedia;
+
+ function shimGetDisplayMedia(window, getSourceId) {
+ if (window.navigator.mediaDevices && 'getDisplayMedia' in window.navigator.mediaDevices) {
+ return;
+ }
+
+ if (!window.navigator.mediaDevices) {
+ return;
+ } // getSourceId is a function that returns a promise resolving with
+ // the sourceId of the screen/window/tab to be shared.
+
+
+ if (typeof getSourceId !== 'function') {
+ console.error('shimGetDisplayMedia: getSourceId argument is not ' + 'a function');
+ return;
+ }
+
+ window.navigator.mediaDevices.getDisplayMedia = function getDisplayMedia(constraints) {
+ return getSourceId(constraints).then(function (sourceId) {
+ var widthSpecified = constraints.video && constraints.video.width;
+ var heightSpecified = constraints.video && constraints.video.height;
+ var frameRateSpecified = constraints.video && constraints.video.frameRate;
+ constraints.video = {
+ mandatory: {
+ chromeMediaSource: 'desktop',
+ chromeMediaSourceId: sourceId,
+ maxFrameRate: frameRateSpecified || 3
+ }
+ };
+
+ if (widthSpecified) {
+ constraints.video.mandatory.maxWidth = widthSpecified;
+ }
+
+ if (heightSpecified) {
+ constraints.video.mandatory.maxHeight = heightSpecified;
+ }
+
+ return window.navigator.mediaDevices.getUserMedia(constraints);
+ });
+ };
+ }
+ }, {}],
+ 5: [function (require, module, exports) {
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+
+ var _typeof$1 = 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);
+ };
+
+ exports.shimGetUserMedia = shimGetUserMedia;
+
+ var _utils = require('../utils.js');
+
+ var utils = _interopRequireWildcard(_utils);
+
+ function _interopRequireWildcard(obj) {
+ if (obj && obj.__esModule) {
+ return obj;
+ } else {
+ var newObj = {};
+
+ if (obj != null) {
+ for (var key in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];
+ }
+ }
+
+ newObj["default"] = obj;
+ return newObj;
+ }
+ }
+
+ var logging = utils.log;
+
+ function shimGetUserMedia(window) {
+ var navigator = window && window.navigator;
+
+ if (!navigator.mediaDevices) {
+ return;
+ }
+
+ var browserDetails = utils.detectBrowser(window);
+
+ var constraintsToChrome_ = function constraintsToChrome_(c) {
+ if ((typeof c === 'undefined' ? 'undefined' : _typeof$1(c)) !== 'object' || c.mandatory || c.optional) {
+ return c;
+ }
+
+ var cc = {};
+ Object.keys(c).forEach(function (key) {
+ if (key === 'require' || key === 'advanced' || key === 'mediaSource') {
+ return;
+ }
+
+ var r = _typeof$1(c[key]) === 'object' ? c[key] : {
+ ideal: c[key]
+ };
+
+ if (r.exact !== undefined && typeof r.exact === 'number') {
+ r.min = r.max = r.exact;
+ }
+
+ var oldname_ = function oldname_(prefix, name) {
+ if (prefix) {
+ return prefix + name.charAt(0).toUpperCase() + name.slice(1);
+ }
+
+ return name === 'deviceId' ? 'sourceId' : name;
+ };
+
+ if (r.ideal !== undefined) {
+ cc.optional = cc.optional || [];
+ var oc = {};
+
+ if (typeof r.ideal === 'number') {
+ oc[oldname_('min', key)] = r.ideal;
+ cc.optional.push(oc);
+ oc = {};
+ oc[oldname_('max', key)] = r.ideal;
+ cc.optional.push(oc);
+ } else {
+ oc[oldname_('', key)] = r.ideal;
+ cc.optional.push(oc);
+ }
+ }
+
+ if (r.exact !== undefined && typeof r.exact !== 'number') {
+ cc.mandatory = cc.mandatory || {};
+ cc.mandatory[oldname_('', key)] = r.exact;
+ } else {
+ ['min', 'max'].forEach(function (mix) {
+ if (r[mix] !== undefined) {
+ cc.mandatory = cc.mandatory || {};
+ cc.mandatory[oldname_(mix, key)] = r[mix];
+ }
+ });
+ }
+ });
+
+ if (c.advanced) {
+ cc.optional = (cc.optional || []).concat(c.advanced);
+ }
+
+ return cc;
+ };
+
+ var shimConstraints_ = function shimConstraints_(constraints, func) {
+ if (browserDetails.version >= 61) {
+ return func(constraints);
+ }
+
+ constraints = JSON.parse(JSON.stringify(constraints));
+
+ if (constraints && _typeof$1(constraints.audio) === 'object') {
+ var remap = function remap(obj, a, b) {
+ if (a in obj && !(b in obj)) {
+ obj[b] = obj[a];
+ delete obj[a];
+ }
+ };
+
+ constraints = JSON.parse(JSON.stringify(constraints));
+ remap(constraints.audio, 'autoGainControl', 'googAutoGainControl');
+ remap(constraints.audio, 'noiseSuppression', 'googNoiseSuppression');
+ constraints.audio = constraintsToChrome_(constraints.audio);
+ }
+
+ if (constraints && _typeof$1(constraints.video) === 'object') {
+ // Shim facingMode for mobile & surface pro.
+ var face = constraints.video.facingMode;
+ face = face && ((typeof face === 'undefined' ? 'undefined' : _typeof$1(face)) === 'object' ? face : {
+ ideal: face
+ });
+ var getSupportedFacingModeLies = browserDetails.version < 66;
+
+ if (face && (face.exact === 'user' || face.exact === 'environment' || face.ideal === 'user' || face.ideal === 'environment') && !(navigator.mediaDevices.getSupportedConstraints && navigator.mediaDevices.getSupportedConstraints().facingMode && !getSupportedFacingModeLies)) {
+ delete constraints.video.facingMode;
+ var matches = void 0;
+
+ if (face.exact === 'environment' || face.ideal === 'environment') {
+ matches = ['back', 'rear'];
+ } else if (face.exact === 'user' || face.ideal === 'user') {
+ matches = ['front'];
+ }
+
+ if (matches) {
+ // Look for matches in label, or use last cam for back (typical).
+ return navigator.mediaDevices.enumerateDevices().then(function (devices) {
+ devices = devices.filter(function (d) {
+ return d.kind === 'videoinput';
+ });
+ var dev = devices.find(function (d) {
+ return matches.some(function (match) {
+ return d.label.toLowerCase().includes(match);
+ });
+ });
+
+ if (!dev && devices.length && matches.includes('back')) {
+ dev = devices[devices.length - 1]; // more likely the back cam
+ }
+
+ if (dev) {
+ constraints.video.deviceId = face.exact ? {
+ exact: dev.deviceId
+ } : {
+ ideal: dev.deviceId
+ };
+ }
+
+ constraints.video = constraintsToChrome_(constraints.video);
+ logging('chrome: ' + JSON.stringify(constraints));
+ return func(constraints);
+ });
+ }
+ }
+
+ constraints.video = constraintsToChrome_(constraints.video);
+ }
+
+ logging('chrome: ' + JSON.stringify(constraints));
+ return func(constraints);
+ };
+
+ var shimError_ = function shimError_(e) {
+ if (browserDetails.version >= 64) {
+ return e;
+ }
+
+ return {
+ name: {
+ PermissionDeniedError: 'NotAllowedError',
+ PermissionDismissedError: 'NotAllowedError',
+ InvalidStateError: 'NotAllowedError',
+ DevicesNotFoundError: 'NotFoundError',
+ ConstraintNotSatisfiedError: 'OverconstrainedError',
+ TrackStartError: 'NotReadableError',
+ MediaDeviceFailedDueToShutdown: 'NotAllowedError',
+ MediaDeviceKillSwitchOn: 'NotAllowedError',
+ TabCaptureError: 'AbortError',
+ ScreenCaptureError: 'AbortError',
+ DeviceCaptureError: 'AbortError'
+ }[e.name] || e.name,
+ message: e.message,
+ constraint: e.constraint || e.constraintName,
+ toString: function toString() {
+ return this.name + (this.message && ': ') + this.message;
+ }
+ };
+ };
+
+ var getUserMedia_ = function getUserMedia_(constraints, onSuccess, onError) {
+ shimConstraints_(constraints, function (c) {
+ navigator.webkitGetUserMedia(c, onSuccess, function (e) {
+ if (onError) {
+ onError(shimError_(e));
+ }
+ });
+ });
+ };
+
+ navigator.getUserMedia = getUserMedia_.bind(navigator); // Even though Chrome 45 has navigator.mediaDevices and a getUserMedia
+ // function which returns a Promise, it does not accept spec-style
+ // constraints.
+
+ if (navigator.mediaDevices.getUserMedia) {
+ var origGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);
+
+ navigator.mediaDevices.getUserMedia = function (cs) {
+ return shimConstraints_(cs, function (c) {
+ return origGetUserMedia(c).then(function (stream) {
+ if (c.audio && !stream.getAudioTracks().length || c.video && !stream.getVideoTracks().length) {
+ stream.getTracks().forEach(function (track) {
+ track.stop();
+ });
+ throw new DOMException('', 'NotFoundError');
+ }
+
+ return stream;
+ }, function (e) {
+ return Promise.reject(shimError_(e));
+ });
+ });
+ };
+ }
+ }
+ }, {
+ "../utils.js": 15
+ }],
+ 6: [function (require, module, exports) {
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+
+ var _typeof$1 = 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);
+ };
+
+ exports.shimRTCIceCandidate = shimRTCIceCandidate;
+ exports.shimMaxMessageSize = shimMaxMessageSize;
+ exports.shimSendThrowTypeError = shimSendThrowTypeError;
+ exports.shimConnectionState = shimConnectionState;
+ exports.removeAllowExtmapMixed = removeAllowExtmapMixed;
+
+ var _sdp = require('sdp');
+
+ var _sdp2 = _interopRequireDefault(_sdp);
+
+ var _utils = require('./utils');
+
+ var utils = _interopRequireWildcard(_utils);
+
+ function _interopRequireWildcard(obj) {
+ if (obj && obj.__esModule) {
+ return obj;
+ } else {
+ var newObj = {};
+
+ if (obj != null) {
+ for (var key in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];
+ }
+ }
+
+ newObj["default"] = obj;
+ return newObj;
+ }
+ }
+
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : {
+ "default": obj
+ };
+ }
+
+ function shimRTCIceCandidate(window) {
+ // foundation is arbitrarily chosen as an indicator for full support for
+ // https://w3c.github.io/webrtc-pc/#rtcicecandidate-interface
+ if (!window.RTCIceCandidate || window.RTCIceCandidate && 'foundation' in window.RTCIceCandidate.prototype) {
+ return;
+ }
+
+ var NativeRTCIceCandidate = window.RTCIceCandidate;
+
+ window.RTCIceCandidate = function RTCIceCandidate(args) {
+ // Remove the a= which shouldn't be part of the candidate string.
+ if ((typeof args === 'undefined' ? 'undefined' : _typeof$1(args)) === 'object' && args.candidate && args.candidate.indexOf('a=') === 0) {
+ args = JSON.parse(JSON.stringify(args));
+ args.candidate = args.candidate.substr(2);
+ }
+
+ if (args.candidate && args.candidate.length) {
+ // Augment the native candidate with the parsed fields.
+ var nativeCandidate = new NativeRTCIceCandidate(args);
+
+ var parsedCandidate = _sdp2["default"].parseCandidate(args.candidate);
+
+ var augmentedCandidate = Object.assign(nativeCandidate, parsedCandidate); // Add a serializer that does not serialize the extra attributes.
+
+ augmentedCandidate.toJSON = function toJSON() {
+ return {
+ candidate: augmentedCandidate.candidate,
+ sdpMid: augmentedCandidate.sdpMid,
+ sdpMLineIndex: augmentedCandidate.sdpMLineIndex,
+ usernameFragment: augmentedCandidate.usernameFragment
+ };
+ };
+
+ return augmentedCandidate;
+ }
+
+ return new NativeRTCIceCandidate(args);
+ };
+
+ window.RTCIceCandidate.prototype = NativeRTCIceCandidate.prototype; // Hook up the augmented candidate in onicecandidate and
+ // addEventListener('icecandidate', ...)
+
+ utils.wrapPeerConnectionEvent(window, 'icecandidate', function (e) {
+ if (e.candidate) {
+ Object.defineProperty(e, 'candidate', {
+ value: new window.RTCIceCandidate(e.candidate),
+ writable: 'false'
+ });
+ }
+
+ return e;
+ });
+ }
+
+ function shimMaxMessageSize(window) {
+ if (!window.RTCPeerConnection) {
+ return;
+ }
+
+ var browserDetails = utils.detectBrowser(window);
+
+ if (!('sctp' in window.RTCPeerConnection.prototype)) {
+ Object.defineProperty(window.RTCPeerConnection.prototype, 'sctp', {
+ get: function get() {
+ return typeof this._sctp === 'undefined' ? null : this._sctp;
+ }
+ });
+ }
+
+ var sctpInDescription = function sctpInDescription(description) {
+ if (!description || !description.sdp) {
+ return false;
+ }
+
+ var sections = _sdp2["default"].splitSections(description.sdp);
+
+ sections.shift();
+ return sections.some(function (mediaSection) {
+ var mLine = _sdp2["default"].parseMLine(mediaSection);
+
+ return mLine && mLine.kind === 'application' && mLine.protocol.indexOf('SCTP') !== -1;
+ });
+ };
+
+ var getRemoteFirefoxVersion = function getRemoteFirefoxVersion(description) {
+ // TODO: Is there a better solution for detecting Firefox?
+ var match = description.sdp.match(/mozilla...THIS_IS_SDPARTA-(\d+)/);
+
+ if (match === null || match.length < 2) {
+ return -1;
+ }
+
+ var version = parseInt(match[1], 10); // Test for NaN (yes, this is ugly)
+
+ return version !== version ? -1 : version;
+ };
+
+ var getCanSendMaxMessageSize = function getCanSendMaxMessageSize(remoteIsFirefox) {
+ // Every implementation we know can send at least 64 KiB.
+ // Note: Although Chrome is technically able to send up to 256 KiB, the
+ // data does not reach the other peer reliably.
+ // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=8419
+ var canSendMaxMessageSize = 65536;
+
+ if (browserDetails.browser === 'firefox') {
+ if (browserDetails.version < 57) {
+ if (remoteIsFirefox === -1) {
+ // FF < 57 will send in 16 KiB chunks using the deprecated PPID
+ // fragmentation.
+ canSendMaxMessageSize = 16384;
+ } else {
+ // However, other FF (and RAWRTC) can reassemble PPID-fragmented
+ // messages. Thus, supporting ~2 GiB when sending.
+ canSendMaxMessageSize = 2147483637;
+ }
+ } else if (browserDetails.version < 60) {
+ // Currently, all FF >= 57 will reset the remote maximum message size
+ // to the default value when a data channel is created at a later
+ // stage. :(
+ // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831
+ canSendMaxMessageSize = browserDetails.version === 57 ? 65535 : 65536;
+ } else {
+ // FF >= 60 supports sending ~2 GiB
+ canSendMaxMessageSize = 2147483637;
+ }
+ }
+
+ return canSendMaxMessageSize;
+ };
+
+ var getMaxMessageSize = function getMaxMessageSize(description, remoteIsFirefox) {
+ // Note: 65536 bytes is the default value from the SDP spec. Also,
+ // every implementation we know supports receiving 65536 bytes.
+ var maxMessageSize = 65536; // FF 57 has a slightly incorrect default remote max message size, so
+ // we need to adjust it here to avoid a failure when sending.
+ // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1425697
+
+ if (browserDetails.browser === 'firefox' && browserDetails.version === 57) {
+ maxMessageSize = 65535;
+ }
+
+ var match = _sdp2["default"].matchPrefix(description.sdp, 'a=max-message-size:');
+
+ if (match.length > 0) {
+ maxMessageSize = parseInt(match[0].substr(19), 10);
+ } else if (browserDetails.browser === 'firefox' && remoteIsFirefox !== -1) {
+ // If the maximum message size is not present in the remote SDP and
+ // both local and remote are Firefox, the remote peer can receive
+ // ~2 GiB.
+ maxMessageSize = 2147483637;
+ }
+
+ return maxMessageSize;
+ };
+
+ var origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription;
+
+ window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription() {
+ this._sctp = null; // Chrome decided to not expose .sctp in plan-b mode.
+ // As usual, adapter.js has to do an 'ugly worakaround'
+ // to cover up the mess.
+
+ if (browserDetails.browser === 'chrome' && browserDetails.version >= 76) {
+ var _getConfiguration = this.getConfiguration(),
+ sdpSemantics = _getConfiguration.sdpSemantics;
+
+ if (sdpSemantics === 'plan-b') {
+ Object.defineProperty(this, 'sctp', {
+ get: function get() {
+ return typeof this._sctp === 'undefined' ? null : this._sctp;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ }
+ }
+
+ if (sctpInDescription(arguments[0])) {
+ // Check if the remote is FF.
+ var isFirefox = getRemoteFirefoxVersion(arguments[0]); // Get the maximum message size the local peer is capable of sending
+
+ var canSendMMS = getCanSendMaxMessageSize(isFirefox); // Get the maximum message size of the remote peer.
+
+ var remoteMMS = getMaxMessageSize(arguments[0], isFirefox); // Determine final maximum message size
+
+ var maxMessageSize = void 0;
+
+ if (canSendMMS === 0 && remoteMMS === 0) {
+ maxMessageSize = Number.POSITIVE_INFINITY;
+ } else if (canSendMMS === 0 || remoteMMS === 0) {
+ maxMessageSize = Math.max(canSendMMS, remoteMMS);
+ } else {
+ maxMessageSize = Math.min(canSendMMS, remoteMMS);
+ } // Create a dummy RTCSctpTransport object and the 'maxMessageSize'
+ // attribute.
+
+
+ var sctp = {};
+ Object.defineProperty(sctp, 'maxMessageSize', {
+ get: function get() {
+ return maxMessageSize;
+ }
+ });
+ this._sctp = sctp;
+ }
+
+ return origSetRemoteDescription.apply(this, arguments);
+ };
+ }
+
+ function shimSendThrowTypeError(window) {
+ if (!(window.RTCPeerConnection && 'createDataChannel' in window.RTCPeerConnection.prototype)) {
+ return;
+ } // Note: Although Firefox >= 57 has a native implementation, the maximum
+ // message size can be reset for all data channels at a later stage.
+ // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831
+
+
+ function wrapDcSend(dc, pc) {
+ var origDataChannelSend = dc.send;
+
+ dc.send = function send() {
+ var data = arguments[0];
+ var length = data.length || data.size || data.byteLength;
+
+ if (dc.readyState === 'open' && pc.sctp && length > pc.sctp.maxMessageSize) {
+ throw new TypeError('Message too large (can send a maximum of ' + pc.sctp.maxMessageSize + ' bytes)');
+ }
+
+ return origDataChannelSend.apply(dc, arguments);
+ };
+ }
+
+ var origCreateDataChannel = window.RTCPeerConnection.prototype.createDataChannel;
+
+ window.RTCPeerConnection.prototype.createDataChannel = function createDataChannel() {
+ var dataChannel = origCreateDataChannel.apply(this, arguments);
+ wrapDcSend(dataChannel, this);
+ return dataChannel;
+ };
+
+ utils.wrapPeerConnectionEvent(window, 'datachannel', function (e) {
+ wrapDcSend(e.channel, e.target);
+ return e;
+ });
+ }
+ /* shims RTCConnectionState by pretending it is the same as iceConnectionState.
+ * See https://bugs.chromium.org/p/webrtc/issues/detail?id=6145#c12
+ * for why this is a valid hack in Chrome. In Firefox it is slightly incorrect
+ * since DTLS failures would be hidden. See
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=1265827
+ * for the Firefox tracking bug.
+ */
+
+
+ function shimConnectionState(window) {
+ if (!window.RTCPeerConnection || 'connectionState' in window.RTCPeerConnection.prototype) {
+ return;
+ }
+
+ var proto = window.RTCPeerConnection.prototype;
+ Object.defineProperty(proto, 'connectionState', {
+ get: function get() {
+ return {
+ completed: 'connected',
+ checking: 'connecting'
+ }[this.iceConnectionState] || this.iceConnectionState;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(proto, 'onconnectionstatechange', {
+ get: function get() {
+ return this._onconnectionstatechange || null;
+ },
+ set: function set(cb) {
+ if (this._onconnectionstatechange) {
+ this.removeEventListener('connectionstatechange', this._onconnectionstatechange);
+ delete this._onconnectionstatechange;
+ }
+
+ if (cb) {
+ this.addEventListener('connectionstatechange', this._onconnectionstatechange = cb);
+ }
+ },
+ enumerable: true,
+ configurable: true
+ });
+ ['setLocalDescription', 'setRemoteDescription'].forEach(function (method) {
+ var origMethod = proto[method];
+
+ proto[method] = function () {
+ if (!this._connectionstatechangepoly) {
+ this._connectionstatechangepoly = function (e) {
+ var pc = e.target;
+
+ if (pc._lastConnectionState !== pc.connectionState) {
+ pc._lastConnectionState = pc.connectionState;
+ var newEvent = new Event('connectionstatechange', e);
+ pc.dispatchEvent(newEvent);
+ }
+
+ return e;
+ };
+
+ this.addEventListener('iceconnectionstatechange', this._connectionstatechangepoly);
+ }
+
+ return origMethod.apply(this, arguments);
+ };
+ });
+ }
+
+ function removeAllowExtmapMixed(window) {
+ /* remove a=extmap-allow-mixed for Chrome < M71 */
+ if (!window.RTCPeerConnection) {
+ return;
+ }
+
+ var browserDetails = utils.detectBrowser(window);
+
+ if (browserDetails.browser === 'chrome' && browserDetails.version >= 71) {
+ return;
+ }
+
+ var nativeSRD = window.RTCPeerConnection.prototype.setRemoteDescription;
+
+ window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription(desc) {
+ if (desc && desc.sdp && desc.sdp.indexOf('\na=extmap-allow-mixed') !== -1) {
+ desc.sdp = desc.sdp.split('\n').filter(function (line) {
+ return line.trim() !== 'a=extmap-allow-mixed';
+ }).join('\n');
+ }
+
+ return nativeSRD.apply(this, arguments);
+ };
+ }
+ }, {
+ "./utils": 15,
+ "sdp": 17
+ }],
+ 7: [function (require, module, exports) {
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+ exports.shimGetDisplayMedia = exports.shimGetUserMedia = undefined;
+
+ var _getusermedia = require('./getusermedia');
+
+ Object.defineProperty(exports, 'shimGetUserMedia', {
+ enumerable: true,
+ get: function get() {
+ return _getusermedia.shimGetUserMedia;
+ }
+ });
+
+ var _getdisplaymedia = require('./getdisplaymedia');
+
+ Object.defineProperty(exports, 'shimGetDisplayMedia', {
+ enumerable: true,
+ get: function get() {
+ return _getdisplaymedia.shimGetDisplayMedia;
+ }
+ });
+ exports.shimPeerConnection = shimPeerConnection;
+ exports.shimReplaceTrack = shimReplaceTrack;
+
+ var _utils = require('../utils');
+
+ var utils = _interopRequireWildcard(_utils);
+
+ var _filtericeservers = require('./filtericeservers');
+
+ var _rtcpeerconnectionShim = require('rtcpeerconnection-shim');
+
+ var _rtcpeerconnectionShim2 = _interopRequireDefault(_rtcpeerconnectionShim);
+
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : {
+ "default": obj
+ };
+ }
+
+ function _interopRequireWildcard(obj) {
+ if (obj && obj.__esModule) {
+ return obj;
+ } else {
+ var newObj = {};
+
+ if (obj != null) {
+ for (var key in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];
+ }
+ }
+
+ newObj["default"] = obj;
+ return newObj;
+ }
+ }
+
+ function shimPeerConnection(window) {
+ var browserDetails = utils.detectBrowser(window);
+
+ if (window.RTCIceGatherer) {
+ if (!window.RTCIceCandidate) {
+ window.RTCIceCandidate = function RTCIceCandidate(args) {
+ return args;
+ };
+ }
+
+ if (!window.RTCSessionDescription) {
+ window.RTCSessionDescription = function RTCSessionDescription(args) {
+ return args;
+ };
+ } // this adds an additional event listener to MediaStrackTrack that signals
+ // when a tracks enabled property was changed. Workaround for a bug in
+ // addStream, see below. No longer required in 15025+
+
+
+ if (browserDetails.version < 15025) {
+ var origMSTEnabled = Object.getOwnPropertyDescriptor(window.MediaStreamTrack.prototype, 'enabled');
+ Object.defineProperty(window.MediaStreamTrack.prototype, 'enabled', {
+ set: function set(value) {
+ origMSTEnabled.set.call(this, value);
+ var ev = new Event('enabled');
+ ev.enabled = value;
+ this.dispatchEvent(ev);
+ }
+ });
+ }
+ } // ORTC defines the DTMF sender a bit different.
+ // https://github.com/w3c/ortc/issues/714
+
+
+ if (window.RTCRtpSender && !('dtmf' in window.RTCRtpSender.prototype)) {
+ Object.defineProperty(window.RTCRtpSender.prototype, 'dtmf', {
+ get: function get() {
+ if (this._dtmf === undefined) {
+ if (this.track.kind === 'audio') {
+ this._dtmf = new window.RTCDtmfSender(this);
+ } else if (this.track.kind === 'video') {
+ this._dtmf = null;
+ }
+ }
+
+ return this._dtmf;
+ }
+ });
+ } // Edge currently only implements the RTCDtmfSender, not the
+ // RTCDTMFSender alias. See http://draft.ortc.org/#rtcdtmfsender2*
+
+
+ if (window.RTCDtmfSender && !window.RTCDTMFSender) {
+ window.RTCDTMFSender = window.RTCDtmfSender;
+ }
+
+ var RTCPeerConnectionShim = (0, _rtcpeerconnectionShim2["default"])(window, browserDetails.version);
+
+ window.RTCPeerConnection = function RTCPeerConnection(config) {
+ if (config && config.iceServers) {
+ config.iceServers = (0, _filtericeservers.filterIceServers)(config.iceServers, browserDetails.version);
+ utils.log('ICE servers after filtering:', config.iceServers);
+ }
+
+ return new RTCPeerConnectionShim(config);
+ };
+
+ window.RTCPeerConnection.prototype = RTCPeerConnectionShim.prototype;
+ }
+
+ function shimReplaceTrack(window) {
+ // ORTC has replaceTrack -- https://github.com/w3c/ortc/issues/614
+ if (window.RTCRtpSender && !('replaceTrack' in window.RTCRtpSender.prototype)) {
+ window.RTCRtpSender.prototype.replaceTrack = window.RTCRtpSender.prototype.setTrack;
+ }
+ }
+ }, {
+ "../utils": 15,
+ "./filtericeservers": 8,
+ "./getdisplaymedia": 9,
+ "./getusermedia": 10,
+ "rtcpeerconnection-shim": 16
+ }],
+ 8: [function (require, module, exports) {
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+ exports.filterIceServers = filterIceServers;
+
+ var _utils = require('../utils');
+
+ var utils = _interopRequireWildcard(_utils);
+
+ function _interopRequireWildcard(obj) {
+ if (obj && obj.__esModule) {
+ return obj;
+ } else {
+ var newObj = {};
+
+ if (obj != null) {
+ for (var key in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];
+ }
+ }
+
+ newObj["default"] = obj;
+ return newObj;
+ }
+ } // Edge does not like
+ // 1) stun: filtered after 14393 unless ?transport=udp is present
+ // 2) turn: that does not have all of turn:host:port?transport=udp
+ // 3) turn: with ipv6 addresses
+ // 4) turn: occurring muliple times
+
+
+ function filterIceServers(iceServers, edgeVersion) {
+ var hasTurn = false;
+ iceServers = JSON.parse(JSON.stringify(iceServers));
+ return iceServers.filter(function (server) {
+ if (server && (server.urls || server.url)) {
+ var urls = server.urls || server.url;
+
+ if (server.url && !server.urls) {
+ utils.deprecated('RTCIceServer.url', 'RTCIceServer.urls');
+ }
+
+ var isString = typeof urls === 'string';
+
+ if (isString) {
+ urls = [urls];
+ }
+
+ urls = urls.filter(function (url) {
+ // filter STUN unconditionally.
+ if (url.indexOf('stun:') === 0) {
+ return false;
+ }
+
+ var validTurn = url.startsWith('turn') && !url.startsWith('turn:[') && url.includes('transport=udp');
+
+ if (validTurn && !hasTurn) {
+ hasTurn = true;
+ return true;
+ }
+
+ return validTurn && !hasTurn;
+ });
+ delete server.url;
+ server.urls = isString ? urls[0] : urls;
+ return !!urls.length;
+ }
+ });
+ }
+ }, {
+ "../utils": 15
+ }],
+ 9: [function (require, module, exports) {
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+ exports.shimGetDisplayMedia = shimGetDisplayMedia;
+
+ function shimGetDisplayMedia(window) {
+ if (!('getDisplayMedia' in window.navigator)) {
+ return;
+ }
+
+ if (!window.navigator.mediaDevices) {
+ return;
+ }
+
+ if (window.navigator.mediaDevices && 'getDisplayMedia' in window.navigator.mediaDevices) {
+ return;
+ }
+
+ window.navigator.mediaDevices.getDisplayMedia = window.navigator.getDisplayMedia.bind(window.navigator);
+ }
+ }, {}],
+ 10: [function (require, module, exports) {
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+ exports.shimGetUserMedia = shimGetUserMedia;
+
+ function shimGetUserMedia(window) {
+ var navigator = window && window.navigator;
+
+ var shimError_ = function shimError_(e) {
+ return {
+ name: {
+ PermissionDeniedError: 'NotAllowedError'
+ }[e.name] || e.name,
+ message: e.message,
+ constraint: e.constraint,
+ toString: function toString() {
+ return this.name;
+ }
+ };
+ }; // getUserMedia error shim.
+
+
+ var origGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);
+
+ navigator.mediaDevices.getUserMedia = function (c) {
+ return origGetUserMedia(c)["catch"](function (e) {
+ return Promise.reject(shimError_(e));
+ });
+ };
+ }
+ }, {}],
+ 11: [function (require, module, exports) {
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+ exports.shimGetDisplayMedia = exports.shimGetUserMedia = undefined;
+
+ var _typeof$1 = 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);
+ };
+
+ var _getusermedia = require('./getusermedia');
+
+ Object.defineProperty(exports, 'shimGetUserMedia', {
+ enumerable: true,
+ get: function get() {
+ return _getusermedia.shimGetUserMedia;
+ }
+ });
+
+ var _getdisplaymedia = require('./getdisplaymedia');
+
+ Object.defineProperty(exports, 'shimGetDisplayMedia', {
+ enumerable: true,
+ get: function get() {
+ return _getdisplaymedia.shimGetDisplayMedia;
+ }
+ });
+ exports.shimOnTrack = shimOnTrack;
+ exports.shimPeerConnection = shimPeerConnection;
+ exports.shimSenderGetStats = shimSenderGetStats;
+ exports.shimReceiverGetStats = shimReceiverGetStats;
+ exports.shimRemoveStream = shimRemoveStream;
+ exports.shimRTCDataChannel = shimRTCDataChannel;
+ exports.shimAddTransceiver = shimAddTransceiver;
+ exports.shimCreateOffer = shimCreateOffer;
+ exports.shimCreateAnswer = shimCreateAnswer;
+
+ var _utils = require('../utils');
+
+ var utils = _interopRequireWildcard(_utils);
+
+ function _interopRequireWildcard(obj) {
+ if (obj && obj.__esModule) {
+ return obj;
+ } else {
+ var newObj = {};
+
+ if (obj != null) {
+ for (var key in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];
+ }
+ }
+
+ newObj["default"] = obj;
+ return newObj;
+ }
+ }
+
+ function _defineProperty(obj, key, value) {
+ if (key in obj) {
+ Object.defineProperty(obj, key, {
+ value: value,
+ enumerable: true,
+ configurable: true,
+ writable: true
+ });
+ } else {
+ obj[key] = value;
+ }
+
+ return obj;
+ }
+
+ function shimOnTrack(window) {
+ if ((typeof window === 'undefined' ? 'undefined' : _typeof$1(window)) === 'object' && window.RTCTrackEvent && 'receiver' in window.RTCTrackEvent.prototype && !('transceiver' in window.RTCTrackEvent.prototype)) {
+ Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', {
+ get: function get() {
+ return {
+ receiver: this.receiver
+ };
+ }
+ });
+ }
+ }
+
+ function shimPeerConnection(window) {
+ var browserDetails = utils.detectBrowser(window);
+
+ if ((typeof window === 'undefined' ? 'undefined' : _typeof$1(window)) !== 'object' || !(window.RTCPeerConnection || window.mozRTCPeerConnection)) {
+ return; // probably media.peerconnection.enabled=false in about:config
+ }
+
+ if (!window.RTCPeerConnection && window.mozRTCPeerConnection) {
+ // very basic support for old versions.
+ window.RTCPeerConnection = window.mozRTCPeerConnection;
+ }
+
+ if (browserDetails.version < 53) {
+ // shim away need for obsolete RTCIceCandidate/RTCSessionDescription.
+ ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate'].forEach(function (method) {
+ var nativeMethod = window.RTCPeerConnection.prototype[method];
+
+ var methodObj = _defineProperty({}, method, function () {
+ arguments[0] = new (method === 'addIceCandidate' ? window.RTCIceCandidate : window.RTCSessionDescription)(arguments[0]);
+ return nativeMethod.apply(this, arguments);
+ });
+
+ window.RTCPeerConnection.prototype[method] = methodObj[method];
+ });
+ } // support for addIceCandidate(null or undefined)
+ // as well as ignoring {sdpMid, candidate: ""}
+
+
+ if (browserDetails.version < 68) {
+ var nativeAddIceCandidate = window.RTCPeerConnection.prototype.addIceCandidate;
+
+ window.RTCPeerConnection.prototype.addIceCandidate = function addIceCandidate() {
+ if (!arguments[0]) {
+ if (arguments[1]) {
+ arguments[1].apply(null);
+ }
+
+ return Promise.resolve();
+ } // Firefox 68+ emits and processes {candidate: "", ...}, ignore
+ // in older versions.
+
+
+ if (arguments[0] && arguments[0].candidate === '') {
+ return Promise.resolve();
+ }
+
+ return nativeAddIceCandidate.apply(this, arguments);
+ };
+ }
+
+ var modernStatsTypes = {
+ inboundrtp: 'inbound-rtp',
+ outboundrtp: 'outbound-rtp',
+ candidatepair: 'candidate-pair',
+ localcandidate: 'local-candidate',
+ remotecandidate: 'remote-candidate'
+ };
+ var nativeGetStats = window.RTCPeerConnection.prototype.getStats;
+
+ window.RTCPeerConnection.prototype.getStats = function getStats() {
+ var _arguments = Array.prototype.slice.call(arguments),
+ selector = _arguments[0],
+ onSucc = _arguments[1],
+ onErr = _arguments[2];
+
+ return nativeGetStats.apply(this, [selector || null]).then(function (stats) {
+ if (browserDetails.version < 53 && !onSucc) {
+ // Shim only promise getStats with spec-hyphens in type names
+ // Leave callback version alone; misc old uses of forEach before Map
+ try {
+ stats.forEach(function (stat) {
+ stat.type = modernStatsTypes[stat.type] || stat.type;
+ });
+ } catch (e) {
+ if (e.name !== 'TypeError') {
+ throw e;
+ } // Avoid TypeError: "type" is read-only, in old versions. 34-43ish
+
+
+ stats.forEach(function (stat, i) {
+ stats.set(i, Object.assign({}, stat, {
+ type: modernStatsTypes[stat.type] || stat.type
+ }));
+ });
+ }
+ }
+
+ return stats;
+ }).then(onSucc, onErr);
+ };
+ }
+
+ function shimSenderGetStats(window) {
+ if (!((typeof window === 'undefined' ? 'undefined' : _typeof$1(window)) === 'object' && window.RTCPeerConnection && window.RTCRtpSender)) {
+ return;
+ }
+
+ if (window.RTCRtpSender && 'getStats' in window.RTCRtpSender.prototype) {
+ return;
+ }
+
+ var origGetSenders = window.RTCPeerConnection.prototype.getSenders;
+
+ if (origGetSenders) {
+ window.RTCPeerConnection.prototype.getSenders = function getSenders() {
+ var _this = this;
+
+ var senders = origGetSenders.apply(this, []);
+ senders.forEach(function (sender) {
+ return sender._pc = _this;
+ });
+ return senders;
+ };
+ }
+
+ var origAddTrack = window.RTCPeerConnection.prototype.addTrack;
+
+ if (origAddTrack) {
+ window.RTCPeerConnection.prototype.addTrack = function addTrack() {
+ var sender = origAddTrack.apply(this, arguments);
+ sender._pc = this;
+ return sender;
+ };
+ }
+
+ window.RTCRtpSender.prototype.getStats = function getStats() {
+ return this.track ? this._pc.getStats(this.track) : Promise.resolve(new Map());
+ };
+ }
+
+ function shimReceiverGetStats(window) {
+ if (!((typeof window === 'undefined' ? 'undefined' : _typeof$1(window)) === 'object' && window.RTCPeerConnection && window.RTCRtpSender)) {
+ return;
+ }
+
+ if (window.RTCRtpSender && 'getStats' in window.RTCRtpReceiver.prototype) {
+ return;
+ }
+
+ var origGetReceivers = window.RTCPeerConnection.prototype.getReceivers;
+
+ if (origGetReceivers) {
+ window.RTCPeerConnection.prototype.getReceivers = function getReceivers() {
+ var _this2 = this;
+
+ var receivers = origGetReceivers.apply(this, []);
+ receivers.forEach(function (receiver) {
+ return receiver._pc = _this2;
+ });
+ return receivers;
+ };
+ }
+
+ utils.wrapPeerConnectionEvent(window, 'track', function (e) {
+ e.receiver._pc = e.srcElement;
+ return e;
+ });
+
+ window.RTCRtpReceiver.prototype.getStats = function getStats() {
+ return this._pc.getStats(this.track);
+ };
+ }
+
+ function shimRemoveStream(window) {
+ if (!window.RTCPeerConnection || 'removeStream' in window.RTCPeerConnection.prototype) {
+ return;
+ }
+
+ window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
+ var _this3 = this;
+
+ utils.deprecated('removeStream', 'removeTrack');
+ this.getSenders().forEach(function (sender) {
+ if (sender.track && stream.getTracks().includes(sender.track)) {
+ _this3.removeTrack(sender);
+ }
+ });
+ };
+ }
+
+ function shimRTCDataChannel(window) {
+ // rename DataChannel to RTCDataChannel (native fix in FF60):
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1173851
+ if (window.DataChannel && !window.RTCDataChannel) {
+ window.RTCDataChannel = window.DataChannel;
+ }
+ }
+
+ function shimAddTransceiver(window) {
+ // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647
+ // Firefox ignores the init sendEncodings options passed to addTransceiver
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918
+ if (!((typeof window === 'undefined' ? 'undefined' : _typeof$1(window)) === 'object' && window.RTCPeerConnection)) {
+ return;
+ }
+
+ var origAddTransceiver = window.RTCPeerConnection.prototype.addTransceiver;
+
+ if (origAddTransceiver) {
+ window.RTCPeerConnection.prototype.addTransceiver = function addTransceiver() {
+ this.setParametersPromises = [];
+ var initParameters = arguments[1];
+ var shouldPerformCheck = initParameters && 'sendEncodings' in initParameters;
+
+ if (shouldPerformCheck) {
+ // If sendEncodings params are provided, validate grammar
+ initParameters.sendEncodings.forEach(function (encodingParam) {
+ if ('rid' in encodingParam) {
+ var ridRegex = /^[a-z0-9]{0,16}$/i;
+
+ if (!ridRegex.test(encodingParam.rid)) {
+ throw new TypeError('Invalid RID value provided.');
+ }
+ }
+
+ if ('scaleResolutionDownBy' in encodingParam) {
+ if (!(parseFloat(encodingParam.scaleResolutionDownBy) >= 1.0)) {
+ throw new RangeError('scale_resolution_down_by must be >= 1.0');
+ }
+ }
+
+ if ('maxFramerate' in encodingParam) {
+ if (!(parseFloat(encodingParam.maxFramerate) >= 0)) {
+ throw new RangeError('max_framerate must be >= 0.0');
+ }
+ }
+ });
+ }
+
+ var transceiver = origAddTransceiver.apply(this, arguments);
+
+ if (shouldPerformCheck) {
+ // Check if the init options were applied. If not we do this in an
+ // asynchronous way and save the promise reference in a global object.
+ // This is an ugly hack, but at the same time is way more robust than
+ // checking the sender parameters before and after the createOffer
+ // Also note that after the createoffer we are not 100% sure that
+ // the params were asynchronously applied so we might miss the
+ // opportunity to recreate offer.
+ var sender = transceiver.sender;
+ var params = sender.getParameters();
+
+ if (!('encodings' in params)) {
+ params.encodings = initParameters.sendEncodings;
+ this.setParametersPromises.push(sender.setParameters(params)["catch"](function () {}));
+ }
+ }
+
+ return transceiver;
+ };
+ }
+ }
+
+ function shimCreateOffer(window) {
+ // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647
+ // Firefox ignores the init sendEncodings options passed to addTransceiver
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918
+ if (!((typeof window === 'undefined' ? 'undefined' : _typeof$1(window)) === 'object' && window.RTCPeerConnection)) {
+ return;
+ }
+
+ var origCreateOffer = window.RTCPeerConnection.prototype.createOffer;
+
+ window.RTCPeerConnection.prototype.createOffer = function createOffer() {
+ var _this4 = this,
+ _arguments2 = arguments;
+
+ if (this.setParametersPromises && this.setParametersPromises.length) {
+ return Promise.all(this.setParametersPromises).then(function () {
+ return origCreateOffer.apply(_this4, _arguments2);
+ })["finally"](function () {
+ _this4.setParametersPromises = [];
+ });
+ }
+
+ return origCreateOffer.apply(this, arguments);
+ };
+ }
+
+ function shimCreateAnswer(window) {
+ // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647
+ // Firefox ignores the init sendEncodings options passed to addTransceiver
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918
+ if (!((typeof window === 'undefined' ? 'undefined' : _typeof$1(window)) === 'object' && window.RTCPeerConnection)) {
+ return;
+ }
+
+ var origCreateAnswer = window.RTCPeerConnection.prototype.createAnswer;
+
+ window.RTCPeerConnection.prototype.createAnswer = function createAnswer() {
+ var _this5 = this,
+ _arguments3 = arguments;
+
+ if (this.setParametersPromises && this.setParametersPromises.length) {
+ return Promise.all(this.setParametersPromises).then(function () {
+ return origCreateAnswer.apply(_this5, _arguments3);
+ })["finally"](function () {
+ _this5.setParametersPromises = [];
+ });
+ }
+
+ return origCreateAnswer.apply(this, arguments);
+ };
+ }
+ }, {
+ "../utils": 15,
+ "./getdisplaymedia": 12,
+ "./getusermedia": 13
+ }],
+ 12: [function (require, module, exports) {
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+ exports.shimGetDisplayMedia = shimGetDisplayMedia;
+
+ function shimGetDisplayMedia(window, preferredMediaSource) {
+ if (window.navigator.mediaDevices && 'getDisplayMedia' in window.navigator.mediaDevices) {
+ return;
+ }
+
+ if (!window.navigator.mediaDevices) {
+ return;
+ }
+
+ window.navigator.mediaDevices.getDisplayMedia = function getDisplayMedia(constraints) {
+ if (!(constraints && constraints.video)) {
+ var err = new DOMException('getDisplayMedia without video ' + 'constraints is undefined');
+ err.name = 'NotFoundError'; // from https://heycam.github.io/webidl/#idl-DOMException-error-names
+
+ err.code = 8;
+ return Promise.reject(err);
+ }
+
+ if (constraints.video === true) {
+ constraints.video = {
+ mediaSource: preferredMediaSource
+ };
+ } else {
+ constraints.video.mediaSource = preferredMediaSource;
+ }
+
+ return window.navigator.mediaDevices.getUserMedia(constraints);
+ };
+ }
+ }, {}],
+ 13: [function (require, module, exports) {
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+
+ var _typeof$1 = 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);
+ };
+
+ exports.shimGetUserMedia = shimGetUserMedia;
+
+ var _utils = require('../utils');
+
+ var utils = _interopRequireWildcard(_utils);
+
+ function _interopRequireWildcard(obj) {
+ if (obj && obj.__esModule) {
+ return obj;
+ } else {
+ var newObj = {};
+
+ if (obj != null) {
+ for (var key in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];
+ }
+ }
+
+ newObj["default"] = obj;
+ return newObj;
+ }
+ }
+
+ function shimGetUserMedia(window) {
+ var browserDetails = utils.detectBrowser(window);
+ var navigator = window && window.navigator;
+ var MediaStreamTrack = window && window.MediaStreamTrack;
+
+ navigator.getUserMedia = function (constraints, onSuccess, onError) {
+ // Replace Firefox 44+'s deprecation warning with unprefixed version.
+ utils.deprecated('navigator.getUserMedia', 'navigator.mediaDevices.getUserMedia');
+ navigator.mediaDevices.getUserMedia(constraints).then(onSuccess, onError);
+ };
+
+ if (!(browserDetails.version > 55 && 'autoGainControl' in navigator.mediaDevices.getSupportedConstraints())) {
+ var remap = function remap(obj, a, b) {
+ if (a in obj && !(b in obj)) {
+ obj[b] = obj[a];
+ delete obj[a];
+ }
+ };
+
+ var nativeGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);
+
+ navigator.mediaDevices.getUserMedia = function (c) {
+ if ((typeof c === 'undefined' ? 'undefined' : _typeof$1(c)) === 'object' && _typeof$1(c.audio) === 'object') {
+ c = JSON.parse(JSON.stringify(c));
+ remap(c.audio, 'autoGainControl', 'mozAutoGainControl');
+ remap(c.audio, 'noiseSuppression', 'mozNoiseSuppression');
+ }
+
+ return nativeGetUserMedia(c);
+ };
+
+ if (MediaStreamTrack && MediaStreamTrack.prototype.getSettings) {
+ var nativeGetSettings = MediaStreamTrack.prototype.getSettings;
+
+ MediaStreamTrack.prototype.getSettings = function () {
+ var obj = nativeGetSettings.apply(this, arguments);
+ remap(obj, 'mozAutoGainControl', 'autoGainControl');
+ remap(obj, 'mozNoiseSuppression', 'noiseSuppression');
+ return obj;
+ };
+ }
+
+ if (MediaStreamTrack && MediaStreamTrack.prototype.applyConstraints) {
+ var nativeApplyConstraints = MediaStreamTrack.prototype.applyConstraints;
+
+ MediaStreamTrack.prototype.applyConstraints = function (c) {
+ if (this.kind === 'audio' && (typeof c === 'undefined' ? 'undefined' : _typeof$1(c)) === 'object') {
+ c = JSON.parse(JSON.stringify(c));
+ remap(c, 'autoGainControl', 'mozAutoGainControl');
+ remap(c, 'noiseSuppression', 'mozNoiseSuppression');
+ }
+
+ return nativeApplyConstraints.apply(this, [c]);
+ };
+ }
+ }
+ }
+ }, {
+ "../utils": 15
+ }],
+ 14: [function (require, module, exports) {
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+
+ var _typeof$1 = 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);
+ };
+
+ exports.shimLocalStreamsAPI = shimLocalStreamsAPI;
+ exports.shimRemoteStreamsAPI = shimRemoteStreamsAPI;
+ exports.shimCallbacksAPI = shimCallbacksAPI;
+ exports.shimGetUserMedia = shimGetUserMedia;
+ exports.shimConstraints = shimConstraints;
+ exports.shimRTCIceServerUrls = shimRTCIceServerUrls;
+ exports.shimTrackEventTransceiver = shimTrackEventTransceiver;
+ exports.shimCreateOfferLegacy = shimCreateOfferLegacy;
+
+ var _utils = require('../utils');
+
+ var utils = _interopRequireWildcard(_utils);
+
+ function _interopRequireWildcard(obj) {
+ if (obj && obj.__esModule) {
+ return obj;
+ } else {
+ var newObj = {};
+
+ if (obj != null) {
+ for (var key in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];
+ }
+ }
+
+ newObj["default"] = obj;
+ return newObj;
+ }
+ }
+
+ function shimLocalStreamsAPI(window) {
+ if ((typeof window === 'undefined' ? 'undefined' : _typeof$1(window)) !== 'object' || !window.RTCPeerConnection) {
+ return;
+ }
+
+ if (!('getLocalStreams' in window.RTCPeerConnection.prototype)) {
+ window.RTCPeerConnection.prototype.getLocalStreams = function getLocalStreams() {
+ if (!this._localStreams) {
+ this._localStreams = [];
+ }
+
+ return this._localStreams;
+ };
+ }
+
+ if (!('addStream' in window.RTCPeerConnection.prototype)) {
+ var _addTrack = window.RTCPeerConnection.prototype.addTrack;
+
+ window.RTCPeerConnection.prototype.addStream = function addStream(stream) {
+ var _this = this;
+
+ if (!this._localStreams) {
+ this._localStreams = [];
+ }
+
+ if (!this._localStreams.includes(stream)) {
+ this._localStreams.push(stream);
+ } // Try to emulate Chrome's behaviour of adding in audio-video order.
+ // Safari orders by track id.
+
+
+ stream.getAudioTracks().forEach(function (track) {
+ return _addTrack.call(_this, track, stream);
+ });
+ stream.getVideoTracks().forEach(function (track) {
+ return _addTrack.call(_this, track, stream);
+ });
+ };
+
+ window.RTCPeerConnection.prototype.addTrack = function addTrack(track) {
+ var stream = arguments[1];
+
+ if (stream) {
+ if (!this._localStreams) {
+ this._localStreams = [stream];
+ } else if (!this._localStreams.includes(stream)) {
+ this._localStreams.push(stream);
+ }
+ }
+
+ return _addTrack.apply(this, arguments);
+ };
+ }
+
+ if (!('removeStream' in window.RTCPeerConnection.prototype)) {
+ window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
+ var _this2 = this;
+
+ if (!this._localStreams) {
+ this._localStreams = [];
+ }
+
+ var index = this._localStreams.indexOf(stream);
+
+ if (index === -1) {
+ return;
+ }
+
+ this._localStreams.splice(index, 1);
+
+ var tracks = stream.getTracks();
+ this.getSenders().forEach(function (sender) {
+ if (tracks.includes(sender.track)) {
+ _this2.removeTrack(sender);
+ }
+ });
+ };
+ }
+ }
+
+ function shimRemoteStreamsAPI(window) {
+ if ((typeof window === 'undefined' ? 'undefined' : _typeof$1(window)) !== 'object' || !window.RTCPeerConnection) {
+ return;
+ }
+
+ if (!('getRemoteStreams' in window.RTCPeerConnection.prototype)) {
+ window.RTCPeerConnection.prototype.getRemoteStreams = function getRemoteStreams() {
+ return this._remoteStreams ? this._remoteStreams : [];
+ };
+ }
+
+ if (!('onaddstream' in window.RTCPeerConnection.prototype)) {
+ Object.defineProperty(window.RTCPeerConnection.prototype, 'onaddstream', {
+ get: function get() {
+ return this._onaddstream;
+ },
+ set: function set(f) {
+ var _this3 = this;
+
+ if (this._onaddstream) {
+ this.removeEventListener('addstream', this._onaddstream);
+ this.removeEventListener('track', this._onaddstreampoly);
+ }
+
+ this.addEventListener('addstream', this._onaddstream = f);
+ this.addEventListener('track', this._onaddstreampoly = function (e) {
+ e.streams.forEach(function (stream) {
+ if (!_this3._remoteStreams) {
+ _this3._remoteStreams = [];
+ }
+
+ if (_this3._remoteStreams.includes(stream)) {
+ return;
+ }
+
+ _this3._remoteStreams.push(stream);
+
+ var event = new Event('addstream');
+ event.stream = stream;
+
+ _this3.dispatchEvent(event);
+ });
+ });
+ }
+ });
+ var origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription;
+
+ window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription() {
+ var pc = this;
+
+ if (!this._onaddstreampoly) {
+ this.addEventListener('track', this._onaddstreampoly = function (e) {
+ e.streams.forEach(function (stream) {
+ if (!pc._remoteStreams) {
+ pc._remoteStreams = [];
+ }
+
+ if (pc._remoteStreams.indexOf(stream) >= 0) {
+ return;
+ }
+
+ pc._remoteStreams.push(stream);
+
+ var event = new Event('addstream');
+ event.stream = stream;
+ pc.dispatchEvent(event);
+ });
+ });
+ }
+
+ return origSetRemoteDescription.apply(pc, arguments);
+ };
+ }
+ }
+
+ function shimCallbacksAPI(window) {
+ if ((typeof window === 'undefined' ? 'undefined' : _typeof$1(window)) !== 'object' || !window.RTCPeerConnection) {
+ return;
+ }
+
+ var prototype = window.RTCPeerConnection.prototype;
+ var origCreateOffer = prototype.createOffer;
+ var origCreateAnswer = prototype.createAnswer;
+ var setLocalDescription = prototype.setLocalDescription;
+ var setRemoteDescription = prototype.setRemoteDescription;
+ var addIceCandidate = prototype.addIceCandidate;
+
+ prototype.createOffer = function createOffer(successCallback, failureCallback) {
+ var options = arguments.length >= 2 ? arguments[2] : arguments[0];
+ var promise = origCreateOffer.apply(this, [options]);
+
+ if (!failureCallback) {
+ return promise;
+ }
+
+ promise.then(successCallback, failureCallback);
+ return Promise.resolve();
+ };
+
+ prototype.createAnswer = function createAnswer(successCallback, failureCallback) {
+ var options = arguments.length >= 2 ? arguments[2] : arguments[0];
+ var promise = origCreateAnswer.apply(this, [options]);
+
+ if (!failureCallback) {
+ return promise;
+ }
+
+ promise.then(successCallback, failureCallback);
+ return Promise.resolve();
+ };
+
+ var withCallback = function withCallback(description, successCallback, failureCallback) {
+ var promise = setLocalDescription.apply(this, [description]);
+
+ if (!failureCallback) {
+ return promise;
+ }
+
+ promise.then(successCallback, failureCallback);
+ return Promise.resolve();
+ };
+
+ prototype.setLocalDescription = withCallback;
+
+ withCallback = function withCallback(description, successCallback, failureCallback) {
+ var promise = setRemoteDescription.apply(this, [description]);
+
+ if (!failureCallback) {
+ return promise;
+ }
+
+ promise.then(successCallback, failureCallback);
+ return Promise.resolve();
+ };
+
+ prototype.setRemoteDescription = withCallback;
+
+ withCallback = function withCallback(candidate, successCallback, failureCallback) {
+ var promise = addIceCandidate.apply(this, [candidate]);
+
+ if (!failureCallback) {
+ return promise;
+ }
+
+ promise.then(successCallback, failureCallback);
+ return Promise.resolve();
+ };
+
+ prototype.addIceCandidate = withCallback;
+ }
+
+ function shimGetUserMedia(window) {
+ var navigator = window && window.navigator;
+
+ if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
+ // shim not needed in Safari 12.1
+ var mediaDevices = navigator.mediaDevices;
+
+ var _getUserMedia = mediaDevices.getUserMedia.bind(mediaDevices);
+
+ navigator.mediaDevices.getUserMedia = function (constraints) {
+ return _getUserMedia(shimConstraints(constraints));
+ };
+ }
+
+ if (!navigator.getUserMedia && navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
+ navigator.getUserMedia = function getUserMedia(constraints, cb, errcb) {
+ navigator.mediaDevices.getUserMedia(constraints).then(cb, errcb);
+ }.bind(navigator);
+ }
+ }
+
+ function shimConstraints(constraints) {
+ if (constraints && constraints.video !== undefined) {
+ return Object.assign({}, constraints, {
+ video: utils.compactObject(constraints.video)
+ });
+ }
+
+ return constraints;
+ }
+
+ function shimRTCIceServerUrls(window) {
+ // migrate from non-spec RTCIceServer.url to RTCIceServer.urls
+ var OrigPeerConnection = window.RTCPeerConnection;
+
+ window.RTCPeerConnection = function RTCPeerConnection(pcConfig, pcConstraints) {
+ if (pcConfig && pcConfig.iceServers) {
+ var newIceServers = [];
+
+ for (var i = 0; i < pcConfig.iceServers.length; i++) {
+ var server = pcConfig.iceServers[i];
+
+ if (!server.hasOwnProperty('urls') && server.hasOwnProperty('url')) {
+ utils.deprecated('RTCIceServer.url', 'RTCIceServer.urls');
+ server = JSON.parse(JSON.stringify(server));
+ server.urls = server.url;
+ delete server.url;
+ newIceServers.push(server);
+ } else {
+ newIceServers.push(pcConfig.iceServers[i]);
+ }
+ }
+
+ pcConfig.iceServers = newIceServers;
+ }
+
+ return new OrigPeerConnection(pcConfig, pcConstraints);
+ };
+
+ window.RTCPeerConnection.prototype = OrigPeerConnection.prototype; // wrap static methods. Currently just generateCertificate.
+
+ if ('generateCertificate' in window.RTCPeerConnection) {
+ Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', {
+ get: function get() {
+ return OrigPeerConnection.generateCertificate;
+ }
+ });
+ }
+ }
+
+ function shimTrackEventTransceiver(window) {
+ // Add event.transceiver member over deprecated event.receiver
+ if ((typeof window === 'undefined' ? 'undefined' : _typeof$1(window)) === 'object' && window.RTCTrackEvent && 'receiver' in window.RTCTrackEvent.prototype && !('transceiver' in window.RTCTrackEvent.prototype)) {
+ Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', {
+ get: function get() {
+ return {
+ receiver: this.receiver
+ };
+ }
+ });
+ }
+ }
+
+ function shimCreateOfferLegacy(window) {
+ var origCreateOffer = window.RTCPeerConnection.prototype.createOffer;
+
+ window.RTCPeerConnection.prototype.createOffer = function createOffer(offerOptions) {
+ if (offerOptions) {
+ if (typeof offerOptions.offerToReceiveAudio !== 'undefined') {
+ // support bit values
+ offerOptions.offerToReceiveAudio = !!offerOptions.offerToReceiveAudio;
+ }
+
+ var audioTransceiver = this.getTransceivers().find(function (transceiver) {
+ return transceiver.receiver.track.kind === 'audio';
+ });
+
+ if (offerOptions.offerToReceiveAudio === false && audioTransceiver) {
+ if (audioTransceiver.direction === 'sendrecv') {
+ if (audioTransceiver.setDirection) {
+ audioTransceiver.setDirection('sendonly');
+ } else {
+ audioTransceiver.direction = 'sendonly';
+ }
+ } else if (audioTransceiver.direction === 'recvonly') {
+ if (audioTransceiver.setDirection) {
+ audioTransceiver.setDirection('inactive');
+ } else {
+ audioTransceiver.direction = 'inactive';
+ }
+ }
+ } else if (offerOptions.offerToReceiveAudio === true && !audioTransceiver) {
+ this.addTransceiver('audio');
+ }
+
+ if (typeof offerOptions.offerToReceiveVideo !== 'undefined') {
+ // support bit values
+ offerOptions.offerToReceiveVideo = !!offerOptions.offerToReceiveVideo;
+ }
+
+ var videoTransceiver = this.getTransceivers().find(function (transceiver) {
+ return transceiver.receiver.track.kind === 'video';
+ });
+
+ if (offerOptions.offerToReceiveVideo === false && videoTransceiver) {
+ if (videoTransceiver.direction === 'sendrecv') {
+ if (videoTransceiver.setDirection) {
+ videoTransceiver.setDirection('sendonly');
+ } else {
+ videoTransceiver.direction = 'sendonly';
+ }
+ } else if (videoTransceiver.direction === 'recvonly') {
+ if (videoTransceiver.setDirection) {
+ videoTransceiver.setDirection('inactive');
+ } else {
+ videoTransceiver.direction = 'inactive';
+ }
+ }
+ } else if (offerOptions.offerToReceiveVideo === true && !videoTransceiver) {
+ this.addTransceiver('video');
+ }
+ }
+
+ return origCreateOffer.apply(this, arguments);
+ };
+ }
+ }, {
+ "../utils": 15
+ }],
+ 15: [function (require, module, exports) {
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+
+ var _typeof$1 = 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);
+ };
+
+ exports.extractVersion = extractVersion;
+ exports.wrapPeerConnectionEvent = wrapPeerConnectionEvent;
+ exports.disableLog = disableLog;
+ exports.disableWarnings = disableWarnings;
+ exports.log = log;
+ exports.deprecated = deprecated;
+ exports.detectBrowser = detectBrowser;
+ exports.compactObject = compactObject;
+ exports.walkStats = walkStats;
+ exports.filterStats = filterStats;
+
+ function _defineProperty(obj, key, value) {
+ if (key in obj) {
+ Object.defineProperty(obj, key, {
+ value: value,
+ enumerable: true,
+ configurable: true,
+ writable: true
+ });
+ } else {
+ obj[key] = value;
+ }
+
+ return obj;
+ }
+
+ var logDisabled_ = true;
+ var deprecationWarnings_ = true;
+ /**
+ * Extract browser version out of the provided user agent string.
+ *
+ * @param {!string} uastring userAgent string.
+ * @param {!string} expr Regular expression used as match criteria.
+ * @param {!number} pos position in the version string to be returned.
+ * @return {!number} browser version.
+ */
+
+ function extractVersion(uastring, expr, pos) {
+ var match = uastring.match(expr);
+ return match && match.length >= pos && parseInt(match[pos], 10);
+ } // Wraps the peerconnection event eventNameToWrap in a function
+ // which returns the modified event object (or false to prevent
+ // the event).
+
+
+ function wrapPeerConnectionEvent(window, eventNameToWrap, wrapper) {
+ if (!window.RTCPeerConnection) {
+ return;
+ }
+
+ var proto = window.RTCPeerConnection.prototype;
+ var nativeAddEventListener = proto.addEventListener;
+
+ proto.addEventListener = function (nativeEventName, cb) {
+ if (nativeEventName !== eventNameToWrap) {
+ return nativeAddEventListener.apply(this, arguments);
+ }
+
+ var wrappedCallback = function wrappedCallback(e) {
+ var modifiedEvent = wrapper(e);
+
+ if (modifiedEvent) {
+ cb(modifiedEvent);
+ }
+ };
+
+ this._eventMap = this._eventMap || {};
+ this._eventMap[cb] = wrappedCallback;
+ return nativeAddEventListener.apply(this, [nativeEventName, wrappedCallback]);
+ };
+
+ var nativeRemoveEventListener = proto.removeEventListener;
+
+ proto.removeEventListener = function (nativeEventName, cb) {
+ if (nativeEventName !== eventNameToWrap || !this._eventMap || !this._eventMap[cb]) {
+ return nativeRemoveEventListener.apply(this, arguments);
+ }
+
+ var unwrappedCb = this._eventMap[cb];
+ delete this._eventMap[cb];
+ return nativeRemoveEventListener.apply(this, [nativeEventName, unwrappedCb]);
+ };
+
+ Object.defineProperty(proto, 'on' + eventNameToWrap, {
+ get: function get() {
+ return this['_on' + eventNameToWrap];
+ },
+ set: function set(cb) {
+ if (this['_on' + eventNameToWrap]) {
+ this.removeEventListener(eventNameToWrap, this['_on' + eventNameToWrap]);
+ delete this['_on' + eventNameToWrap];
+ }
+
+ if (cb) {
+ this.addEventListener(eventNameToWrap, this['_on' + eventNameToWrap] = cb);
+ }
+ },
+ enumerable: true,
+ configurable: true
+ });
+ }
+
+ function disableLog(bool) {
+ if (typeof bool !== 'boolean') {
+ return new Error('Argument type: ' + (typeof bool === 'undefined' ? 'undefined' : _typeof$1(bool)) + '. Please use a boolean.');
+ }
+
+ logDisabled_ = bool;
+ return bool ? 'adapter.js logging disabled' : 'adapter.js logging enabled';
+ }
+ /**
+ * Disable or enable deprecation warnings
+ * @param {!boolean} bool set to true to disable warnings.
+ */
+
+
+ function disableWarnings(bool) {
+ if (typeof bool !== 'boolean') {
+ return new Error('Argument type: ' + (typeof bool === 'undefined' ? 'undefined' : _typeof$1(bool)) + '. Please use a boolean.');
+ }
+
+ deprecationWarnings_ = !bool;
+ return 'adapter.js deprecation warnings ' + (bool ? 'disabled' : 'enabled');
+ }
+
+ function log() {
+ if ((typeof window === 'undefined' ? 'undefined' : _typeof$1(window)) === 'object') {
+ if (logDisabled_) {
+ return;
+ }
+
+ if (typeof console !== 'undefined' && typeof console.log === 'function') {
+ console.log.apply(console, arguments);
+ }
+ }
+ }
+ /**
+ * Shows a deprecation warning suggesting the modern and spec-compatible API.
+ */
+
+
+ function deprecated(oldMethod, newMethod) {
+ if (!deprecationWarnings_) {
+ return;
+ }
+
+ console.warn(oldMethod + ' is deprecated, please use ' + newMethod + ' instead.');
+ }
+ /**
+ * Browser detector.
+ *
+ * @return {object} result containing browser and version
+ * properties.
+ */
+
+
+ function detectBrowser(window) {
+ var navigator = window.navigator; // Returned result object.
+
+ var result = {
+ browser: null,
+ version: null
+ }; // Fail early if it's not a browser
+
+ if (typeof window === 'undefined' || !window.navigator) {
+ result.browser = 'Not a browser.';
+ return result;
+ }
+
+ if (navigator.mozGetUserMedia) {
+ // Firefox.
+ result.browser = 'firefox';
+ result.version = extractVersion(navigator.userAgent, /Firefox\/(\d+)\./, 1);
+ } else if (navigator.webkitGetUserMedia || window.isSecureContext === false && window.webkitRTCPeerConnection && !window.RTCIceGatherer) {
+ // Chrome, Chromium, Webview, Opera.
+ // Version matches Chrome/WebRTC version.
+ // Chrome 74 removed webkitGetUserMedia on http as well so we need the
+ // more complicated fallback to webkitRTCPeerConnection.
+ result.browser = 'chrome';
+ result.version = extractVersion(navigator.userAgent, /Chrom(e|ium)\/(\d+)\./, 2);
+ } else if (navigator.mediaDevices && navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)) {
+ // Edge.
+ result.browser = 'edge';
+ result.version = extractVersion(navigator.userAgent, /Edge\/(\d+).(\d+)$/, 2);
+ } else if (window.RTCPeerConnection && navigator.userAgent.match(/AppleWebKit\/(\d+)\./)) {
+ // Safari.
+ result.browser = 'safari';
+ result.version = extractVersion(navigator.userAgent, /AppleWebKit\/(\d+)\./, 1);
+ result.supportsUnifiedPlan = window.RTCRtpTransceiver && 'currentDirection' in window.RTCRtpTransceiver.prototype;
+ } else {
+ // Default fallthrough: not supported.
+ result.browser = 'Not a supported browser.';
+ return result;
+ }
+
+ return result;
+ }
+ /**
+ * Checks if something is an object.
+ *
+ * @param {*} val The something you want to check.
+ * @return true if val is an object, false otherwise.
+ */
+
+
+ function isObject(val) {
+ return Object.prototype.toString.call(val) === '[object Object]';
+ }
+ /**
+ * Remove all empty objects and undefined values
+ * from a nested object -- an enhanced and vanilla version
+ * of Lodash's `compact`.
+ */
+
+
+ function compactObject(data) {
+ if (!isObject(data)) {
+ return data;
+ }
+
+ return Object.keys(data).reduce(function (accumulator, key) {
+ var isObj = isObject(data[key]);
+ var value = isObj ? compactObject(data[key]) : data[key];
+ var isEmptyObject = isObj && !Object.keys(value).length;
+
+ if (value === undefined || isEmptyObject) {
+ return accumulator;
+ }
+
+ return Object.assign(accumulator, _defineProperty({}, key, value));
+ }, {});
+ }
+ /* iterates the stats graph recursively. */
+
+
+ function walkStats(stats, base, resultSet) {
+ if (!base || resultSet.has(base.id)) {
+ return;
+ }
+
+ resultSet.set(base.id, base);
+ Object.keys(base).forEach(function (name) {
+ if (name.endsWith('Id')) {
+ walkStats(stats, stats.get(base[name]), resultSet);
+ } else if (name.endsWith('Ids')) {
+ base[name].forEach(function (id) {
+ walkStats(stats, stats.get(id), resultSet);
+ });
+ }
+ });
+ }
+ /* filter getStats for a sender/receiver track. */
+
+
+ function filterStats(result, track, outbound) {
+ var streamStatsType = outbound ? 'outbound-rtp' : 'inbound-rtp';
+ var filteredResult = new Map();
+
+ if (track === null) {
+ return filteredResult;
+ }
+
+ var trackStats = [];
+ result.forEach(function (value) {
+ if (value.type === 'track' && value.trackIdentifier === track.id) {
+ trackStats.push(value);
+ }
+ });
+ trackStats.forEach(function (trackStat) {
+ result.forEach(function (stats) {
+ if (stats.type === streamStatsType && stats.trackId === trackStat.id) {
+ walkStats(result, stats, filteredResult);
+ }
+ });
+ });
+ return filteredResult;
+ }
+ }, {}],
+ 16: [function (require, module, exports) {
+
+ var SDPUtils = require('sdp');
+
+ function fixStatsType(stat) {
+ return {
+ inboundrtp: 'inbound-rtp',
+ outboundrtp: 'outbound-rtp',
+ candidatepair: 'candidate-pair',
+ localcandidate: 'local-candidate',
+ remotecandidate: 'remote-candidate'
+ }[stat.type] || stat.type;
+ }
+
+ function writeMediaSection(transceiver, caps, type, stream, dtlsRole) {
+ var sdp = SDPUtils.writeRtpDescription(transceiver.kind, caps); // Map ICE parameters (ufrag, pwd) to SDP.
+
+ sdp += SDPUtils.writeIceParameters(transceiver.iceGatherer.getLocalParameters()); // Map DTLS parameters to SDP.
+
+ sdp += SDPUtils.writeDtlsParameters(transceiver.dtlsTransport.getLocalParameters(), type === 'offer' ? 'actpass' : dtlsRole || 'active');
+ sdp += 'a=mid:' + transceiver.mid + '\r\n';
+
+ if (transceiver.rtpSender && transceiver.rtpReceiver) {
+ sdp += 'a=sendrecv\r\n';
+ } else if (transceiver.rtpSender) {
+ sdp += 'a=sendonly\r\n';
+ } else if (transceiver.rtpReceiver) {
+ sdp += 'a=recvonly\r\n';
+ } else {
+ sdp += 'a=inactive\r\n';
+ }
+
+ if (transceiver.rtpSender) {
+ var trackId = transceiver.rtpSender._initialTrackId || transceiver.rtpSender.track.id;
+ transceiver.rtpSender._initialTrackId = trackId; // spec.
+
+ var msid = 'msid:' + (stream ? stream.id : '-') + ' ' + trackId + '\r\n';
+ sdp += 'a=' + msid; // for Chrome. Legacy should no longer be required.
+
+ sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc + ' ' + msid; // RTX
+
+ if (transceiver.sendEncodingParameters[0].rtx) {
+ sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc + ' ' + msid;
+ sdp += 'a=ssrc-group:FID ' + transceiver.sendEncodingParameters[0].ssrc + ' ' + transceiver.sendEncodingParameters[0].rtx.ssrc + '\r\n';
+ }
+ } // FIXME: this should be written by writeRtpDescription.
+
+
+ sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc + ' cname:' + SDPUtils.localCName + '\r\n';
+
+ if (transceiver.rtpSender && transceiver.sendEncodingParameters[0].rtx) {
+ sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc + ' cname:' + SDPUtils.localCName + '\r\n';
+ }
+
+ return sdp;
+ } // Edge does not like
+ // 1) stun: filtered after 14393 unless ?transport=udp is present
+ // 2) turn: that does not have all of turn:host:port?transport=udp
+ // 3) turn: with ipv6 addresses
+ // 4) turn: occurring muliple times
+
+
+ function filterIceServers(iceServers, edgeVersion) {
+ var hasTurn = false;
+ iceServers = JSON.parse(JSON.stringify(iceServers));
+ return iceServers.filter(function (server) {
+ if (server && (server.urls || server.url)) {
+ var urls = server.urls || server.url;
+
+ if (server.url && !server.urls) {
+ console.warn('RTCIceServer.url is deprecated! Use urls instead.');
+ }
+
+ var isString = typeof urls === 'string';
+
+ if (isString) {
+ urls = [urls];
+ }
+
+ urls = urls.filter(function (url) {
+ var validTurn = url.indexOf('turn:') === 0 && url.indexOf('transport=udp') !== -1 && url.indexOf('turn:[') === -1 && !hasTurn;
+
+ if (validTurn) {
+ hasTurn = true;
+ return true;
+ }
+
+ return url.indexOf('stun:') === 0 && edgeVersion >= 14393 && url.indexOf('?transport=udp') === -1;
+ });
+ delete server.url;
+ server.urls = isString ? urls[0] : urls;
+ return !!urls.length;
+ }
+ });
+ } // Determines the intersection of local and remote capabilities.
+
+
+ function getCommonCapabilities(localCapabilities, remoteCapabilities) {
+ var commonCapabilities = {
+ codecs: [],
+ headerExtensions: [],
+ fecMechanisms: []
+ };
+
+ var findCodecByPayloadType = function findCodecByPayloadType(pt, codecs) {
+ pt = parseInt(pt, 10);
+
+ for (var i = 0; i < codecs.length; i++) {
+ if (codecs[i].payloadType === pt || codecs[i].preferredPayloadType === pt) {
+ return codecs[i];
+ }
+ }
+ };
+
+ var rtxCapabilityMatches = function rtxCapabilityMatches(lRtx, rRtx, lCodecs, rCodecs) {
+ var lCodec = findCodecByPayloadType(lRtx.parameters.apt, lCodecs);
+ var rCodec = findCodecByPayloadType(rRtx.parameters.apt, rCodecs);
+ return lCodec && rCodec && lCodec.name.toLowerCase() === rCodec.name.toLowerCase();
+ };
+
+ localCapabilities.codecs.forEach(function (lCodec) {
+ for (var i = 0; i < remoteCapabilities.codecs.length; i++) {
+ var rCodec = remoteCapabilities.codecs[i];
+
+ if (lCodec.name.toLowerCase() === rCodec.name.toLowerCase() && lCodec.clockRate === rCodec.clockRate) {
+ if (lCodec.name.toLowerCase() === 'rtx' && lCodec.parameters && rCodec.parameters.apt) {
+ // for RTX we need to find the local rtx that has a apt
+ // which points to the same local codec as the remote one.
+ if (!rtxCapabilityMatches(lCodec, rCodec, localCapabilities.codecs, remoteCapabilities.codecs)) {
+ continue;
+ }
+ }
+
+ rCodec = JSON.parse(JSON.stringify(rCodec)); // deepcopy
+ // number of channels is the highest common number of channels
+
+ rCodec.numChannels = Math.min(lCodec.numChannels, rCodec.numChannels); // push rCodec so we reply with offerer payload type
+
+ commonCapabilities.codecs.push(rCodec); // determine common feedback mechanisms
+
+ rCodec.rtcpFeedback = rCodec.rtcpFeedback.filter(function (fb) {
+ for (var j = 0; j < lCodec.rtcpFeedback.length; j++) {
+ if (lCodec.rtcpFeedback[j].type === fb.type && lCodec.rtcpFeedback[j].parameter === fb.parameter) {
+ return true;
+ }
+ }
+
+ return false;
+ }); // FIXME: also need to determine .parameters
+ // see https://github.com/openpeer/ortc/issues/569
+
+ break;
+ }
+ }
+ });
+ localCapabilities.headerExtensions.forEach(function (lHeaderExtension) {
+ for (var i = 0; i < remoteCapabilities.headerExtensions.length; i++) {
+ var rHeaderExtension = remoteCapabilities.headerExtensions[i];
+
+ if (lHeaderExtension.uri === rHeaderExtension.uri) {
+ commonCapabilities.headerExtensions.push(rHeaderExtension);
+ break;
+ }
+ }
+ }); // FIXME: fecMechanisms
+
+ return commonCapabilities;
+ } // is action=setLocalDescription with type allowed in signalingState
+
+
+ function isActionAllowedInSignalingState(action, type, signalingState) {
+ return {
+ offer: {
+ setLocalDescription: ['stable', 'have-local-offer'],
+ setRemoteDescription: ['stable', 'have-remote-offer']
+ },
+ answer: {
+ setLocalDescription: ['have-remote-offer', 'have-local-pranswer'],
+ setRemoteDescription: ['have-local-offer', 'have-remote-pranswer']
+ }
+ }[type][action].indexOf(signalingState) !== -1;
+ }
+
+ function maybeAddCandidate(iceTransport, candidate) {
+ // Edge's internal representation adds some fields therefore
+ // not all field褧 are taken into account.
+ var alreadyAdded = iceTransport.getRemoteCandidates().find(function (remoteCandidate) {
+ return candidate.foundation === remoteCandidate.foundation && candidate.ip === remoteCandidate.ip && candidate.port === remoteCandidate.port && candidate.priority === remoteCandidate.priority && candidate.protocol === remoteCandidate.protocol && candidate.type === remoteCandidate.type;
+ });
+
+ if (!alreadyAdded) {
+ iceTransport.addRemoteCandidate(candidate);
+ }
+
+ return !alreadyAdded;
+ }
+
+ function makeError(name, description) {
+ var e = new Error(description);
+ e.name = name; // legacy error codes from https://heycam.github.io/webidl/#idl-DOMException-error-names
+
+ e.code = {
+ NotSupportedError: 9,
+ InvalidStateError: 11,
+ InvalidAccessError: 15,
+ TypeError: undefined,
+ OperationError: undefined
+ }[name];
+ return e;
+ }
+
+ module.exports = function (window, edgeVersion) {
+ // https://w3c.github.io/mediacapture-main/#mediastream
+ // Helper function to add the track to the stream and
+ // dispatch the event ourselves.
+ function addTrackToStreamAndFireEvent(track, stream) {
+ stream.addTrack(track);
+ stream.dispatchEvent(new window.MediaStreamTrackEvent('addtrack', {
+ track: track
+ }));
+ }
+
+ function removeTrackFromStreamAndFireEvent(track, stream) {
+ stream.removeTrack(track);
+ stream.dispatchEvent(new window.MediaStreamTrackEvent('removetrack', {
+ track: track
+ }));
+ }
+
+ function fireAddTrack(pc, track, receiver, streams) {
+ var trackEvent = new Event('track');
+ trackEvent.track = track;
+ trackEvent.receiver = receiver;
+ trackEvent.transceiver = {
+ receiver: receiver
+ };
+ trackEvent.streams = streams;
+ window.setTimeout(function () {
+ pc._dispatchEvent('track', trackEvent);
+ });
+ }
+
+ var RTCPeerConnection = function RTCPeerConnection(config) {
+ var pc = this;
+
+ var _eventTarget = document.createDocumentFragment();
+
+ ['addEventListener', 'removeEventListener', 'dispatchEvent'].forEach(function (method) {
+ pc[method] = _eventTarget[method].bind(_eventTarget);
+ });
+ this.canTrickleIceCandidates = null;
+ this.needNegotiation = false;
+ this.localStreams = [];
+ this.remoteStreams = [];
+ this._localDescription = null;
+ this._remoteDescription = null;
+ this.signalingState = 'stable';
+ this.iceConnectionState = 'new';
+ this.connectionState = 'new';
+ this.iceGatheringState = 'new';
+ config = JSON.parse(JSON.stringify(config || {}));
+ this.usingBundle = config.bundlePolicy === 'max-bundle';
+
+ if (config.rtcpMuxPolicy === 'negotiate') {
+ throw makeError('NotSupportedError', 'rtcpMuxPolicy \'negotiate\' is not supported');
+ } else if (!config.rtcpMuxPolicy) {
+ config.rtcpMuxPolicy = 'require';
+ }
+
+ switch (config.iceTransportPolicy) {
+ case 'all':
+ case 'relay':
+ break;
+
+ default:
+ config.iceTransportPolicy = 'all';
+ break;
+ }
+
+ switch (config.bundlePolicy) {
+ case 'balanced':
+ case 'max-compat':
+ case 'max-bundle':
+ break;
+
+ default:
+ config.bundlePolicy = 'balanced';
+ break;
+ }
+
+ config.iceServers = filterIceServers(config.iceServers || [], edgeVersion);
+ this._iceGatherers = [];
+
+ if (config.iceCandidatePoolSize) {
+ for (var i = config.iceCandidatePoolSize; i > 0; i--) {
+ this._iceGatherers.push(new window.RTCIceGatherer({
+ iceServers: config.iceServers,
+ gatherPolicy: config.iceTransportPolicy
+ }));
+ }
+ } else {
+ config.iceCandidatePoolSize = 0;
+ }
+
+ this._config = config; // per-track iceGathers, iceTransports, dtlsTransports, rtpSenders, ...
+ // everything that is needed to describe a SDP m-line.
+
+ this.transceivers = [];
+ this._sdpSessionId = SDPUtils.generateSessionId();
+ this._sdpSessionVersion = 0;
+ this._dtlsRole = undefined; // role for a=setup to use in answers.
+
+ this._isClosed = false;
+ };
+
+ Object.defineProperty(RTCPeerConnection.prototype, 'localDescription', {
+ configurable: true,
+ get: function get() {
+ return this._localDescription;
+ }
+ });
+ Object.defineProperty(RTCPeerConnection.prototype, 'remoteDescription', {
+ configurable: true,
+ get: function get() {
+ return this._remoteDescription;
+ }
+ }); // set up event handlers on prototype
+
+ RTCPeerConnection.prototype.onicecandidate = null;
+ RTCPeerConnection.prototype.onaddstream = null;
+ RTCPeerConnection.prototype.ontrack = null;
+ RTCPeerConnection.prototype.onremovestream = null;
+ RTCPeerConnection.prototype.onsignalingstatechange = null;
+ RTCPeerConnection.prototype.oniceconnectionstatechange = null;
+ RTCPeerConnection.prototype.onconnectionstatechange = null;
+ RTCPeerConnection.prototype.onicegatheringstatechange = null;
+ RTCPeerConnection.prototype.onnegotiationneeded = null;
+ RTCPeerConnection.prototype.ondatachannel = null;
+
+ RTCPeerConnection.prototype._dispatchEvent = function (name, event) {
+ if (this._isClosed) {
+ return;
+ }
+
+ this.dispatchEvent(event);
+
+ if (typeof this['on' + name] === 'function') {
+ this['on' + name](event);
+ }
+ };
+
+ RTCPeerConnection.prototype._emitGatheringStateChange = function () {
+ var event = new Event('icegatheringstatechange');
+
+ this._dispatchEvent('icegatheringstatechange', event);
+ };
+
+ RTCPeerConnection.prototype.getConfiguration = function () {
+ return this._config;
+ };
+
+ RTCPeerConnection.prototype.getLocalStreams = function () {
+ return this.localStreams;
+ };
+
+ RTCPeerConnection.prototype.getRemoteStreams = function () {
+ return this.remoteStreams;
+ }; // internal helper to create a transceiver object.
+ // (which is not yet the same as the WebRTC 1.0 transceiver)
+
+
+ RTCPeerConnection.prototype._createTransceiver = function (kind, doNotAdd) {
+ var hasBundleTransport = this.transceivers.length > 0;
+ var transceiver = {
+ track: null,
+ iceGatherer: null,
+ iceTransport: null,
+ dtlsTransport: null,
+ localCapabilities: null,
+ remoteCapabilities: null,
+ rtpSender: null,
+ rtpReceiver: null,
+ kind: kind,
+ mid: null,
+ sendEncodingParameters: null,
+ recvEncodingParameters: null,
+ stream: null,
+ associatedRemoteMediaStreams: [],
+ wantReceive: true
+ };
+
+ if (this.usingBundle && hasBundleTransport) {
+ transceiver.iceTransport = this.transceivers[0].iceTransport;
+ transceiver.dtlsTransport = this.transceivers[0].dtlsTransport;
+ } else {
+ var transports = this._createIceAndDtlsTransports();
+
+ transceiver.iceTransport = transports.iceTransport;
+ transceiver.dtlsTransport = transports.dtlsTransport;
+ }
+
+ if (!doNotAdd) {
+ this.transceivers.push(transceiver);
+ }
+
+ return transceiver;
+ };
+
+ RTCPeerConnection.prototype.addTrack = function (track, stream) {
+ if (this._isClosed) {
+ throw makeError('InvalidStateError', 'Attempted to call addTrack on a closed peerconnection.');
+ }
+
+ var alreadyExists = this.transceivers.find(function (s) {
+ return s.track === track;
+ });
+
+ if (alreadyExists) {
+ throw makeError('InvalidAccessError', 'Track already exists.');
+ }
+
+ var transceiver;
+
+ for (var i = 0; i < this.transceivers.length; i++) {
+ if (!this.transceivers[i].track && this.transceivers[i].kind === track.kind) {
+ transceiver = this.transceivers[i];
+ }
+ }
+
+ if (!transceiver) {
+ transceiver = this._createTransceiver(track.kind);
+ }
+
+ this._maybeFireNegotiationNeeded();
+
+ if (this.localStreams.indexOf(stream) === -1) {
+ this.localStreams.push(stream);
+ }
+
+ transceiver.track = track;
+ transceiver.stream = stream;
+ transceiver.rtpSender = new window.RTCRtpSender(track, transceiver.dtlsTransport);
+ return transceiver.rtpSender;
+ };
+
+ RTCPeerConnection.prototype.addStream = function (stream) {
+ var pc = this;
+
+ if (edgeVersion >= 15025) {
+ stream.getTracks().forEach(function (track) {
+ pc.addTrack(track, stream);
+ });
+ } else {
+ // Clone is necessary for local demos mostly, attaching directly
+ // to two different senders does not work (build 10547).
+ // Fixed in 15025 (or earlier)
+ var clonedStream = stream.clone();
+ stream.getTracks().forEach(function (track, idx) {
+ var clonedTrack = clonedStream.getTracks()[idx];
+ track.addEventListener('enabled', function (event) {
+ clonedTrack.enabled = event.enabled;
+ });
+ });
+ clonedStream.getTracks().forEach(function (track) {
+ pc.addTrack(track, clonedStream);
+ });
+ }
+ };
+
+ RTCPeerConnection.prototype.removeTrack = function (sender) {
+ if (this._isClosed) {
+ throw makeError('InvalidStateError', 'Attempted to call removeTrack on a closed peerconnection.');
+ }
+
+ if (!(sender instanceof window.RTCRtpSender)) {
+ throw new TypeError('Argument 1 of RTCPeerConnection.removeTrack ' + 'does not implement interface RTCRtpSender.');
+ }
+
+ var transceiver = this.transceivers.find(function (t) {
+ return t.rtpSender === sender;
+ });
+
+ if (!transceiver) {
+ throw makeError('InvalidAccessError', 'Sender was not created by this connection.');
+ }
+
+ var stream = transceiver.stream;
+ transceiver.rtpSender.stop();
+ transceiver.rtpSender = null;
+ transceiver.track = null;
+ transceiver.stream = null; // remove the stream from the set of local streams
+
+ var localStreams = this.transceivers.map(function (t) {
+ return t.stream;
+ });
+
+ if (localStreams.indexOf(stream) === -1 && this.localStreams.indexOf(stream) > -1) {
+ this.localStreams.splice(this.localStreams.indexOf(stream), 1);
+ }
+
+ this._maybeFireNegotiationNeeded();
+ };
+
+ RTCPeerConnection.prototype.removeStream = function (stream) {
+ var pc = this;
+ stream.getTracks().forEach(function (track) {
+ var sender = pc.getSenders().find(function (s) {
+ return s.track === track;
+ });
+
+ if (sender) {
+ pc.removeTrack(sender);
+ }
+ });
+ };
+
+ RTCPeerConnection.prototype.getSenders = function () {
+ return this.transceivers.filter(function (transceiver) {
+ return !!transceiver.rtpSender;
+ }).map(function (transceiver) {
+ return transceiver.rtpSender;
+ });
+ };
+
+ RTCPeerConnection.prototype.getReceivers = function () {
+ return this.transceivers.filter(function (transceiver) {
+ return !!transceiver.rtpReceiver;
+ }).map(function (transceiver) {
+ return transceiver.rtpReceiver;
+ });
+ };
+
+ RTCPeerConnection.prototype._createIceGatherer = function (sdpMLineIndex, usingBundle) {
+ var pc = this;
+
+ if (usingBundle && sdpMLineIndex > 0) {
+ return this.transceivers[0].iceGatherer;
+ } else if (this._iceGatherers.length) {
+ return this._iceGatherers.shift();
+ }
+
+ var iceGatherer = new window.RTCIceGatherer({
+ iceServers: this._config.iceServers,
+ gatherPolicy: this._config.iceTransportPolicy
+ });
+ Object.defineProperty(iceGatherer, 'state', {
+ value: 'new',
+ writable: true
+ });
+ this.transceivers[sdpMLineIndex].bufferedCandidateEvents = [];
+
+ this.transceivers[sdpMLineIndex].bufferCandidates = function (event) {
+ var end = !event.candidate || Object.keys(event.candidate).length === 0; // polyfill since RTCIceGatherer.state is not implemented in
+ // Edge 10547 yet.
+
+ iceGatherer.state = end ? 'completed' : 'gathering';
+
+ if (pc.transceivers[sdpMLineIndex].bufferedCandidateEvents !== null) {
+ pc.transceivers[sdpMLineIndex].bufferedCandidateEvents.push(event);
+ }
+ };
+
+ iceGatherer.addEventListener('localcandidate', this.transceivers[sdpMLineIndex].bufferCandidates);
+ return iceGatherer;
+ }; // start gathering from an RTCIceGatherer.
+
+
+ RTCPeerConnection.prototype._gather = function (mid, sdpMLineIndex) {
+ var pc = this;
+ var iceGatherer = this.transceivers[sdpMLineIndex].iceGatherer;
+
+ if (iceGatherer.onlocalcandidate) {
+ return;
+ }
+
+ var bufferedCandidateEvents = this.transceivers[sdpMLineIndex].bufferedCandidateEvents;
+ this.transceivers[sdpMLineIndex].bufferedCandidateEvents = null;
+ iceGatherer.removeEventListener('localcandidate', this.transceivers[sdpMLineIndex].bufferCandidates);
+
+ iceGatherer.onlocalcandidate = function (evt) {
+ if (pc.usingBundle && sdpMLineIndex > 0) {
+ // if we know that we use bundle we can drop candidates with
+ // 褧dpMLineIndex > 0. If we don't do this then our state gets
+ // confused since we dispose the extra ice gatherer.
+ return;
+ }
+
+ var event = new Event('icecandidate');
+ event.candidate = {
+ sdpMid: mid,
+ sdpMLineIndex: sdpMLineIndex
+ };
+ var cand = evt.candidate; // Edge emits an empty object for RTCIceCandidateComplete鈥�
+
+ var end = !cand || Object.keys(cand).length === 0;
+
+ if (end) {
+ // polyfill since RTCIceGatherer.state is not implemented in
+ // Edge 10547 yet.
+ if (iceGatherer.state === 'new' || iceGatherer.state === 'gathering') {
+ iceGatherer.state = 'completed';
+ }
+ } else {
+ if (iceGatherer.state === 'new') {
+ iceGatherer.state = 'gathering';
+ } // RTCIceCandidate doesn't have a component, needs to be added
+
+
+ cand.component = 1; // also the usernameFragment. TODO: update SDP to take both variants.
+
+ cand.ufrag = iceGatherer.getLocalParameters().usernameFragment;
+ var serializedCandidate = SDPUtils.writeCandidate(cand);
+ event.candidate = Object.assign(event.candidate, SDPUtils.parseCandidate(serializedCandidate));
+ event.candidate.candidate = serializedCandidate;
+
+ event.candidate.toJSON = function () {
+ return {
+ candidate: event.candidate.candidate,
+ sdpMid: event.candidate.sdpMid,
+ sdpMLineIndex: event.candidate.sdpMLineIndex,
+ usernameFragment: event.candidate.usernameFragment
+ };
+ };
+ } // update local description.
+
+
+ var sections = SDPUtils.getMediaSections(pc._localDescription.sdp);
+
+ if (!end) {
+ sections[event.candidate.sdpMLineIndex] += 'a=' + event.candidate.candidate + '\r\n';
+ } else {
+ sections[event.candidate.sdpMLineIndex] += 'a=end-of-candidates\r\n';
+ }
+
+ pc._localDescription.sdp = SDPUtils.getDescription(pc._localDescription.sdp) + sections.join('');
+ var complete = pc.transceivers.every(function (transceiver) {
+ return transceiver.iceGatherer && transceiver.iceGatherer.state === 'completed';
+ });
+
+ if (pc.iceGatheringState !== 'gathering') {
+ pc.iceGatheringState = 'gathering';
+
+ pc._emitGatheringStateChange();
+ } // Emit candidate. Also emit null candidate when all gatherers are
+ // complete.
+
+
+ if (!end) {
+ pc._dispatchEvent('icecandidate', event);
+ }
+
+ if (complete) {
+ pc._dispatchEvent('icecandidate', new Event('icecandidate'));
+
+ pc.iceGatheringState = 'complete';
+
+ pc._emitGatheringStateChange();
+ }
+ }; // emit already gathered candidates.
+
+
+ window.setTimeout(function () {
+ bufferedCandidateEvents.forEach(function (e) {
+ iceGatherer.onlocalcandidate(e);
+ });
+ }, 0);
+ }; // Create ICE transport and DTLS transport.
+
+
+ RTCPeerConnection.prototype._createIceAndDtlsTransports = function () {
+ var pc = this;
+ var iceTransport = new window.RTCIceTransport(null);
+
+ iceTransport.onicestatechange = function () {
+ pc._updateIceConnectionState();
+
+ pc._updateConnectionState();
+ };
+
+ var dtlsTransport = new window.RTCDtlsTransport(iceTransport);
+
+ dtlsTransport.ondtlsstatechange = function () {
+ pc._updateConnectionState();
+ };
+
+ dtlsTransport.onerror = function () {
+ // onerror does not set state to failed by itself.
+ Object.defineProperty(dtlsTransport, 'state', {
+ value: 'failed',
+ writable: true
+ });
+
+ pc._updateConnectionState();
+ };
+
+ return {
+ iceTransport: iceTransport,
+ dtlsTransport: dtlsTransport
+ };
+ }; // Destroy ICE gatherer, ICE transport and DTLS transport.
+ // Without triggering the callbacks.
+
+
+ RTCPeerConnection.prototype._disposeIceAndDtlsTransports = function (sdpMLineIndex) {
+ var iceGatherer = this.transceivers[sdpMLineIndex].iceGatherer;
+
+ if (iceGatherer) {
+ delete iceGatherer.onlocalcandidate;
+ delete this.transceivers[sdpMLineIndex].iceGatherer;
+ }
+
+ var iceTransport = this.transceivers[sdpMLineIndex].iceTransport;
+
+ if (iceTransport) {
+ delete iceTransport.onicestatechange;
+ delete this.transceivers[sdpMLineIndex].iceTransport;
+ }
+
+ var dtlsTransport = this.transceivers[sdpMLineIndex].dtlsTransport;
+
+ if (dtlsTransport) {
+ delete dtlsTransport.ondtlsstatechange;
+ delete dtlsTransport.onerror;
+ delete this.transceivers[sdpMLineIndex].dtlsTransport;
+ }
+ }; // Start the RTP Sender and Receiver for a transceiver.
+
+
+ RTCPeerConnection.prototype._transceive = function (transceiver, send, recv) {
+ var params = getCommonCapabilities(transceiver.localCapabilities, transceiver.remoteCapabilities);
+
+ if (send && transceiver.rtpSender) {
+ params.encodings = transceiver.sendEncodingParameters;
+ params.rtcp = {
+ cname: SDPUtils.localCName,
+ compound: transceiver.rtcpParameters.compound
+ };
+
+ if (transceiver.recvEncodingParameters.length) {
+ params.rtcp.ssrc = transceiver.recvEncodingParameters[0].ssrc;
+ }
+
+ transceiver.rtpSender.send(params);
+ }
+
+ if (recv && transceiver.rtpReceiver && params.codecs.length > 0) {
+ // remove RTX field in Edge 14942
+ if (transceiver.kind === 'video' && transceiver.recvEncodingParameters && edgeVersion < 15019) {
+ transceiver.recvEncodingParameters.forEach(function (p) {
+ delete p.rtx;
+ });
+ }
+
+ if (transceiver.recvEncodingParameters.length) {
+ params.encodings = transceiver.recvEncodingParameters;
+ } else {
+ params.encodings = [{}];
+ }
+
+ params.rtcp = {
+ compound: transceiver.rtcpParameters.compound
+ };
+
+ if (transceiver.rtcpParameters.cname) {
+ params.rtcp.cname = transceiver.rtcpParameters.cname;
+ }
+
+ if (transceiver.sendEncodingParameters.length) {
+ params.rtcp.ssrc = transceiver.sendEncodingParameters[0].ssrc;
+ }
+
+ transceiver.rtpReceiver.receive(params);
+ }
+ };
+
+ RTCPeerConnection.prototype.setLocalDescription = function (description) {
+ var pc = this; // Note: pranswer is not supported.
+
+ if (['offer', 'answer'].indexOf(description.type) === -1) {
+ return Promise.reject(makeError('TypeError', 'Unsupported type "' + description.type + '"'));
+ }
+
+ if (!isActionAllowedInSignalingState('setLocalDescription', description.type, pc.signalingState) || pc._isClosed) {
+ return Promise.reject(makeError('InvalidStateError', 'Can not set local ' + description.type + ' in state ' + pc.signalingState));
+ }
+
+ var sections;
+ var sessionpart;
+
+ if (description.type === 'offer') {
+ // VERY limited support for SDP munging. Limited to:
+ // * changing the order of codecs
+ sections = SDPUtils.splitSections(description.sdp);
+ sessionpart = sections.shift();
+ sections.forEach(function (mediaSection, sdpMLineIndex) {
+ var caps = SDPUtils.parseRtpParameters(mediaSection);
+ pc.transceivers[sdpMLineIndex].localCapabilities = caps;
+ });
+ pc.transceivers.forEach(function (transceiver, sdpMLineIndex) {
+ pc._gather(transceiver.mid, sdpMLineIndex);
+ });
+ } else if (description.type === 'answer') {
+ sections = SDPUtils.splitSections(pc._remoteDescription.sdp);
+ sessionpart = sections.shift();
+ var isIceLite = SDPUtils.matchPrefix(sessionpart, 'a=ice-lite').length > 0;
+ sections.forEach(function (mediaSection, sdpMLineIndex) {
+ var transceiver = pc.transceivers[sdpMLineIndex];
+ var iceGatherer = transceiver.iceGatherer;
+ var iceTransport = transceiver.iceTransport;
+ var dtlsTransport = transceiver.dtlsTransport;
+ var localCapabilities = transceiver.localCapabilities;
+ var remoteCapabilities = transceiver.remoteCapabilities; // treat bundle-only as not-rejected.
+
+ var rejected = SDPUtils.isRejected(mediaSection) && SDPUtils.matchPrefix(mediaSection, 'a=bundle-only').length === 0;
+
+ if (!rejected && !transceiver.rejected) {
+ var remoteIceParameters = SDPUtils.getIceParameters(mediaSection, sessionpart);
+ var remoteDtlsParameters = SDPUtils.getDtlsParameters(mediaSection, sessionpart);
+
+ if (isIceLite) {
+ remoteDtlsParameters.role = 'server';
+ }
+
+ if (!pc.usingBundle || sdpMLineIndex === 0) {
+ pc._gather(transceiver.mid, sdpMLineIndex);
+
+ if (iceTransport.state === 'new') {
+ iceTransport.start(iceGatherer, remoteIceParameters, isIceLite ? 'controlling' : 'controlled');
+ }
+
+ if (dtlsTransport.state === 'new') {
+ dtlsTransport.start(remoteDtlsParameters);
+ }
+ } // Calculate intersection of capabilities.
+
+
+ var params = getCommonCapabilities(localCapabilities, remoteCapabilities); // Start the RTCRtpSender. The RTCRtpReceiver for this
+ // transceiver has already been started in setRemoteDescription.
+
+ pc._transceive(transceiver, params.codecs.length > 0, false);
+ }
+ });
+ }
+
+ pc._localDescription = {
+ type: description.type,
+ sdp: description.sdp
+ };
+
+ if (description.type === 'offer') {
+ pc._updateSignalingState('have-local-offer');
+ } else {
+ pc._updateSignalingState('stable');
+ }
+
+ return Promise.resolve();
+ };
+
+ RTCPeerConnection.prototype.setRemoteDescription = function (description) {
+ var pc = this; // Note: pranswer is not supported.
+
+ if (['offer', 'answer'].indexOf(description.type) === -1) {
+ return Promise.reject(makeError('TypeError', 'Unsupported type "' + description.type + '"'));
+ }
+
+ if (!isActionAllowedInSignalingState('setRemoteDescription', description.type, pc.signalingState) || pc._isClosed) {
+ return Promise.reject(makeError('InvalidStateError', 'Can not set remote ' + description.type + ' in state ' + pc.signalingState));
+ }
+
+ var streams = {};
+ pc.remoteStreams.forEach(function (stream) {
+ streams[stream.id] = stream;
+ });
+ var receiverList = [];
+ var sections = SDPUtils.splitSections(description.sdp);
+ var sessionpart = sections.shift();
+ var isIceLite = SDPUtils.matchPrefix(sessionpart, 'a=ice-lite').length > 0;
+ var usingBundle = SDPUtils.matchPrefix(sessionpart, 'a=group:BUNDLE ').length > 0;
+ pc.usingBundle = usingBundle;
+ var iceOptions = SDPUtils.matchPrefix(sessionpart, 'a=ice-options:')[0];
+
+ if (iceOptions) {
+ pc.canTrickleIceCandidates = iceOptions.substr(14).split(' ').indexOf('trickle') >= 0;
+ } else {
+ pc.canTrickleIceCandidates = false;
+ }
+
+ sections.forEach(function (mediaSection, sdpMLineIndex) {
+ var lines = SDPUtils.splitLines(mediaSection);
+ var kind = SDPUtils.getKind(mediaSection); // treat bundle-only as not-rejected.
+
+ var rejected = SDPUtils.isRejected(mediaSection) && SDPUtils.matchPrefix(mediaSection, 'a=bundle-only').length === 0;
+ var protocol = lines[0].substr(2).split(' ')[2];
+ var direction = SDPUtils.getDirection(mediaSection, sessionpart);
+ var remoteMsid = SDPUtils.parseMsid(mediaSection);
+ var mid = SDPUtils.getMid(mediaSection) || SDPUtils.generateIdentifier(); // Reject datachannels which are not implemented yet.
+
+ if (rejected || kind === 'application' && (protocol === 'DTLS/SCTP' || protocol === 'UDP/DTLS/SCTP')) {
+ // TODO: this is dangerous in the case where a non-rejected m-line
+ // becomes rejected.
+ pc.transceivers[sdpMLineIndex] = {
+ mid: mid,
+ kind: kind,
+ protocol: protocol,
+ rejected: true
+ };
+ return;
+ }
+
+ if (!rejected && pc.transceivers[sdpMLineIndex] && pc.transceivers[sdpMLineIndex].rejected) {
+ // recycle a rejected transceiver.
+ pc.transceivers[sdpMLineIndex] = pc._createTransceiver(kind, true);
+ }
+
+ var transceiver;
+ var iceGatherer;
+ var iceTransport;
+ var dtlsTransport;
+ var rtpReceiver;
+ var sendEncodingParameters;
+ var recvEncodingParameters;
+ var localCapabilities;
+ var track; // FIXME: ensure the mediaSection has rtcp-mux set.
+
+ var remoteCapabilities = SDPUtils.parseRtpParameters(mediaSection);
+ var remoteIceParameters;
+ var remoteDtlsParameters;
+
+ if (!rejected) {
+ remoteIceParameters = SDPUtils.getIceParameters(mediaSection, sessionpart);
+ remoteDtlsParameters = SDPUtils.getDtlsParameters(mediaSection, sessionpart);
+ remoteDtlsParameters.role = 'client';
+ }
+
+ recvEncodingParameters = SDPUtils.parseRtpEncodingParameters(mediaSection);
+ var rtcpParameters = SDPUtils.parseRtcpParameters(mediaSection);
+ var isComplete = SDPUtils.matchPrefix(mediaSection, 'a=end-of-candidates', sessionpart).length > 0;
+ var cands = SDPUtils.matchPrefix(mediaSection, 'a=candidate:').map(function (cand) {
+ return SDPUtils.parseCandidate(cand);
+ }).filter(function (cand) {
+ return cand.component === 1;
+ }); // Check if we can use BUNDLE and dispose transports.
+
+ if ((description.type === 'offer' || description.type === 'answer') && !rejected && usingBundle && sdpMLineIndex > 0 && pc.transceivers[sdpMLineIndex]) {
+ pc._disposeIceAndDtlsTransports(sdpMLineIndex);
+
+ pc.transceivers[sdpMLineIndex].iceGatherer = pc.transceivers[0].iceGatherer;
+ pc.transceivers[sdpMLineIndex].iceTransport = pc.transceivers[0].iceTransport;
+ pc.transceivers[sdpMLineIndex].dtlsTransport = pc.transceivers[0].dtlsTransport;
+
+ if (pc.transceivers[sdpMLineIndex].rtpSender) {
+ pc.transceivers[sdpMLineIndex].rtpSender.setTransport(pc.transceivers[0].dtlsTransport);
+ }
+
+ if (pc.transceivers[sdpMLineIndex].rtpReceiver) {
+ pc.transceivers[sdpMLineIndex].rtpReceiver.setTransport(pc.transceivers[0].dtlsTransport);
+ }
+ }
+
+ if (description.type === 'offer' && !rejected) {
+ transceiver = pc.transceivers[sdpMLineIndex] || pc._createTransceiver(kind);
+ transceiver.mid = mid;
+
+ if (!transceiver.iceGatherer) {
+ transceiver.iceGatherer = pc._createIceGatherer(sdpMLineIndex, usingBundle);
+ }
+
+ if (cands.length && transceiver.iceTransport.state === 'new') {
+ if (isComplete && (!usingBundle || sdpMLineIndex === 0)) {
+ transceiver.iceTransport.setRemoteCandidates(cands);
+ } else {
+ cands.forEach(function (candidate) {
+ maybeAddCandidate(transceiver.iceTransport, candidate);
+ });
+ }
+ }
+
+ localCapabilities = window.RTCRtpReceiver.getCapabilities(kind); // filter RTX until additional stuff needed for RTX is implemented
+ // in adapter.js
+
+ if (edgeVersion < 15019) {
+ localCapabilities.codecs = localCapabilities.codecs.filter(function (codec) {
+ return codec.name !== 'rtx';
+ });
+ }
+
+ sendEncodingParameters = transceiver.sendEncodingParameters || [{
+ ssrc: (2 * sdpMLineIndex + 2) * 1001
+ }]; // TODO: rewrite to use http://w3c.github.io/webrtc-pc/#set-associated-remote-streams
+
+ var isNewTrack = false;
+
+ if (direction === 'sendrecv' || direction === 'sendonly') {
+ isNewTrack = !transceiver.rtpReceiver;
+ rtpReceiver = transceiver.rtpReceiver || new window.RTCRtpReceiver(transceiver.dtlsTransport, kind);
+
+ if (isNewTrack) {
+ var stream;
+ track = rtpReceiver.track; // FIXME: does not work with Plan B.
+
+ if (remoteMsid && remoteMsid.stream === '-') ; else if (remoteMsid) {
+ if (!streams[remoteMsid.stream]) {
+ streams[remoteMsid.stream] = new window.MediaStream();
+ Object.defineProperty(streams[remoteMsid.stream], 'id', {
+ get: function get() {
+ return remoteMsid.stream;
+ }
+ });
+ }
+
+ Object.defineProperty(track, 'id', {
+ get: function get() {
+ return remoteMsid.track;
+ }
+ });
+ stream = streams[remoteMsid.stream];
+ } else {
+ if (!streams["default"]) {
+ streams["default"] = new window.MediaStream();
+ }
+
+ stream = streams["default"];
+ }
+
+ if (stream) {
+ addTrackToStreamAndFireEvent(track, stream);
+ transceiver.associatedRemoteMediaStreams.push(stream);
+ }
+
+ receiverList.push([track, rtpReceiver, stream]);
+ }
+ } else if (transceiver.rtpReceiver && transceiver.rtpReceiver.track) {
+ transceiver.associatedRemoteMediaStreams.forEach(function (s) {
+ var nativeTrack = s.getTracks().find(function (t) {
+ return t.id === transceiver.rtpReceiver.track.id;
+ });
+
+ if (nativeTrack) {
+ removeTrackFromStreamAndFireEvent(nativeTrack, s);
+ }
+ });
+ transceiver.associatedRemoteMediaStreams = [];
+ }
+
+ transceiver.localCapabilities = localCapabilities;
+ transceiver.remoteCapabilities = remoteCapabilities;
+ transceiver.rtpReceiver = rtpReceiver;
+ transceiver.rtcpParameters = rtcpParameters;
+ transceiver.sendEncodingParameters = sendEncodingParameters;
+ transceiver.recvEncodingParameters = recvEncodingParameters; // Start the RTCRtpReceiver now. The RTPSender is started in
+ // setLocalDescription.
+
+ pc._transceive(pc.transceivers[sdpMLineIndex], false, isNewTrack);
+ } else if (description.type === 'answer' && !rejected) {
+ transceiver = pc.transceivers[sdpMLineIndex];
+ iceGatherer = transceiver.iceGatherer;
+ iceTransport = transceiver.iceTransport;
+ dtlsTransport = transceiver.dtlsTransport;
+ rtpReceiver = transceiver.rtpReceiver;
+ sendEncodingParameters = transceiver.sendEncodingParameters;
+ localCapabilities = transceiver.localCapabilities;
+ pc.transceivers[sdpMLineIndex].recvEncodingParameters = recvEncodingParameters;
+ pc.transceivers[sdpMLineIndex].remoteCapabilities = remoteCapabilities;
+ pc.transceivers[sdpMLineIndex].rtcpParameters = rtcpParameters;
+
+ if (cands.length && iceTransport.state === 'new') {
+ if ((isIceLite || isComplete) && (!usingBundle || sdpMLineIndex === 0)) {
+ iceTransport.setRemoteCandidates(cands);
+ } else {
+ cands.forEach(function (candidate) {
+ maybeAddCandidate(transceiver.iceTransport, candidate);
+ });
+ }
+ }
+
+ if (!usingBundle || sdpMLineIndex === 0) {
+ if (iceTransport.state === 'new') {
+ iceTransport.start(iceGatherer, remoteIceParameters, 'controlling');
+ }
+
+ if (dtlsTransport.state === 'new') {
+ dtlsTransport.start(remoteDtlsParameters);
+ }
+ } // If the offer contained RTX but the answer did not,
+ // remove RTX from sendEncodingParameters.
+
+
+ var commonCapabilities = getCommonCapabilities(transceiver.localCapabilities, transceiver.remoteCapabilities);
+ var hasRtx = commonCapabilities.codecs.filter(function (c) {
+ return c.name.toLowerCase() === 'rtx';
+ }).length;
+
+ if (!hasRtx && transceiver.sendEncodingParameters[0].rtx) {
+ delete transceiver.sendEncodingParameters[0].rtx;
+ }
+
+ pc._transceive(transceiver, direction === 'sendrecv' || direction === 'recvonly', direction === 'sendrecv' || direction === 'sendonly'); // TODO: rewrite to use http://w3c.github.io/webrtc-pc/#set-associated-remote-streams
+
+
+ if (rtpReceiver && (direction === 'sendrecv' || direction === 'sendonly')) {
+ track = rtpReceiver.track;
+
+ if (remoteMsid) {
+ if (!streams[remoteMsid.stream]) {
+ streams[remoteMsid.stream] = new window.MediaStream();
+ }
+
+ addTrackToStreamAndFireEvent(track, streams[remoteMsid.stream]);
+ receiverList.push([track, rtpReceiver, streams[remoteMsid.stream]]);
+ } else {
+ if (!streams["default"]) {
+ streams["default"] = new window.MediaStream();
+ }
+
+ addTrackToStreamAndFireEvent(track, streams["default"]);
+ receiverList.push([track, rtpReceiver, streams["default"]]);
+ }
+ } else {
+ // FIXME: actually the receiver should be created later.
+ delete transceiver.rtpReceiver;
+ }
+ }
+ });
+
+ if (pc._dtlsRole === undefined) {
+ pc._dtlsRole = description.type === 'offer' ? 'active' : 'passive';
+ }
+
+ pc._remoteDescription = {
+ type: description.type,
+ sdp: description.sdp
+ };
+
+ if (description.type === 'offer') {
+ pc._updateSignalingState('have-remote-offer');
+ } else {
+ pc._updateSignalingState('stable');
+ }
+
+ Object.keys(streams).forEach(function (sid) {
+ var stream = streams[sid];
+
+ if (stream.getTracks().length) {
+ if (pc.remoteStreams.indexOf(stream) === -1) {
+ pc.remoteStreams.push(stream);
+ var event = new Event('addstream');
+ event.stream = stream;
+ window.setTimeout(function () {
+ pc._dispatchEvent('addstream', event);
+ });
+ }
+
+ receiverList.forEach(function (item) {
+ var track = item[0];
+ var receiver = item[1];
+
+ if (stream.id !== item[2].id) {
+ return;
+ }
+
+ fireAddTrack(pc, track, receiver, [stream]);
+ });
+ }
+ });
+ receiverList.forEach(function (item) {
+ if (item[2]) {
+ return;
+ }
+
+ fireAddTrack(pc, item[0], item[1], []);
+ }); // check whether addIceCandidate({}) was called within four seconds after
+ // setRemoteDescription.
+
+ window.setTimeout(function () {
+ if (!(pc && pc.transceivers)) {
+ return;
+ }
+
+ pc.transceivers.forEach(function (transceiver) {
+ if (transceiver.iceTransport && transceiver.iceTransport.state === 'new' && transceiver.iceTransport.getRemoteCandidates().length > 0) {
+ console.warn('Timeout for addRemoteCandidate. Consider sending ' + 'an end-of-candidates notification');
+ transceiver.iceTransport.addRemoteCandidate({});
+ }
+ });
+ }, 4000);
+ return Promise.resolve();
+ };
+
+ RTCPeerConnection.prototype.close = function () {
+ this.transceivers.forEach(function (transceiver) {
+ /* not yet
+ if (transceiver.iceGatherer) {
+ transceiver.iceGatherer.close();
+ }
+ */
+ if (transceiver.iceTransport) {
+ transceiver.iceTransport.stop();
+ }
+
+ if (transceiver.dtlsTransport) {
+ transceiver.dtlsTransport.stop();
+ }
+
+ if (transceiver.rtpSender) {
+ transceiver.rtpSender.stop();
+ }
+
+ if (transceiver.rtpReceiver) {
+ transceiver.rtpReceiver.stop();
+ }
+ }); // FIXME: clean up tracks, local streams, remote streams, etc
+
+ this._isClosed = true;
+
+ this._updateSignalingState('closed');
+ }; // Update the signaling state.
+
+
+ RTCPeerConnection.prototype._updateSignalingState = function (newState) {
+ this.signalingState = newState;
+ var event = new Event('signalingstatechange');
+
+ this._dispatchEvent('signalingstatechange', event);
+ }; // Determine whether to fire the negotiationneeded event.
+
+
+ RTCPeerConnection.prototype._maybeFireNegotiationNeeded = function () {
+ var pc = this;
+
+ if (this.signalingState !== 'stable' || this.needNegotiation === true) {
+ return;
+ }
+
+ this.needNegotiation = true;
+ window.setTimeout(function () {
+ if (pc.needNegotiation) {
+ pc.needNegotiation = false;
+ var event = new Event('negotiationneeded');
+
+ pc._dispatchEvent('negotiationneeded', event);
+ }
+ }, 0);
+ }; // Update the ice connection state.
+
+
+ RTCPeerConnection.prototype._updateIceConnectionState = function () {
+ var newState;
+ var states = {
+ 'new': 0,
+ closed: 0,
+ checking: 0,
+ connected: 0,
+ completed: 0,
+ disconnected: 0,
+ failed: 0
+ };
+ this.transceivers.forEach(function (transceiver) {
+ if (transceiver.iceTransport && !transceiver.rejected) {
+ states[transceiver.iceTransport.state]++;
+ }
+ });
+ newState = 'new';
+
+ if (states.failed > 0) {
+ newState = 'failed';
+ } else if (states.checking > 0) {
+ newState = 'checking';
+ } else if (states.disconnected > 0) {
+ newState = 'disconnected';
+ } else if (states["new"] > 0) {
+ newState = 'new';
+ } else if (states.connected > 0) {
+ newState = 'connected';
+ } else if (states.completed > 0) {
+ newState = 'completed';
+ }
+
+ if (newState !== this.iceConnectionState) {
+ this.iceConnectionState = newState;
+ var event = new Event('iceconnectionstatechange');
+
+ this._dispatchEvent('iceconnectionstatechange', event);
+ }
+ }; // Update the connection state.
+
+
+ RTCPeerConnection.prototype._updateConnectionState = function () {
+ var newState;
+ var states = {
+ 'new': 0,
+ closed: 0,
+ connecting: 0,
+ connected: 0,
+ completed: 0,
+ disconnected: 0,
+ failed: 0
+ };
+ this.transceivers.forEach(function (transceiver) {
+ if (transceiver.iceTransport && transceiver.dtlsTransport && !transceiver.rejected) {
+ states[transceiver.iceTransport.state]++;
+ states[transceiver.dtlsTransport.state]++;
+ }
+ }); // ICETransport.completed and connected are the same for this purpose.
+
+ states.connected += states.completed;
+ newState = 'new';
+
+ if (states.failed > 0) {
+ newState = 'failed';
+ } else if (states.connecting > 0) {
+ newState = 'connecting';
+ } else if (states.disconnected > 0) {
+ newState = 'disconnected';
+ } else if (states["new"] > 0) {
+ newState = 'new';
+ } else if (states.connected > 0) {
+ newState = 'connected';
+ }
+
+ if (newState !== this.connectionState) {
+ this.connectionState = newState;
+ var event = new Event('connectionstatechange');
+
+ this._dispatchEvent('connectionstatechange', event);
+ }
+ };
+
+ RTCPeerConnection.prototype.createOffer = function () {
+ var pc = this;
+
+ if (pc._isClosed) {
+ return Promise.reject(makeError('InvalidStateError', 'Can not call createOffer after close'));
+ }
+
+ var numAudioTracks = pc.transceivers.filter(function (t) {
+ return t.kind === 'audio';
+ }).length;
+ var numVideoTracks = pc.transceivers.filter(function (t) {
+ return t.kind === 'video';
+ }).length; // Determine number of audio and video tracks we need to send/recv.
+
+ var offerOptions = arguments[0];
+
+ if (offerOptions) {
+ // Reject Chrome legacy constraints.
+ if (offerOptions.mandatory || offerOptions.optional) {
+ throw new TypeError('Legacy mandatory/optional constraints not supported.');
+ }
+
+ if (offerOptions.offerToReceiveAudio !== undefined) {
+ if (offerOptions.offerToReceiveAudio === true) {
+ numAudioTracks = 1;
+ } else if (offerOptions.offerToReceiveAudio === false) {
+ numAudioTracks = 0;
+ } else {
+ numAudioTracks = offerOptions.offerToReceiveAudio;
+ }
+ }
+
+ if (offerOptions.offerToReceiveVideo !== undefined) {
+ if (offerOptions.offerToReceiveVideo === true) {
+ numVideoTracks = 1;
+ } else if (offerOptions.offerToReceiveVideo === false) {
+ numVideoTracks = 0;
+ } else {
+ numVideoTracks = offerOptions.offerToReceiveVideo;
+ }
+ }
+ }
+
+ pc.transceivers.forEach(function (transceiver) {
+ if (transceiver.kind === 'audio') {
+ numAudioTracks--;
+
+ if (numAudioTracks < 0) {
+ transceiver.wantReceive = false;
+ }
+ } else if (transceiver.kind === 'video') {
+ numVideoTracks--;
+
+ if (numVideoTracks < 0) {
+ transceiver.wantReceive = false;
+ }
+ }
+ }); // Create M-lines for recvonly streams.
+
+ while (numAudioTracks > 0 || numVideoTracks > 0) {
+ if (numAudioTracks > 0) {
+ pc._createTransceiver('audio');
+
+ numAudioTracks--;
+ }
+
+ if (numVideoTracks > 0) {
+ pc._createTransceiver('video');
+
+ numVideoTracks--;
+ }
+ }
+
+ var sdp = SDPUtils.writeSessionBoilerplate(pc._sdpSessionId, pc._sdpSessionVersion++);
+ pc.transceivers.forEach(function (transceiver, sdpMLineIndex) {
+ // For each track, create an ice gatherer, ice transport,
+ // dtls transport, potentially rtpsender and rtpreceiver.
+ var track = transceiver.track;
+ var kind = transceiver.kind;
+ var mid = transceiver.mid || SDPUtils.generateIdentifier();
+ transceiver.mid = mid;
+
+ if (!transceiver.iceGatherer) {
+ transceiver.iceGatherer = pc._createIceGatherer(sdpMLineIndex, pc.usingBundle);
+ }
+
+ var localCapabilities = window.RTCRtpSender.getCapabilities(kind); // filter RTX until additional stuff needed for RTX is implemented
+ // in adapter.js
+
+ if (edgeVersion < 15019) {
+ localCapabilities.codecs = localCapabilities.codecs.filter(function (codec) {
+ return codec.name !== 'rtx';
+ });
+ }
+
+ localCapabilities.codecs.forEach(function (codec) {
+ // work around https://bugs.chromium.org/p/webrtc/issues/detail?id=6552
+ // by adding level-asymmetry-allowed=1
+ if (codec.name === 'H264' && codec.parameters['level-asymmetry-allowed'] === undefined) {
+ codec.parameters['level-asymmetry-allowed'] = '1';
+ } // for subsequent offers, we might have to re-use the payload
+ // type of the last offer.
+
+
+ if (transceiver.remoteCapabilities && transceiver.remoteCapabilities.codecs) {
+ transceiver.remoteCapabilities.codecs.forEach(function (remoteCodec) {
+ if (codec.name.toLowerCase() === remoteCodec.name.toLowerCase() && codec.clockRate === remoteCodec.clockRate) {
+ codec.preferredPayloadType = remoteCodec.payloadType;
+ }
+ });
+ }
+ });
+ localCapabilities.headerExtensions.forEach(function (hdrExt) {
+ var remoteExtensions = transceiver.remoteCapabilities && transceiver.remoteCapabilities.headerExtensions || [];
+ remoteExtensions.forEach(function (rHdrExt) {
+ if (hdrExt.uri === rHdrExt.uri) {
+ hdrExt.id = rHdrExt.id;
+ }
+ });
+ }); // generate an ssrc now, to be used later in rtpSender.send
+
+ var sendEncodingParameters = transceiver.sendEncodingParameters || [{
+ ssrc: (2 * sdpMLineIndex + 1) * 1001
+ }];
+
+ if (track) {
+ // add RTX
+ if (edgeVersion >= 15019 && kind === 'video' && !sendEncodingParameters[0].rtx) {
+ sendEncodingParameters[0].rtx = {
+ ssrc: sendEncodingParameters[0].ssrc + 1
+ };
+ }
+ }
+
+ if (transceiver.wantReceive) {
+ transceiver.rtpReceiver = new window.RTCRtpReceiver(transceiver.dtlsTransport, kind);
+ }
+
+ transceiver.localCapabilities = localCapabilities;
+ transceiver.sendEncodingParameters = sendEncodingParameters;
+ }); // always offer BUNDLE and dispose on return if not supported.
+
+ if (pc._config.bundlePolicy !== 'max-compat') {
+ sdp += 'a=group:BUNDLE ' + pc.transceivers.map(function (t) {
+ return t.mid;
+ }).join(' ') + '\r\n';
+ }
+
+ sdp += 'a=ice-options:trickle\r\n';
+ pc.transceivers.forEach(function (transceiver, sdpMLineIndex) {
+ sdp += writeMediaSection(transceiver, transceiver.localCapabilities, 'offer', transceiver.stream, pc._dtlsRole);
+ sdp += 'a=rtcp-rsize\r\n';
+
+ if (transceiver.iceGatherer && pc.iceGatheringState !== 'new' && (sdpMLineIndex === 0 || !pc.usingBundle)) {
+ transceiver.iceGatherer.getLocalCandidates().forEach(function (cand) {
+ cand.component = 1;
+ sdp += 'a=' + SDPUtils.writeCandidate(cand) + '\r\n';
+ });
+
+ if (transceiver.iceGatherer.state === 'completed') {
+ sdp += 'a=end-of-candidates\r\n';
+ }
+ }
+ });
+ var desc = new window.RTCSessionDescription({
+ type: 'offer',
+ sdp: sdp
+ });
+ return Promise.resolve(desc);
+ };
+
+ RTCPeerConnection.prototype.createAnswer = function () {
+ var pc = this;
+
+ if (pc._isClosed) {
+ return Promise.reject(makeError('InvalidStateError', 'Can not call createAnswer after close'));
+ }
+
+ if (!(pc.signalingState === 'have-remote-offer' || pc.signalingState === 'have-local-pranswer')) {
+ return Promise.reject(makeError('InvalidStateError', 'Can not call createAnswer in signalingState ' + pc.signalingState));
+ }
+
+ var sdp = SDPUtils.writeSessionBoilerplate(pc._sdpSessionId, pc._sdpSessionVersion++);
+
+ if (pc.usingBundle) {
+ sdp += 'a=group:BUNDLE ' + pc.transceivers.map(function (t) {
+ return t.mid;
+ }).join(' ') + '\r\n';
+ }
+
+ sdp += 'a=ice-options:trickle\r\n';
+ var mediaSectionsInOffer = SDPUtils.getMediaSections(pc._remoteDescription.sdp).length;
+ pc.transceivers.forEach(function (transceiver, sdpMLineIndex) {
+ if (sdpMLineIndex + 1 > mediaSectionsInOffer) {
+ return;
+ }
+
+ if (transceiver.rejected) {
+ if (transceiver.kind === 'application') {
+ if (transceiver.protocol === 'DTLS/SCTP') {
+ // legacy fmt
+ sdp += 'm=application 0 DTLS/SCTP 5000\r\n';
+ } else {
+ sdp += 'm=application 0 ' + transceiver.protocol + ' webrtc-datachannel\r\n';
+ }
+ } else if (transceiver.kind === 'audio') {
+ sdp += 'm=audio 0 UDP/TLS/RTP/SAVPF 0\r\n' + 'a=rtpmap:0 PCMU/8000\r\n';
+ } else if (transceiver.kind === 'video') {
+ sdp += 'm=video 0 UDP/TLS/RTP/SAVPF 120\r\n' + 'a=rtpmap:120 VP8/90000\r\n';
+ }
+
+ sdp += 'c=IN IP4 0.0.0.0\r\n' + 'a=inactive\r\n' + 'a=mid:' + transceiver.mid + '\r\n';
+ return;
+ } // FIXME: look at direction.
+
+
+ if (transceiver.stream) {
+ var localTrack;
+
+ if (transceiver.kind === 'audio') {
+ localTrack = transceiver.stream.getAudioTracks()[0];
+ } else if (transceiver.kind === 'video') {
+ localTrack = transceiver.stream.getVideoTracks()[0];
+ }
+
+ if (localTrack) {
+ // add RTX
+ if (edgeVersion >= 15019 && transceiver.kind === 'video' && !transceiver.sendEncodingParameters[0].rtx) {
+ transceiver.sendEncodingParameters[0].rtx = {
+ ssrc: transceiver.sendEncodingParameters[0].ssrc + 1
+ };
+ }
+ }
+ } // Calculate intersection of capabilities.
+
+
+ var commonCapabilities = getCommonCapabilities(transceiver.localCapabilities, transceiver.remoteCapabilities);
+ var hasRtx = commonCapabilities.codecs.filter(function (c) {
+ return c.name.toLowerCase() === 'rtx';
+ }).length;
+
+ if (!hasRtx && transceiver.sendEncodingParameters[0].rtx) {
+ delete transceiver.sendEncodingParameters[0].rtx;
+ }
+
+ sdp += writeMediaSection(transceiver, commonCapabilities, 'answer', transceiver.stream, pc._dtlsRole);
+
+ if (transceiver.rtcpParameters && transceiver.rtcpParameters.reducedSize) {
+ sdp += 'a=rtcp-rsize\r\n';
+ }
+ });
+ var desc = new window.RTCSessionDescription({
+ type: 'answer',
+ sdp: sdp
+ });
+ return Promise.resolve(desc);
+ };
+
+ RTCPeerConnection.prototype.addIceCandidate = function (candidate) {
+ var pc = this;
+ var sections;
+
+ if (candidate && !(candidate.sdpMLineIndex !== undefined || candidate.sdpMid)) {
+ return Promise.reject(new TypeError('sdpMLineIndex or sdpMid required'));
+ } // TODO: needs to go into ops queue.
+
+
+ return new Promise(function (resolve, reject) {
+ if (!pc._remoteDescription) {
+ return reject(makeError('InvalidStateError', 'Can not add ICE candidate without a remote description'));
+ } else if (!candidate || candidate.candidate === '') {
+ for (var j = 0; j < pc.transceivers.length; j++) {
+ if (pc.transceivers[j].rejected) {
+ continue;
+ }
+
+ pc.transceivers[j].iceTransport.addRemoteCandidate({});
+ sections = SDPUtils.getMediaSections(pc._remoteDescription.sdp);
+ sections[j] += 'a=end-of-candidates\r\n';
+ pc._remoteDescription.sdp = SDPUtils.getDescription(pc._remoteDescription.sdp) + sections.join('');
+
+ if (pc.usingBundle) {
+ break;
+ }
+ }
+ } else {
+ var sdpMLineIndex = candidate.sdpMLineIndex;
+
+ if (candidate.sdpMid) {
+ for (var i = 0; i < pc.transceivers.length; i++) {
+ if (pc.transceivers[i].mid === candidate.sdpMid) {
+ sdpMLineIndex = i;
+ break;
+ }
+ }
+ }
+
+ var transceiver = pc.transceivers[sdpMLineIndex];
+
+ if (transceiver) {
+ if (transceiver.rejected) {
+ return resolve();
+ }
+
+ var cand = Object.keys(candidate.candidate).length > 0 ? SDPUtils.parseCandidate(candidate.candidate) : {}; // Ignore Chrome's invalid candidates since Edge does not like them.
+
+ if (cand.protocol === 'tcp' && (cand.port === 0 || cand.port === 9)) {
+ return resolve();
+ } // Ignore RTCP candidates, we assume RTCP-MUX.
+
+
+ if (cand.component && cand.component !== 1) {
+ return resolve();
+ } // when using bundle, avoid adding candidates to the wrong
+ // ice transport. And avoid adding candidates added in the SDP.
+
+
+ if (sdpMLineIndex === 0 || sdpMLineIndex > 0 && transceiver.iceTransport !== pc.transceivers[0].iceTransport) {
+ if (!maybeAddCandidate(transceiver.iceTransport, cand)) {
+ return reject(makeError('OperationError', 'Can not add ICE candidate'));
+ }
+ } // update the remoteDescription.
+
+
+ var candidateString = candidate.candidate.trim();
+
+ if (candidateString.indexOf('a=') === 0) {
+ candidateString = candidateString.substr(2);
+ }
+
+ sections = SDPUtils.getMediaSections(pc._remoteDescription.sdp);
+ sections[sdpMLineIndex] += 'a=' + (cand.type ? candidateString : 'end-of-candidates') + '\r\n';
+ pc._remoteDescription.sdp = SDPUtils.getDescription(pc._remoteDescription.sdp) + sections.join('');
+ } else {
+ return reject(makeError('OperationError', 'Can not add ICE candidate'));
+ }
+ }
+
+ resolve();
+ });
+ };
+
+ RTCPeerConnection.prototype.getStats = function (selector) {
+ if (selector && selector instanceof window.MediaStreamTrack) {
+ var senderOrReceiver = null;
+ this.transceivers.forEach(function (transceiver) {
+ if (transceiver.rtpSender && transceiver.rtpSender.track === selector) {
+ senderOrReceiver = transceiver.rtpSender;
+ } else if (transceiver.rtpReceiver && transceiver.rtpReceiver.track === selector) {
+ senderOrReceiver = transceiver.rtpReceiver;
+ }
+ });
+
+ if (!senderOrReceiver) {
+ throw makeError('InvalidAccessError', 'Invalid selector.');
+ }
+
+ return senderOrReceiver.getStats();
+ }
+
+ var promises = [];
+ this.transceivers.forEach(function (transceiver) {
+ ['rtpSender', 'rtpReceiver', 'iceGatherer', 'iceTransport', 'dtlsTransport'].forEach(function (method) {
+ if (transceiver[method]) {
+ promises.push(transceiver[method].getStats());
+ }
+ });
+ });
+ return Promise.all(promises).then(function (allStats) {
+ var results = new Map();
+ allStats.forEach(function (stats) {
+ stats.forEach(function (stat) {
+ results.set(stat.id, stat);
+ });
+ });
+ return results;
+ });
+ }; // fix low-level stat names and return Map instead of object.
+
+
+ var ortcObjects = ['RTCRtpSender', 'RTCRtpReceiver', 'RTCIceGatherer', 'RTCIceTransport', 'RTCDtlsTransport'];
+ ortcObjects.forEach(function (ortcObjectName) {
+ var obj = window[ortcObjectName];
+
+ if (obj && obj.prototype && obj.prototype.getStats) {
+ var nativeGetstats = obj.prototype.getStats;
+
+ obj.prototype.getStats = function () {
+ return nativeGetstats.apply(this).then(function (nativeStats) {
+ var mapStats = new Map();
+ Object.keys(nativeStats).forEach(function (id) {
+ nativeStats[id].type = fixStatsType(nativeStats[id]);
+ mapStats.set(id, nativeStats[id]);
+ });
+ return mapStats;
+ });
+ };
+ }
+ }); // legacy callback shims. Should be moved to adapter.js some days.
+
+ var methods = ['createOffer', 'createAnswer'];
+ methods.forEach(function (method) {
+ var nativeMethod = RTCPeerConnection.prototype[method];
+
+ RTCPeerConnection.prototype[method] = function () {
+ var args = arguments;
+
+ if (typeof args[0] === 'function' || typeof args[1] === 'function') {
+ // legacy
+ return nativeMethod.apply(this, [arguments[2]]).then(function (description) {
+ if (typeof args[0] === 'function') {
+ args[0].apply(null, [description]);
+ }
+ }, function (error) {
+ if (typeof args[1] === 'function') {
+ args[1].apply(null, [error]);
+ }
+ });
+ }
+
+ return nativeMethod.apply(this, arguments);
+ };
+ });
+ methods = ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate'];
+ methods.forEach(function (method) {
+ var nativeMethod = RTCPeerConnection.prototype[method];
+
+ RTCPeerConnection.prototype[method] = function () {
+ var args = arguments;
+
+ if (typeof args[1] === 'function' || typeof args[2] === 'function') {
+ // legacy
+ return nativeMethod.apply(this, arguments).then(function () {
+ if (typeof args[1] === 'function') {
+ args[1].apply(null);
+ }
+ }, function (error) {
+ if (typeof args[2] === 'function') {
+ args[2].apply(null, [error]);
+ }
+ });
+ }
+
+ return nativeMethod.apply(this, arguments);
+ };
+ }); // getStats is special. It doesn't have a spec legacy method yet we support
+ // getStats(something, cb) without error callbacks.
+
+ ['getStats'].forEach(function (method) {
+ var nativeMethod = RTCPeerConnection.prototype[method];
+
+ RTCPeerConnection.prototype[method] = function () {
+ var args = arguments;
+
+ if (typeof args[1] === 'function') {
+ return nativeMethod.apply(this, arguments).then(function () {
+ if (typeof args[1] === 'function') {
+ args[1].apply(null);
+ }
+ });
+ }
+
+ return nativeMethod.apply(this, arguments);
+ };
+ });
+ return RTCPeerConnection;
+ };
+ }, {
+ "sdp": 17
+ }],
+ 17: [function (require, module, exports) {
+
+ var SDPUtils = {}; // Generate an alphanumeric identifier for cname or mids.
+ // TODO: use UUIDs instead? https://gist.github.com/jed/982883
+
+ SDPUtils.generateIdentifier = function () {
+ return Math.random().toString(36).substr(2, 10);
+ }; // The RTCP CNAME used by all peerconnections from the same JS.
+
+
+ SDPUtils.localCName = SDPUtils.generateIdentifier(); // Splits SDP into lines, dealing with both CRLF and LF.
+
+ SDPUtils.splitLines = function (blob) {
+ return blob.trim().split('\n').map(function (line) {
+ return line.trim();
+ });
+ }; // Splits SDP into sessionpart and mediasections. Ensures CRLF.
+
+
+ SDPUtils.splitSections = function (blob) {
+ var parts = blob.split('\nm=');
+ return parts.map(function (part, index) {
+ return (index > 0 ? 'm=' + part : part).trim() + '\r\n';
+ });
+ }; // returns the session description.
+
+
+ SDPUtils.getDescription = function (blob) {
+ var sections = SDPUtils.splitSections(blob);
+ return sections && sections[0];
+ }; // returns the individual media sections.
+
+
+ SDPUtils.getMediaSections = function (blob) {
+ var sections = SDPUtils.splitSections(blob);
+ sections.shift();
+ return sections;
+ }; // Returns lines that start with a certain prefix.
+
+
+ SDPUtils.matchPrefix = function (blob, prefix) {
+ return SDPUtils.splitLines(blob).filter(function (line) {
+ return line.indexOf(prefix) === 0;
+ });
+ }; // Parses an ICE candidate line. Sample input:
+ // candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8
+ // rport 55996"
+
+
+ SDPUtils.parseCandidate = function (line) {
+ var parts; // Parse both variants.
+
+ if (line.indexOf('a=candidate:') === 0) {
+ parts = line.substring(12).split(' ');
+ } else {
+ parts = line.substring(10).split(' ');
+ }
+
+ var candidate = {
+ foundation: parts[0],
+ component: parseInt(parts[1], 10),
+ protocol: parts[2].toLowerCase(),
+ priority: parseInt(parts[3], 10),
+ ip: parts[4],
+ address: parts[4],
+ // address is an alias for ip.
+ port: parseInt(parts[5], 10),
+ // skip parts[6] == 'typ'
+ type: parts[7]
+ };
+
+ for (var i = 8; i < parts.length; i += 2) {
+ switch (parts[i]) {
+ case 'raddr':
+ candidate.relatedAddress = parts[i + 1];
+ break;
+
+ case 'rport':
+ candidate.relatedPort = parseInt(parts[i + 1], 10);
+ break;
+
+ case 'tcptype':
+ candidate.tcpType = parts[i + 1];
+ break;
+
+ case 'ufrag':
+ candidate.ufrag = parts[i + 1]; // for backward compability.
+
+ candidate.usernameFragment = parts[i + 1];
+ break;
+
+ default:
+ // extension handling, in particular ufrag
+ candidate[parts[i]] = parts[i + 1];
+ break;
+ }
+ }
+
+ return candidate;
+ }; // Translates a candidate object into SDP candidate attribute.
+
+
+ SDPUtils.writeCandidate = function (candidate) {
+ var sdp = [];
+ sdp.push(candidate.foundation);
+ sdp.push(candidate.component);
+ sdp.push(candidate.protocol.toUpperCase());
+ sdp.push(candidate.priority);
+ sdp.push(candidate.address || candidate.ip);
+ sdp.push(candidate.port);
+ var type = candidate.type;
+ sdp.push('typ');
+ sdp.push(type);
+
+ if (type !== 'host' && candidate.relatedAddress && candidate.relatedPort) {
+ sdp.push('raddr');
+ sdp.push(candidate.relatedAddress);
+ sdp.push('rport');
+ sdp.push(candidate.relatedPort);
+ }
+
+ if (candidate.tcpType && candidate.protocol.toLowerCase() === 'tcp') {
+ sdp.push('tcptype');
+ sdp.push(candidate.tcpType);
+ }
+
+ if (candidate.usernameFragment || candidate.ufrag) {
+ sdp.push('ufrag');
+ sdp.push(candidate.usernameFragment || candidate.ufrag);
+ }
+
+ return 'candidate:' + sdp.join(' ');
+ }; // Parses an ice-options line, returns an array of option tags.
+ // a=ice-options:foo bar
+
+
+ SDPUtils.parseIceOptions = function (line) {
+ return line.substr(14).split(' ');
+ }; // Parses an rtpmap line, returns RTCRtpCoddecParameters. Sample input:
+ // a=rtpmap:111 opus/48000/2
+
+
+ SDPUtils.parseRtpMap = function (line) {
+ var parts = line.substr(9).split(' ');
+ var parsed = {
+ payloadType: parseInt(parts.shift(), 10) // was: id
+
+ };
+ parts = parts[0].split('/');
+ parsed.name = parts[0];
+ parsed.clockRate = parseInt(parts[1], 10); // was: clockrate
+
+ parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1; // legacy alias, got renamed back to channels in ORTC.
+
+ parsed.numChannels = parsed.channels;
+ return parsed;
+ }; // Generate an a=rtpmap line from RTCRtpCodecCapability or
+ // RTCRtpCodecParameters.
+
+
+ SDPUtils.writeRtpMap = function (codec) {
+ var pt = codec.payloadType;
+
+ if (codec.preferredPayloadType !== undefined) {
+ pt = codec.preferredPayloadType;
+ }
+
+ var channels = codec.channels || codec.numChannels || 1;
+ return 'a=rtpmap:' + pt + ' ' + codec.name + '/' + codec.clockRate + (channels !== 1 ? '/' + channels : '') + '\r\n';
+ }; // Parses an a=extmap line (headerextension from RFC 5285). Sample input:
+ // a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
+ // a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset
+
+
+ SDPUtils.parseExtmap = function (line) {
+ var parts = line.substr(9).split(' ');
+ return {
+ id: parseInt(parts[0], 10),
+ direction: parts[0].indexOf('/') > 0 ? parts[0].split('/')[1] : 'sendrecv',
+ uri: parts[1]
+ };
+ }; // Generates a=extmap line from RTCRtpHeaderExtensionParameters or
+ // RTCRtpHeaderExtension.
+
+
+ SDPUtils.writeExtmap = function (headerExtension) {
+ return 'a=extmap:' + (headerExtension.id || headerExtension.preferredId) + (headerExtension.direction && headerExtension.direction !== 'sendrecv' ? '/' + headerExtension.direction : '') + ' ' + headerExtension.uri + '\r\n';
+ }; // Parses an ftmp line, returns dictionary. Sample input:
+ // a=fmtp:96 vbr=on;cng=on
+ // Also deals with vbr=on; cng=on
+
+
+ SDPUtils.parseFmtp = function (line) {
+ var parsed = {};
+ var kv;
+ var parts = line.substr(line.indexOf(' ') + 1).split(';');
+
+ for (var j = 0; j < parts.length; j++) {
+ kv = parts[j].trim().split('=');
+ parsed[kv[0].trim()] = kv[1];
+ }
+
+ return parsed;
+ }; // Generates an a=ftmp line from RTCRtpCodecCapability or RTCRtpCodecParameters.
+
+
+ SDPUtils.writeFmtp = function (codec) {
+ var line = '';
+ var pt = codec.payloadType;
+
+ if (codec.preferredPayloadType !== undefined) {
+ pt = codec.preferredPayloadType;
+ }
+
+ if (codec.parameters && Object.keys(codec.parameters).length) {
+ var params = [];
+ Object.keys(codec.parameters).forEach(function (param) {
+ if (codec.parameters[param]) {
+ params.push(param + '=' + codec.parameters[param]);
+ } else {
+ params.push(param);
+ }
+ });
+ line += 'a=fmtp:' + pt + ' ' + params.join(';') + '\r\n';
+ }
+
+ return line;
+ }; // Parses an rtcp-fb line, returns RTCPRtcpFeedback object. Sample input:
+ // a=rtcp-fb:98 nack rpsi
+
+
+ SDPUtils.parseRtcpFb = function (line) {
+ var parts = line.substr(line.indexOf(' ') + 1).split(' ');
+ return {
+ type: parts.shift(),
+ parameter: parts.join(' ')
+ };
+ }; // Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters.
+
+
+ SDPUtils.writeRtcpFb = function (codec) {
+ var lines = '';
+ var pt = codec.payloadType;
+
+ if (codec.preferredPayloadType !== undefined) {
+ pt = codec.preferredPayloadType;
+ }
+
+ if (codec.rtcpFeedback && codec.rtcpFeedback.length) {
+ // FIXME: special handling for trr-int?
+ codec.rtcpFeedback.forEach(function (fb) {
+ lines += 'a=rtcp-fb:' + pt + ' ' + fb.type + (fb.parameter && fb.parameter.length ? ' ' + fb.parameter : '') + '\r\n';
+ });
+ }
+
+ return lines;
+ }; // Parses an RFC 5576 ssrc media attribute. Sample input:
+ // a=ssrc:3735928559 cname:something
+
+
+ SDPUtils.parseSsrcMedia = function (line) {
+ var sp = line.indexOf(' ');
+ var parts = {
+ ssrc: parseInt(line.substr(7, sp - 7), 10)
+ };
+ var colon = line.indexOf(':', sp);
+
+ if (colon > -1) {
+ parts.attribute = line.substr(sp + 1, colon - sp - 1);
+ parts.value = line.substr(colon + 1);
+ } else {
+ parts.attribute = line.substr(sp + 1);
+ }
+
+ return parts;
+ };
+
+ SDPUtils.parseSsrcGroup = function (line) {
+ var parts = line.substr(13).split(' ');
+ return {
+ semantics: parts.shift(),
+ ssrcs: parts.map(function (ssrc) {
+ return parseInt(ssrc, 10);
+ })
+ };
+ }; // Extracts the MID (RFC 5888) from a media section.
+ // returns the MID or undefined if no mid line was found.
+
+
+ SDPUtils.getMid = function (mediaSection) {
+ var mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:')[0];
+
+ if (mid) {
+ return mid.substr(6);
+ }
+ };
+
+ SDPUtils.parseFingerprint = function (line) {
+ var parts = line.substr(14).split(' ');
+ return {
+ algorithm: parts[0].toLowerCase(),
+ // algorithm is case-sensitive in Edge.
+ value: parts[1]
+ };
+ }; // Extracts DTLS parameters from SDP media section or sessionpart.
+ // FIXME: for consistency with other functions this should only
+ // get the fingerprint line as input. See also getIceParameters.
+
+
+ SDPUtils.getDtlsParameters = function (mediaSection, sessionpart) {
+ var lines = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=fingerprint:'); // Note: a=setup line is ignored since we use the 'auto' role.
+ // Note2: 'algorithm' is not case sensitive except in Edge.
+
+ return {
+ role: 'auto',
+ fingerprints: lines.map(SDPUtils.parseFingerprint)
+ };
+ }; // Serializes DTLS parameters to SDP.
+
+
+ SDPUtils.writeDtlsParameters = function (params, setupType) {
+ var sdp = 'a=setup:' + setupType + '\r\n';
+ params.fingerprints.forEach(function (fp) {
+ sdp += 'a=fingerprint:' + fp.algorithm + ' ' + fp.value + '\r\n';
+ });
+ return sdp;
+ }; // Parses ICE information from SDP media section or sessionpart.
+ // FIXME: for consistency with other functions this should only
+ // get the ice-ufrag and ice-pwd lines as input.
+
+
+ SDPUtils.getIceParameters = function (mediaSection, sessionpart) {
+ var lines = SDPUtils.splitLines(mediaSection); // Search in session part, too.
+
+ lines = lines.concat(SDPUtils.splitLines(sessionpart));
+ var iceParameters = {
+ usernameFragment: lines.filter(function (line) {
+ return line.indexOf('a=ice-ufrag:') === 0;
+ })[0].substr(12),
+ password: lines.filter(function (line) {
+ return line.indexOf('a=ice-pwd:') === 0;
+ })[0].substr(10)
+ };
+ return iceParameters;
+ }; // Serializes ICE parameters to SDP.
+
+
+ SDPUtils.writeIceParameters = function (params) {
+ return 'a=ice-ufrag:' + params.usernameFragment + '\r\n' + 'a=ice-pwd:' + params.password + '\r\n';
+ }; // Parses the SDP media section and returns RTCRtpParameters.
+
+
+ SDPUtils.parseRtpParameters = function (mediaSection) {
+ var description = {
+ codecs: [],
+ headerExtensions: [],
+ fecMechanisms: [],
+ rtcp: []
+ };
+ var lines = SDPUtils.splitLines(mediaSection);
+ var mline = lines[0].split(' ');
+
+ for (var i = 3; i < mline.length; i++) {
+ // find all codecs from mline[3..]
+ var pt = mline[i];
+ var rtpmapline = SDPUtils.matchPrefix(mediaSection, 'a=rtpmap:' + pt + ' ')[0];
+
+ if (rtpmapline) {
+ var codec = SDPUtils.parseRtpMap(rtpmapline);
+ var fmtps = SDPUtils.matchPrefix(mediaSection, 'a=fmtp:' + pt + ' '); // Only the first a=fmtp:<pt> is considered.
+
+ codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {};
+ codec.rtcpFeedback = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:' + pt + ' ').map(SDPUtils.parseRtcpFb);
+ description.codecs.push(codec); // parse FEC mechanisms from rtpmap lines.
+
+ switch (codec.name.toUpperCase()) {
+ case 'RED':
+ case 'ULPFEC':
+ description.fecMechanisms.push(codec.name.toUpperCase());
+ break;
+ }
+ }
+ }
+
+ SDPUtils.matchPrefix(mediaSection, 'a=extmap:').forEach(function (line) {
+ description.headerExtensions.push(SDPUtils.parseExtmap(line));
+ }); // FIXME: parse rtcp.
+
+ return description;
+ }; // Generates parts of the SDP media section describing the capabilities /
+ // parameters.
+
+
+ SDPUtils.writeRtpDescription = function (kind, caps) {
+ var sdp = ''; // Build the mline.
+
+ sdp += 'm=' + kind + ' ';
+ sdp += caps.codecs.length > 0 ? '9' : '0'; // reject if no codecs.
+
+ sdp += ' UDP/TLS/RTP/SAVPF ';
+ sdp += caps.codecs.map(function (codec) {
+ if (codec.preferredPayloadType !== undefined) {
+ return codec.preferredPayloadType;
+ }
+
+ return codec.payloadType;
+ }).join(' ') + '\r\n';
+ sdp += 'c=IN IP4 0.0.0.0\r\n';
+ sdp += 'a=rtcp:9 IN IP4 0.0.0.0\r\n'; // Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb.
+
+ caps.codecs.forEach(function (codec) {
+ sdp += SDPUtils.writeRtpMap(codec);
+ sdp += SDPUtils.writeFmtp(codec);
+ sdp += SDPUtils.writeRtcpFb(codec);
+ });
+ var maxptime = 0;
+ caps.codecs.forEach(function (codec) {
+ if (codec.maxptime > maxptime) {
+ maxptime = codec.maxptime;
+ }
+ });
+
+ if (maxptime > 0) {
+ sdp += 'a=maxptime:' + maxptime + '\r\n';
+ }
+
+ sdp += 'a=rtcp-mux\r\n';
+
+ if (caps.headerExtensions) {
+ caps.headerExtensions.forEach(function (extension) {
+ sdp += SDPUtils.writeExtmap(extension);
+ });
+ } // FIXME: write fecMechanisms.
+
+
+ return sdp;
+ }; // Parses the SDP media section and returns an array of
+ // RTCRtpEncodingParameters.
+
+
+ SDPUtils.parseRtpEncodingParameters = function (mediaSection) {
+ var encodingParameters = [];
+ var description = SDPUtils.parseRtpParameters(mediaSection);
+ var hasRed = description.fecMechanisms.indexOf('RED') !== -1;
+ var hasUlpfec = description.fecMechanisms.indexOf('ULPFEC') !== -1; // filter a=ssrc:... cname:, ignore PlanB-msid
+
+ var ssrcs = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(function (line) {
+ return SDPUtils.parseSsrcMedia(line);
+ }).filter(function (parts) {
+ return parts.attribute === 'cname';
+ });
+ var primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc;
+ var secondarySsrc;
+ var flows = SDPUtils.matchPrefix(mediaSection, 'a=ssrc-group:FID').map(function (line) {
+ var parts = line.substr(17).split(' ');
+ return parts.map(function (part) {
+ return parseInt(part, 10);
+ });
+ });
+
+ if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) {
+ secondarySsrc = flows[0][1];
+ }
+
+ description.codecs.forEach(function (codec) {
+ if (codec.name.toUpperCase() === 'RTX' && codec.parameters.apt) {
+ var encParam = {
+ ssrc: primarySsrc,
+ codecPayloadType: parseInt(codec.parameters.apt, 10)
+ };
+
+ if (primarySsrc && secondarySsrc) {
+ encParam.rtx = {
+ ssrc: secondarySsrc
+ };
+ }
+
+ encodingParameters.push(encParam);
+
+ if (hasRed) {
+ encParam = JSON.parse(JSON.stringify(encParam));
+ encParam.fec = {
+ ssrc: primarySsrc,
+ mechanism: hasUlpfec ? 'red+ulpfec' : 'red'
+ };
+ encodingParameters.push(encParam);
+ }
+ }
+ });
+
+ if (encodingParameters.length === 0 && primarySsrc) {
+ encodingParameters.push({
+ ssrc: primarySsrc
+ });
+ } // we support both b=AS and b=TIAS but interpret AS as TIAS.
+
+
+ var bandwidth = SDPUtils.matchPrefix(mediaSection, 'b=');
+
+ if (bandwidth.length) {
+ if (bandwidth[0].indexOf('b=TIAS:') === 0) {
+ bandwidth = parseInt(bandwidth[0].substr(7), 10);
+ } else if (bandwidth[0].indexOf('b=AS:') === 0) {
+ // use formula from JSEP to convert b=AS to TIAS value.
+ bandwidth = parseInt(bandwidth[0].substr(5), 10) * 1000 * 0.95 - 50 * 40 * 8;
+ } else {
+ bandwidth = undefined;
+ }
+
+ encodingParameters.forEach(function (params) {
+ params.maxBitrate = bandwidth;
+ });
+ }
+
+ return encodingParameters;
+ }; // parses http://draft.ortc.org/#rtcrtcpparameters*
+
+
+ SDPUtils.parseRtcpParameters = function (mediaSection) {
+ var rtcpParameters = {}; // Gets the first SSRC. Note tha with RTX there might be multiple
+ // SSRCs.
+
+ var remoteSsrc = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(function (line) {
+ return SDPUtils.parseSsrcMedia(line);
+ }).filter(function (obj) {
+ return obj.attribute === 'cname';
+ })[0];
+
+ if (remoteSsrc) {
+ rtcpParameters.cname = remoteSsrc.value;
+ rtcpParameters.ssrc = remoteSsrc.ssrc;
+ } // Edge uses the compound attribute instead of reducedSize
+ // compound is !reducedSize
+
+
+ var rsize = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-rsize');
+ rtcpParameters.reducedSize = rsize.length > 0;
+ rtcpParameters.compound = rsize.length === 0; // parses the rtcp-mux attr褨bute.
+ // Note that Edge does not support unmuxed RTCP.
+
+ var mux = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-mux');
+ rtcpParameters.mux = mux.length > 0;
+ return rtcpParameters;
+ }; // parses either a=msid: or a=ssrc:... msid lines and returns
+ // the id of the MediaStream and MediaStreamTrack.
+
+
+ SDPUtils.parseMsid = function (mediaSection) {
+ var parts;
+ var spec = SDPUtils.matchPrefix(mediaSection, 'a=msid:');
+
+ if (spec.length === 1) {
+ parts = spec[0].substr(7).split(' ');
+ return {
+ stream: parts[0],
+ track: parts[1]
+ };
+ }
+
+ var planB = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(function (line) {
+ return SDPUtils.parseSsrcMedia(line);
+ }).filter(function (msidParts) {
+ return msidParts.attribute === 'msid';
+ });
+
+ if (planB.length > 0) {
+ parts = planB[0].value.split(' ');
+ return {
+ stream: parts[0],
+ track: parts[1]
+ };
+ }
+ }; // SCTP
+ // parses draft-ietf-mmusic-sctp-sdp-26 first and falls back
+ // to draft-ietf-mmusic-sctp-sdp-05
+
+
+ SDPUtils.parseSctpDescription = function (mediaSection) {
+ var mline = SDPUtils.parseMLine(mediaSection);
+ var maxSizeLine = SDPUtils.matchPrefix(mediaSection, 'a=max-message-size:');
+ var maxMessageSize;
+
+ if (maxSizeLine.length > 0) {
+ maxMessageSize = parseInt(maxSizeLine[0].substr(19), 10);
+ }
+
+ if (isNaN(maxMessageSize)) {
+ maxMessageSize = 65536;
+ }
+
+ var sctpPort = SDPUtils.matchPrefix(mediaSection, 'a=sctp-port:');
+
+ if (sctpPort.length > 0) {
+ return {
+ port: parseInt(sctpPort[0].substr(12), 10),
+ protocol: mline.fmt,
+ maxMessageSize: maxMessageSize
+ };
+ }
+
+ var sctpMapLines = SDPUtils.matchPrefix(mediaSection, 'a=sctpmap:');
+
+ if (sctpMapLines.length > 0) {
+ var parts = SDPUtils.matchPrefix(mediaSection, 'a=sctpmap:')[0].substr(10).split(' ');
+ return {
+ port: parseInt(parts[0], 10),
+ protocol: parts[1],
+ maxMessageSize: maxMessageSize
+ };
+ }
+ }; // SCTP
+ // outputs the draft-ietf-mmusic-sctp-sdp-26 version that all browsers
+ // support by now receiving in this format, unless we originally parsed
+ // as the draft-ietf-mmusic-sctp-sdp-05 format (indicated by the m-line
+ // protocol of DTLS/SCTP -- without UDP/ or TCP/)
+
+
+ SDPUtils.writeSctpDescription = function (media, sctp) {
+ var output = [];
+
+ if (media.protocol !== 'DTLS/SCTP') {
+ output = ['m=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.protocol + '\r\n', 'c=IN IP4 0.0.0.0\r\n', 'a=sctp-port:' + sctp.port + '\r\n'];
+ } else {
+ output = ['m=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.port + '\r\n', 'c=IN IP4 0.0.0.0\r\n', 'a=sctpmap:' + sctp.port + ' ' + sctp.protocol + ' 65535\r\n'];
+ }
+
+ if (sctp.maxMessageSize !== undefined) {
+ output.push('a=max-message-size:' + sctp.maxMessageSize + '\r\n');
+ }
+
+ return output.join('');
+ }; // Generate a session ID for SDP.
+ // https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1
+ // recommends using a cryptographically random +ve 64-bit value
+ // but right now this should be acceptable and within the right range
+
+
+ SDPUtils.generateSessionId = function () {
+ return Math.random().toString().substr(2, 21);
+ }; // Write boilder plate for start of SDP
+ // sessId argument is optional - if not supplied it will
+ // be generated randomly
+ // sessVersion is optional and defaults to 2
+ // sessUser is optional and defaults to 'thisisadapterortc'
+
+
+ SDPUtils.writeSessionBoilerplate = function (sessId, sessVer, sessUser) {
+ var sessionId;
+ var version = sessVer !== undefined ? sessVer : 2;
+
+ if (sessId) {
+ sessionId = sessId;
+ } else {
+ sessionId = SDPUtils.generateSessionId();
+ }
+
+ var user = sessUser || 'thisisadapterortc'; // FIXME: sess-id should be an NTP timestamp.
+
+ return 'v=0\r\n' + 'o=' + user + ' ' + sessionId + ' ' + version + ' IN IP4 127.0.0.1\r\n' + 's=-\r\n' + 't=0 0\r\n';
+ };
+
+ SDPUtils.writeMediaSection = function (transceiver, caps, type, stream) {
+ var sdp = SDPUtils.writeRtpDescription(transceiver.kind, caps); // Map ICE parameters (ufrag, pwd) to SDP.
+
+ sdp += SDPUtils.writeIceParameters(transceiver.iceGatherer.getLocalParameters()); // Map DTLS parameters to SDP.
+
+ sdp += SDPUtils.writeDtlsParameters(transceiver.dtlsTransport.getLocalParameters(), type === 'offer' ? 'actpass' : 'active');
+ sdp += 'a=mid:' + transceiver.mid + '\r\n';
+
+ if (transceiver.direction) {
+ sdp += 'a=' + transceiver.direction + '\r\n';
+ } else if (transceiver.rtpSender && transceiver.rtpReceiver) {
+ sdp += 'a=sendrecv\r\n';
+ } else if (transceiver.rtpSender) {
+ sdp += 'a=sendonly\r\n';
+ } else if (transceiver.rtpReceiver) {
+ sdp += 'a=recvonly\r\n';
+ } else {
+ sdp += 'a=inactive\r\n';
+ }
+
+ if (transceiver.rtpSender) {
+ // spec.
+ var msid = 'msid:' + stream.id + ' ' + transceiver.rtpSender.track.id + '\r\n';
+ sdp += 'a=' + msid; // for Chrome.
+
+ sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc + ' ' + msid;
+
+ if (transceiver.sendEncodingParameters[0].rtx) {
+ sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc + ' ' + msid;
+ sdp += 'a=ssrc-group:FID ' + transceiver.sendEncodingParameters[0].ssrc + ' ' + transceiver.sendEncodingParameters[0].rtx.ssrc + '\r\n';
+ }
+ } // FIXME: this should be written by writeRtpDescription.
+
+
+ sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc + ' cname:' + SDPUtils.localCName + '\r\n';
+
+ if (transceiver.rtpSender && transceiver.sendEncodingParameters[0].rtx) {
+ sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc + ' cname:' + SDPUtils.localCName + '\r\n';
+ }
+
+ return sdp;
+ }; // Gets the direction from the mediaSection or the sessionpart.
+
+
+ SDPUtils.getDirection = function (mediaSection, sessionpart) {
+ // Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv.
+ var lines = SDPUtils.splitLines(mediaSection);
+
+ for (var i = 0; i < lines.length; i++) {
+ switch (lines[i]) {
+ case 'a=sendrecv':
+ case 'a=sendonly':
+ case 'a=recvonly':
+ case 'a=inactive':
+ return lines[i].substr(2);
+
+ }
+ }
+
+ if (sessionpart) {
+ return SDPUtils.getDirection(sessionpart);
+ }
+
+ return 'sendrecv';
+ };
+
+ SDPUtils.getKind = function (mediaSection) {
+ var lines = SDPUtils.splitLines(mediaSection);
+ var mline = lines[0].split(' ');
+ return mline[0].substr(2);
+ };
+
+ SDPUtils.isRejected = function (mediaSection) {
+ return mediaSection.split(' ', 2)[1] === '0';
+ };
+
+ SDPUtils.parseMLine = function (mediaSection) {
+ var lines = SDPUtils.splitLines(mediaSection);
+ var parts = lines[0].substr(2).split(' ');
+ return {
+ kind: parts[0],
+ port: parseInt(parts[1], 10),
+ protocol: parts[2],
+ fmt: parts.slice(3).join(' ')
+ };
+ };
+
+ SDPUtils.parseOLine = function (mediaSection) {
+ var line = SDPUtils.matchPrefix(mediaSection, 'o=')[0];
+ var parts = line.substr(2).split(' ');
+ return {
+ username: parts[0],
+ sessionId: parts[1],
+ sessionVersion: parseInt(parts[2], 10),
+ netType: parts[3],
+ addressType: parts[4],
+ address: parts[5]
+ };
+ }; // a very naive interpretation of a valid SDP.
+
+
+ SDPUtils.isValidSDP = function (blob) {
+ if (typeof blob !== 'string' || blob.length === 0) {
+ return false;
+ }
+
+ var lines = SDPUtils.splitLines(blob);
+
+ for (var i = 0; i < lines.length; i++) {
+ if (lines[i].length < 2 || lines[i].charAt(1) !== '=') {
+ return false;
+ } // TODO: check the modifier a bit more.
+
+ }
+
+ return true;
+ }; // Expose public methods.
+
+
+ if (_typeof(module) === 'object') {
+ module.exports = SDPUtils;
+ }
+ }, {}]
+ }, {}, [1])(1);
+});
+
+/*
+ The MIT License (MIT)
+
+ Copyright (c) 2016 Meetecho
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ */
+// List of sessions
+Janus$1.sessions = {};
+
+Janus$1.isExtensionEnabled = function () {
+ if (navigator.mediaDevices && navigator.mediaDevices.getDisplayMedia) {
+ // No need for the extension, getDisplayMedia is supported
+ return true;
+ }
+
+ if (window.navigator.userAgent.match('Chrome')) {
+ var chromever = parseInt(window.navigator.userAgent.match(/Chrome\/(.*) /)[1], 10);
+ var maxver = 33;
+ if (window.navigator.userAgent.match('Linux')) maxver = 35; // "known" crash in chrome 34 and 35 on linux
+
+ if (chromever >= 26 && chromever <= maxver) {
+ // Older versions of Chrome don't support this extension-based approach, so lie
+ return true;
+ }
+
+ return Janus$1.extension.isInstalled();
+ } else {
+ // Firefox of others, no need for the extension (but this doesn't mean it will work)
+ return true;
+ }
+};
+
+var defaultExtension = {
+ // Screensharing Chrome Extension ID
+ extensionId: 'hapfgfdkleiggjjpfpenajgdnfckjpaj',
+ isInstalled: function isInstalled() {
+ return document.querySelector('#janus-extension-installed') !== null;
+ },
+ getScreen: function getScreen(callback) {
+ var pending = window.setTimeout(function () {
+ var error = new Error('NavigatorUserMediaError');
+ error.name = 'The required Chrome extension is not installed: click <a href="#">here</a> to install it. (NOTE: this will need you to refresh the page)';
+ return callback(error);
+ }, 1000);
+ this.cache[pending] = callback;
+ window.postMessage({
+ type: 'janusGetScreen',
+ id: pending
+ }, '*');
+ },
+ init: function init() {
+ var cache = {};
+ this.cache = cache; // Wait for events from the Chrome Extension
+
+ window.addEventListener('message', function (event) {
+ if (event.origin != window.location.origin) return;
+
+ if (event.data.type == 'janusGotScreen' && cache[event.data.id]) {
+ var callback = cache[event.data.id];
+ delete cache[event.data.id];
+
+ if (event.data.sourceId === '') {
+ // user canceled
+ var error = new Error('NavigatorUserMediaError');
+ error.name = 'You cancelled the request for permission, giving up...';
+ callback(error);
+ } else {
+ callback(null, event.data.sourceId);
+ }
+ } else if (event.data.type == 'janusGetScreenPending') {
+ console.log('clearing ', event.data.id);
+ window.clearTimeout(event.data.id);
+ }
+ });
+ }
+};
+
+Janus$1.useDefaultDependencies = function (deps) {
+ var f = deps && deps.fetch || fetch;
+ var p = deps && deps.Promise || Promise;
+ var socketCls = deps && deps.WebSocket || WebSocket;
+ return {
+ newWebSocket: function newWebSocket(server, proto) {
+ return new socketCls(server, proto);
+ },
+ extension: deps && deps.extension || defaultExtension,
+ isArray: function isArray(arr) {
+ return Array.isArray(arr);
+ },
+ webRTCAdapter: deps && deps.adapter || window.adapter,
+ httpAPICall: function httpAPICall(url, options) {
+ var fetchOptions = {
+ method: options.verb,
+ headers: {
+ 'Accept': 'application/json, text/plain, */*'
+ },
+ cache: 'no-cache'
+ };
+
+ if (options.verb === "POST") {
+ fetchOptions.headers['Content-Type'] = 'application/json';
+ }
+
+ if (options.withCredentials !== undefined) {
+ fetchOptions.credentials = options.withCredentials === true ? 'include' : options.withCredentials ? options.withCredentials : 'omit';
+ }
+
+ if (options.body !== undefined) {
+ fetchOptions.body = JSON.stringify(options.body);
+ }
+
+ var fetching = f(url, fetchOptions)["catch"](function (error) {
+ return p.reject({
+ message: 'Probably a network error, is the server down?',
+ error: error
+ });
+ });
+ /*
+ * fetch() does not natively support timeouts.
+ * Work around this by starting a timeout manually, and racing it agains the fetch() to see which thing resolves first.
+ */
+
+ if (options.timeout !== undefined) {
+ var timeout = new p(function (resolve, reject) {
+ var timerId = setTimeout(function () {
+ clearTimeout(timerId);
+ return reject({
+ message: 'Request timed out',
+ timeout: options.timeout
+ });
+ }, options.timeout);
+ });
+ fetching = p.race([fetching, timeout]);
+ }
+
+ fetching.then(function (response) {
+ if (response.ok) {
+ if (_typeof(options.success) === _typeof(Janus$1.noop)) {
+ return response.json().then(function (parsed) {
+ options.success(parsed);
+ })["catch"](function (error) {
+ return p.reject({
+ message: 'Failed to parse response body',
+ error: error,
+ response: response
+ });
+ });
+ }
+ } else {
+ return p.reject({
+ message: 'API call failed',
+ response: response
+ });
+ }
+ })["catch"](function (error) {
+ if (_typeof(options.error) === _typeof(Janus$1.noop)) {
+ options.error(error.message || '<< internal error >>', error);
+ }
+ });
+ return fetching;
+ }
+ };
+};
+
+Janus$1.useOldDependencies = function (deps) {
+ var jq = deps && deps.jQuery || jQuery;
+ var socketCls = deps && deps.WebSocket || WebSocket;
+ return {
+ newWebSocket: function newWebSocket(server, proto) {
+ return new socketCls(server, proto);
+ },
+ isArray: function isArray(arr) {
+ return jq.isArray(arr);
+ },
+ extension: deps && deps.extension || defaultExtension,
+ webRTCAdapter: deps && deps.adapter || adapter,
+ httpAPICall: function httpAPICall(url, options) {
+ var payload = options.body !== undefined ? {
+ contentType: 'application/json',
+ data: JSON.stringify(options.body)
+ } : {};
+ var credentials = options.withCredentials !== undefined ? {
+ xhrFields: {
+ withCredentials: options.withCredentials
+ }
+ } : {};
+ return jq.ajax(jq.extend(payload, credentials, {
+ url: url,
+ type: options.verb,
+ cache: false,
+ dataType: 'json',
+ async: options.async,
+ timeout: options.timeout,
+ success: function success(result) {
+ if (_typeof(options.success) === _typeof(Janus$1.noop)) {
+ options.success(result);
+ }
+ },
+ error: function error(xhr, status, err) {
+ if (_typeof(options.error) === _typeof(Janus$1.noop)) {
+ options.error(status, err);
+ }
+ }
+ }));
+ }
+ };
+};
+
+Janus$1.noop = function () {};
+
+Janus$1.dataChanDefaultLabel = "JanusDataChannel"; // Note: in the future we may want to change this, e.g., as was
+// attempted in https://github.com/meetecho/janus-gateway/issues/1670
+
+Janus$1.endOfCandidates = null; // Initialization
+
+Janus$1.init = function (options) {
+ options = options || {};
+ options.callback = typeof options.callback == "function" ? options.callback : Janus$1.noop;
+
+ if (Janus$1.initDone === true) {
+ // Already initialized
+ options.callback();
+ } else {
+ if (typeof console == "undefined" || typeof console.log == "undefined") console = {
+ log: function log() {}
+ }; // Console logging (all debugging disabled by default)
+
+ Janus$1.trace = Janus$1.noop;
+ Janus$1.debug = Janus$1.noop;
+ Janus$1.vdebug = Janus$1.noop;
+ Janus$1.log = Janus$1.noop;
+ Janus$1.warn = Janus$1.noop;
+ Janus$1.error = Janus$1.noop;
+
+ if (options.debug === true || options.debug === "all") {
+ // Enable all debugging levels
+ Janus$1.trace = console.trace.bind(console);
+ Janus$1.debug = console.debug.bind(console);
+ Janus$1.vdebug = console.debug.bind(console);
+ Janus$1.log = console.log.bind(console);
+ Janus$1.warn = console.warn.bind(console);
+ Janus$1.error = console.error.bind(console);
+ } else if (Array.isArray(options.debug)) {
+ for (var i in options.debug) {
+ var d = options.debug[i];
+
+ switch (d) {
+ case "trace":
+ Janus$1.trace = console.trace.bind(console);
+ break;
+
+ case "debug":
+ Janus$1.debug = console.debug.bind(console);
+ break;
+
+ case "vdebug":
+ Janus$1.vdebug = console.debug.bind(console);
+ break;
+
+ case "log":
+ Janus$1.log = console.log.bind(console);
+ break;
+
+ case "warn":
+ Janus$1.warn = console.warn.bind(console);
+ break;
+
+ case "error":
+ Janus$1.error = console.error.bind(console);
+ break;
+
+ default:
+ console.error("Unknown debugging option '" + d + "' (supported: 'trace', 'debug', 'vdebug', 'log', warn', 'error')");
+ break;
+ }
+ }
+ }
+
+ Janus$1.log("Initializing library");
+ var usedDependencies = options.dependencies || Janus$1.useDefaultDependencies();
+ Janus$1.isArray = usedDependencies.isArray;
+ Janus$1.webRTCAdapter = usedDependencies.webRTCAdapter;
+ Janus$1.httpAPICall = usedDependencies.httpAPICall;
+ Janus$1.newWebSocket = usedDependencies.newWebSocket;
+ Janus$1.extension = usedDependencies.extension;
+ Janus$1.extension.init(); // Helper method to enumerate devices
+
+ Janus$1.listDevices = function (callback, config) {
+ callback = typeof callback == "function" ? callback : Janus$1.noop;
+ if (config == null) config = {
+ audio: true,
+ video: true
+ };
+
+ if (Janus$1.isGetUserMediaAvailable()) {
+ navigator.mediaDevices.getUserMedia(config).then(function (stream) {
+ navigator.mediaDevices.enumerateDevices().then(function (devices) {
+ Janus$1.debug(devices);
+ callback(devices); // Get rid of the now useless stream
+
+ try {
+ var tracks = stream.getTracks();
+
+ for (var i in tracks) {
+ var mst = tracks[i];
+ if (mst !== null && mst !== undefined) mst.stop();
+ }
+ } catch (e) {}
+ });
+ })["catch"](function (err) {
+ Janus$1.error(err);
+ callback([]);
+ });
+ } else {
+ Janus$1.warn("navigator.mediaDevices unavailable");
+ callback([]);
+ }
+ }; // Helper methods to attach/reattach a stream to a video element (previously part of adapter.js)
+
+
+ Janus$1.attachMediaStream = function (element, stream) {
+ if (Janus$1.webRTCAdapter.browserDetails.browser === 'chrome') {
+ var chromever = Janus$1.webRTCAdapter.browserDetails.version;
+
+ if (chromever >= 52) {
+ element.srcObject = stream;
+ } else if (typeof element.src !== 'undefined') {
+ element.src = URL.createObjectURL(stream);
+ } else {
+ Janus$1.error("Error attaching stream to element");
+ }
+ } else {
+ element.srcObject = stream;
+ }
+ };
+
+ Janus$1.reattachMediaStream = function (to, from) {
+ if (Janus$1.webRTCAdapter.browserDetails.browser === 'chrome') {
+ var chromever = Janus$1.webRTCAdapter.browserDetails.version;
+
+ if (chromever >= 52) {
+ to.srcObject = from.srcObject;
+ } else if (typeof to.src !== 'undefined') {
+ to.src = from.src;
+ } else {
+ Janus$1.error("Error reattaching stream to element");
+ }
+ } else {
+ to.srcObject = from.srcObject;
+ }
+ }; // Detect tab close: make sure we don't loose existing onbeforeunload handlers
+ // (note: for iOS we need to subscribe to a different event, 'pagehide', see
+ // https://gist.github.com/thehunmonkgroup/6bee8941a49b86be31a787fe8f4b8cfe)
+
+
+ var iOS = ['iPad', 'iPhone', 'iPod'].indexOf(navigator.platform) >= 0;
+ var eventName = iOS ? 'pagehide' : 'beforeunload';
+ var oldOBF = window["on" + eventName];
+ window.addEventListener(eventName, function (event) {
+ Janus$1.log("Closing window");
+
+ for (var s in Janus$1.sessions) {
+ if (Janus$1.sessions[s] !== null && Janus$1.sessions[s] !== undefined && Janus$1.sessions[s].destroyOnUnload) {
+ Janus$1.log("Destroying session " + s);
+ Janus$1.sessions[s].destroy({
+ asyncRequest: false,
+ notifyDestroyed: false
+ });
+ }
+ }
+
+ if (oldOBF && typeof oldOBF == "function") oldOBF();
+ }); // If this is a Safari Technology Preview, check if VP8 is supported
+
+ Janus$1.safariVp8 = false;
+
+ if (Janus$1.webRTCAdapter.browserDetails.browser === 'safari' && Janus$1.webRTCAdapter.browserDetails.version >= 605) {
+ // Let's see if RTCRtpSender.getCapabilities() is there
+ if (RTCRtpSender && RTCRtpSender.getCapabilities && RTCRtpSender.getCapabilities("video") && RTCRtpSender.getCapabilities("video").codecs && RTCRtpSender.getCapabilities("video").codecs.length) {
+ for (var i in RTCRtpSender.getCapabilities("video").codecs) {
+ var codec = RTCRtpSender.getCapabilities("video").codecs[i];
+
+ if (codec && codec.mimeType && codec.mimeType.toLowerCase() === "video/vp8") {
+ Janus$1.safariVp8 = true;
+ break;
+ }
+ }
+
+ if (Janus$1.safariVp8) {
+ Janus$1.log("This version of Safari supports VP8");
+ } else {
+ Janus$1.warn("This version of Safari does NOT support VP8: if you're using a Technology Preview, " + "try enabling the 'WebRTC VP8 codec' setting in the 'Experimental Features' Develop menu");
+ }
+ } else {
+ // We do it in a very ugly way, as there's no alternative...
+ // We create a PeerConnection to see if VP8 is in an offer
+ var testpc = new RTCPeerConnection({}, {});
+ testpc.createOffer({
+ offerToReceiveVideo: true
+ }).then(function (offer) {
+ Janus$1.safariVp8 = offer.sdp.indexOf("VP8") !== -1;
+
+ if (Janus$1.safariVp8) {
+ Janus$1.log("This version of Safari supports VP8");
+ } else {
+ Janus$1.warn("This version of Safari does NOT support VP8: if you're using a Technology Preview, " + "try enabling the 'WebRTC VP8 codec' setting in the 'Experimental Features' Develop menu");
+ }
+
+ testpc.close();
+ testpc = null;
+ });
+ }
+ } // Check if this browser supports Unified Plan and transceivers
+ // Based on https://codepen.io/anon/pen/ZqLwWV?editors=0010
+
+
+ Janus$1.unifiedPlan = false;
+
+ if (Janus$1.webRTCAdapter.browserDetails.browser === 'firefox' && Janus$1.webRTCAdapter.browserDetails.version >= 59) {
+ // Firefox definitely does, starting from version 59
+ Janus$1.unifiedPlan = true;
+ } else if (Janus$1.webRTCAdapter.browserDetails.browser === 'chrome' && Janus$1.webRTCAdapter.browserDetails.version < 72) {
+ // Chrome does, but it's only usable from version 72 on
+ Janus$1.unifiedPlan = false;
+ } else if (typeof RTCRtpTransceiver !== 'undefined' && !('currentDirection' in RTCRtpTransceiver.prototype)) {
+ // Safari supports addTransceiver() but not Unified Plan when
+ // currentDirection is not defined (see codepen above)
+ Janus$1.unifiedPlan = false;
+ } else {
+ // Check if addTransceiver() throws an exception
+ var tempPc = new RTCPeerConnection();
+
+ try {
+ tempPc.addTransceiver('audio');
+ Janus$1.unifiedPlan = true;
+ } catch (e) {}
+
+ tempPc.close();
+ }
+
+ Janus$1.initDone = true;
+ options.callback();
+ }
+}; // Helper method to check whether WebRTC is supported by this browser
+
+
+Janus$1.isWebrtcSupported = function () {
+ return window.RTCPeerConnection !== undefined && window.RTCPeerConnection !== null;
+}; // Helper method to check whether devices can be accessed by this browser (e.g., not possible via plain HTTP)
+
+
+Janus$1.isGetUserMediaAvailable = function () {
+ return navigator.mediaDevices !== undefined && navigator.mediaDevices !== null && navigator.mediaDevices.getUserMedia !== undefined && navigator.mediaDevices.getUserMedia !== null;
+}; // Helper method to create random identifiers (e.g., transaction)
+
+
+Janus$1.randomString = function (len) {
+ var charSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+ var randomString = '';
+
+ for (var i = 0; i < len; i++) {
+ var randomPoz = Math.floor(Math.random() * charSet.length);
+ randomString += charSet.substring(randomPoz, randomPoz + 1);
+ }
+
+ return randomString;
+};
+
+function Janus$1(gatewayCallbacks) {
+ if (Janus$1.initDone === undefined) {
+ gatewayCallbacks.error("Library not initialized");
+ return {};
+ }
+
+ if (!Janus$1.isWebrtcSupported()) {
+ gatewayCallbacks.error("WebRTC not supported by this browser");
+ return {};
+ }
+
+ Janus$1.log("Library initialized: " + Janus$1.initDone);
+ gatewayCallbacks = gatewayCallbacks || {};
+ gatewayCallbacks.success = typeof gatewayCallbacks.success == "function" ? gatewayCallbacks.success : Janus$1.noop;
+ gatewayCallbacks.error = typeof gatewayCallbacks.error == "function" ? gatewayCallbacks.error : Janus$1.noop;
+ gatewayCallbacks.destroyed = typeof gatewayCallbacks.destroyed == "function" ? gatewayCallbacks.destroyed : Janus$1.noop;
+
+ if (gatewayCallbacks.server === null || gatewayCallbacks.server === undefined) {
+ gatewayCallbacks.error("Invalid server url");
+ return {};
+ }
+
+ var websockets = false;
+ var ws = null;
+ var wsHandlers = {};
+ var wsKeepaliveTimeoutId = null;
+ var servers = null,
+ serversIndex = 0;
+ var server = gatewayCallbacks.server;
+
+ if (Janus$1.isArray(server)) {
+ Janus$1.log("Multiple servers provided (" + server.length + "), will use the first that works");
+ server = null;
+ servers = gatewayCallbacks.server;
+ Janus$1.debug(servers);
+ } else {
+ if (server.indexOf("ws") === 0) {
+ websockets = true;
+ Janus$1.log("Using WebSockets to contact Janus: " + server);
+ } else {
+ websockets = false;
+ Janus$1.log("Using REST API to contact Janus: " + server);
+ }
+ }
+
+ var iceServers = gatewayCallbacks.iceServers;
+ if (iceServers === undefined || iceServers === null) iceServers = [{
+ urls: "stun:stun.l.google.com:19302"
+ }];
+ var iceTransportPolicy = gatewayCallbacks.iceTransportPolicy;
+ var bundlePolicy = gatewayCallbacks.bundlePolicy; // Whether IPv6 candidates should be gathered
+
+ var ipv6Support = gatewayCallbacks.ipv6;
+ if (ipv6Support === undefined || ipv6Support === null) ipv6Support = false; // Whether we should enable the withCredentials flag for XHR requests
+
+ var withCredentials = false;
+ if (gatewayCallbacks.withCredentials !== undefined && gatewayCallbacks.withCredentials !== null) withCredentials = gatewayCallbacks.withCredentials === true; // Optional max events
+
+ var maxev = 10;
+ if (gatewayCallbacks.max_poll_events !== undefined && gatewayCallbacks.max_poll_events !== null) maxev = gatewayCallbacks.max_poll_events;
+ if (maxev < 1) maxev = 1; // Token to use (only if the token based authentication mechanism is enabled)
+
+ var token = null;
+ if (gatewayCallbacks.token !== undefined && gatewayCallbacks.token !== null) token = gatewayCallbacks.token; // API secret to use (only if the shared API secret is enabled)
+
+ var apisecret = null;
+ if (gatewayCallbacks.apisecret !== undefined && gatewayCallbacks.apisecret !== null) apisecret = gatewayCallbacks.apisecret; // Whether we should destroy this session when onbeforeunload is called
+
+ this.destroyOnUnload = true;
+ if (gatewayCallbacks.destroyOnUnload !== undefined && gatewayCallbacks.destroyOnUnload !== null) this.destroyOnUnload = gatewayCallbacks.destroyOnUnload === true; // Some timeout-related values
+
+ var keepAlivePeriod = 25000;
+ if (gatewayCallbacks.keepAlivePeriod !== undefined && gatewayCallbacks.keepAlivePeriod !== null) keepAlivePeriod = gatewayCallbacks.keepAlivePeriod;
+ if (isNaN(keepAlivePeriod)) keepAlivePeriod = 25000;
+ var longPollTimeout = 60000;
+ if (gatewayCallbacks.longPollTimeout !== undefined && gatewayCallbacks.longPollTimeout !== null) longPollTimeout = gatewayCallbacks.longPollTimeout;
+ if (isNaN(longPollTimeout)) longPollTimeout = 60000; // overrides for default maxBitrate values for simulcasting
+
+ function getMaxBitrates(simulcastMaxBitrates) {
+ var maxBitrates = {
+ high: 900000,
+ medium: 300000,
+ low: 100000
+ };
+
+ if (simulcastMaxBitrates !== undefined && simulcastMaxBitrates !== null) {
+ if (simulcastMaxBitrates.high) maxBitrates.high = simulcastMaxBitrates.high;
+ if (simulcastMaxBitrates.medium) maxBitrates.medium = simulcastMaxBitrates.medium;
+ if (simulcastMaxBitrates.low) maxBitrates.low = simulcastMaxBitrates.low;
+ }
+
+ return maxBitrates;
+ }
+
+ var connected = false;
+ var sessionId = null;
+ var pluginHandles = {};
+ var that = this;
+ var retries = 0;
+ var transactions = {};
+ createSession(gatewayCallbacks); // Public methods
+
+ this.getServer = function () {
+ return server;
+ };
+
+ this.isConnected = function () {
+ return connected;
+ };
+
+ this.reconnect = function (callbacks) {
+ callbacks = callbacks || {};
+ callbacks.success = typeof callbacks.success == "function" ? callbacks.success : Janus$1.noop;
+ callbacks.error = typeof callbacks.error == "function" ? callbacks.error : Janus$1.noop;
+ callbacks["reconnect"] = true;
+ createSession(callbacks);
+ };
+
+ this.getSessionId = function () {
+ return sessionId;
+ };
+
+ this.destroy = function (callbacks) {
+ destroySession(callbacks);
+ };
+
+ this.attach = function (callbacks) {
+ createHandle(callbacks);
+ };
+
+ function eventHandler() {
+ if (sessionId == null) return;
+ Janus$1.debug('Long poll...');
+
+ if (!connected) {
+ Janus$1.warn("Is the server down? (connected=false)");
+ return;
+ }
+
+ var longpoll = server + "/" + sessionId + "?rid=" + new Date().getTime();
+ if (maxev !== undefined && maxev !== null) longpoll = longpoll + "&maxev=" + maxev;
+ if (token !== null && token !== undefined) longpoll = longpoll + "&token=" + encodeURIComponent(token);
+ if (apisecret !== null && apisecret !== undefined) longpoll = longpoll + "&apisecret=" + encodeURIComponent(apisecret);
+ Janus$1.httpAPICall(longpoll, {
+ verb: 'GET',
+ withCredentials: withCredentials,
+ success: handleEvent,
+ timeout: longPollTimeout,
+ error: function error(textStatus, errorThrown) {
+ Janus$1.error(textStatus + ":", errorThrown);
+ retries++;
+
+ if (retries > 3) {
+ // Did we just lose the server? :-(
+ connected = false;
+ gatewayCallbacks.error("Lost connection to the server (is it down?)");
+ return;
+ }
+
+ eventHandler();
+ }
+ });
+ } // Private event handler: this will trigger plugin callbacks, if set
+
+
+ function handleEvent(json, skipTimeout) {
+ retries = 0;
+ if (!websockets && sessionId !== undefined && sessionId !== null && skipTimeout !== true) eventHandler();
+
+ if (!websockets && Janus$1.isArray(json)) {
+ // We got an array: it means we passed a maxev > 1, iterate on all objects
+ for (var i = 0; i < json.length; i++) {
+ handleEvent(json[i], true);
+ }
+
+ return;
+ }
+
+ if (json["rtcgw"] === "keepalive") {
+ // Nothing happened
+ Janus$1.vdebug("Got a keepalive on session " + sessionId);
+ return;
+ } else if (json["rtcgw"] === "ack") {
+ // Just an ack, we can probably ignore
+ Janus$1.debug("Got an ack on session " + sessionId);
+ Janus$1.debug(json);
+ var transaction = json["transaction"];
+
+ if (transaction !== null && transaction !== undefined) {
+ var reportSuccess = transactions[transaction];
+
+ if (reportSuccess !== null && reportSuccess !== undefined) {
+ reportSuccess(json);
+ }
+
+ delete transactions[transaction];
+ }
+
+ return;
+ } else if (json["rtcgw"] === "success") {
+ // Success!
+ Janus$1.debug("Got a success on session " + sessionId);
+ Janus$1.debug(json);
+ var transaction = json["transaction"];
+
+ if (transaction !== null && transaction !== undefined) {
+ var reportSuccess = transactions[transaction];
+
+ if (reportSuccess !== null && reportSuccess !== undefined) {
+ reportSuccess(json);
+ }
+
+ delete transactions[transaction];
+ }
+
+ return;
+ } else if (json["rtcgw"] === "trickle") {
+ // We got a trickle candidate from Janus
+ var sender = json["sender"];
+
+ if (sender === undefined || sender === null) {
+ Janus$1.warn("Missing sender...");
+ return;
+ }
+
+ var pluginHandle = pluginHandles[sender];
+
+ if (pluginHandle === undefined || pluginHandle === null) {
+ Janus$1.debug("This handle is not attached to this session");
+ return;
+ }
+
+ var candidate = json["candidate"];
+ Janus$1.debug("Got a trickled candidate on session " + sessionId);
+ Janus$1.debug(candidate);
+ var config = pluginHandle.webrtcStuff;
+
+ if (config.pc && config.remoteSdp) {
+ // Add candidate right now
+ Janus$1.debug("Adding remote candidate:", candidate);
+
+ if (!candidate || candidate.completed === true) {
+ // end-of-candidates
+ config.pc.addIceCandidate(Janus$1.endOfCandidates);
+ } else {
+ // New candidate
+ config.pc.addIceCandidate(candidate);
+ }
+ } else {
+ // We didn't do setRemoteDescription (trickle got here before the offer?)
+ Janus$1.debug("We didn't do setRemoteDescription (trickle got here before the offer?), caching candidate");
+ if (!config.candidates) config.candidates = [];
+ config.candidates.push(candidate);
+ Janus$1.debug(config.candidates);
+ }
+ } else if (json["rtcgw"] === "webrtcup") {
+ // The PeerConnection with the server is up! Notify this
+ Janus$1.debug("Got a webrtcup event on session " + sessionId);
+ Janus$1.debug(json);
+ var sender = json["sender"];
+
+ if (sender === undefined || sender === null) {
+ Janus$1.warn("Missing sender...");
+ return;
+ }
+
+ var pluginHandle = pluginHandles[sender];
+
+ if (pluginHandle === undefined || pluginHandle === null) {
+ Janus$1.debug("This handle is not attached to this session");
+ return;
+ }
+
+ pluginHandle.webrtcState(true);
+ return;
+ } else if (json["rtcgw"] === "hangup") {
+ // A plugin asked the core to hangup a PeerConnection on one of our handles
+ Janus$1.debug("Got a hangup event on session " + sessionId);
+ Janus$1.debug(json);
+ var sender = json["sender"];
+
+ if (sender === undefined || sender === null) {
+ Janus$1.warn("Missing sender...");
+ return;
+ }
+
+ var pluginHandle = pluginHandles[sender];
+
+ if (pluginHandle === undefined || pluginHandle === null) {
+ Janus$1.debug("This handle is not attached to this session");
+ return;
+ }
+
+ pluginHandle.webrtcState(false, json["reason"]);
+ pluginHandle.hangup();
+ } else if (json["rtcgw"] === "detached") {
+ // A plugin asked the core to detach one of our handles
+ Janus$1.debug("Got a detached event on session " + sessionId);
+ Janus$1.debug(json);
+ var sender = json["sender"];
+
+ if (sender === undefined || sender === null) {
+ Janus$1.warn("Missing sender...");
+ return;
+ }
+
+ var pluginHandle = pluginHandles[sender];
+
+ if (pluginHandle === undefined || pluginHandle === null) {
+ // Don't warn here because destroyHandle causes this situation.
+ return;
+ }
+
+ pluginHandle.detached = true;
+ pluginHandle.ondetached();
+ pluginHandle.detach();
+ } else if (json["rtcgw"] === "media") {
+ // Media started/stopped flowing
+ Janus$1.debug("Got a media event on session " + sessionId);
+ Janus$1.debug(json);
+ var sender = json["sender"];
+
+ if (sender === undefined || sender === null) {
+ Janus$1.warn("Missing sender...");
+ return;
+ }
+
+ var pluginHandle = pluginHandles[sender];
+
+ if (pluginHandle === undefined || pluginHandle === null) {
+ Janus$1.debug("This handle is not attached to this session");
+ return;
+ }
+
+ pluginHandle.mediaState(json["type"], json["receiving"]);
+ } else if (json["rtcgw"] === "slowlink") {
+ Janus$1.debug("Got a slowlink event on session " + sessionId);
+ Janus$1.debug(json); // Trouble uplink or downlink
+
+ var sender = json["sender"];
+
+ if (sender === undefined || sender === null) {
+ Janus$1.warn("Missing sender...");
+ return;
+ }
+
+ var pluginHandle = pluginHandles[sender];
+
+ if (pluginHandle === undefined || pluginHandle === null) {
+ Janus$1.debug("This handle is not attached to this session");
+ return;
+ }
+
+ pluginHandle.slowLink(json["uplink"], json["lost"]);
+ } else if (json["rtcgw"] === "error") {
+ // Oops, something wrong happened
+ Janus$1.error("Ooops: " + json["error"].code + " " + json["error"].reason); // FIXME
+
+ Janus$1.debug(json);
+ var transaction = json["transaction"];
+
+ if (transaction !== null && transaction !== undefined) {
+ var reportSuccess = transactions[transaction];
+
+ if (reportSuccess !== null && reportSuccess !== undefined) {
+ reportSuccess(json);
+ }
+
+ delete transactions[transaction];
+ }
+
+ return;
+ } else if (json["rtcgw"] === "event") {
+ Janus$1.debug("Got a plugin event on session " + sessionId);
+ Janus$1.debug(json);
+ var sender = json["sender"];
+
+ if (sender === undefined || sender === null) {
+ Janus$1.warn("Missing sender...");
+ return;
+ }
+
+ var plugindata = json["plugindata"];
+
+ if (plugindata === undefined || plugindata === null) {
+ Janus$1.warn("Missing plugindata...");
+ return;
+ }
+
+ Janus$1.debug(" -- Event is coming from " + sender + " (" + plugindata["plugin"] + ")");
+ var data = plugindata["data"];
+ Janus$1.debug(data);
+ var pluginHandle = pluginHandles[sender];
+
+ if (pluginHandle === undefined || pluginHandle === null) {
+ Janus$1.warn("This handle is not attached to this session");
+ return;
+ }
+
+ var jsep = json["jsep"];
+
+ if (jsep !== undefined && jsep !== null) {
+ Janus$1.debug("Handling SDP as well...");
+ Janus$1.debug(jsep);
+ }
+
+ var callback = pluginHandle.onmessage;
+
+ if (callback !== null && callback !== undefined) {
+ Janus$1.debug("Notifying application..."); // Send to callback specified when attaching plugin handle
+
+ callback(data, jsep);
+ } else {
+ // Send to generic callback (?)
+ Janus$1.debug("No provided notification callback");
+ }
+ } else if (json["rtcgw"] === "timeout") {
+ Janus$1.error("Timeout on session " + sessionId);
+ Janus$1.debug(json);
+
+ if (websockets) {
+ ws.close(3504, "Gateway timeout");
+ }
+
+ return;
+ } else {
+ Janus$1.warn("Unknown message/event '" + json["rtcgw"] + "' on session " + sessionId);
+ Janus$1.debug(json);
+ }
+ } // Private helper to send keep-alive messages on WebSockets
+
+
+ function keepAlive() {
+ if (server === null || !websockets || !connected) return;
+ wsKeepaliveTimeoutId = setTimeout(keepAlive, keepAlivePeriod);
+ var request = {
+ "rtcgw": "keepalive",
+ "session_id": sessionId,
+ "transaction": Janus$1.randomString(12)
+ };
+ if (token !== null && token !== undefined) request["token"] = token;
+ if (apisecret !== null && apisecret !== undefined) request["apisecret"] = apisecret;
+ ws.send(JSON.stringify(request));
+ } // Private method to create a session
+
+
+ function createSession(callbacks) {
+ var transaction = Janus$1.randomString(12); // console.log("jannus create_token",stream);
+
+ var request = {
+ "rtcgw": "create",
+ "transaction": transaction,
+ "token": window.EZUIKit.opt.stream,
+ "device": window.EZUIKit.opt.deviceSerial,
+ "channel": window.EZUIKit.opt.channelNo
+ };
+
+ if (callbacks["reconnect"]) {
+ // We're reconnecting, claim the session
+ connected = false;
+ request["rtcgw"] = "claim";
+ request["session_id"] = sessionId; // If we were using websockets, ignore the old connection
+
+ if (ws) {
+ ws.onopen = null;
+ ws.onerror = null;
+ ws.onclose = null;
+
+ if (wsKeepaliveTimeoutId) {
+ clearTimeout(wsKeepaliveTimeoutId);
+ wsKeepaliveTimeoutId = null;
+ }
+ }
+ }
+
+ if (token !== null && token !== undefined) request["token"] = token;
+ if (apisecret !== null && apisecret !== undefined) request["apisecret"] = apisecret;
+
+ if (server === null && Janus$1.isArray(servers)) {
+ // We still need to find a working server from the list we were given
+ server = servers[serversIndex];
+
+ if (server.indexOf("ws") === 0) {
+ websockets = true;
+ Janus$1.log("Server #" + (serversIndex + 1) + ": trying WebSockets to contact Janus (" + server + ")");
+ } else {
+ websockets = false;
+ Janus$1.log("Server #" + (serversIndex + 1) + ": trying REST API to contact Janus (" + server + ")");
+ }
+ }
+
+ if (websockets) {
+ ws = Janus$1.newWebSocket(server, 'rtcgw-protocol');
+ wsHandlers = {
+ 'error': function error() {
+ Janus$1.error("Error connecting to the Janus WebSockets server... " + server);
+
+ if (Janus$1.isArray(servers) && !callbacks["reconnect"]) {
+ serversIndex++;
+
+ if (serversIndex == servers.length) {
+ // We tried all the servers the user gave us and they all failed
+ callbacks.error("Error connecting to any of the provided Janus servers: Is the server down?");
+ return;
+ } // Let's try the next server
+
+
+ server = null;
+ setTimeout(function () {
+ createSession(callbacks);
+ }, 200);
+ return;
+ }
+
+ callbacks.error("Error connecting to the Janus WebSockets server: Is the server down?");
+ },
+ 'open': function open() {
+ // We need to be notified about the success
+ transactions[transaction] = function (json) {
+ Janus$1.debug(json);
+
+ if (json["rtcgw"] !== "success") {
+ Janus$1.error("Ooops: " + json["error"].code + " " + json["error"].reason); // FIXME
+
+ callbacks.error(json["error"].reason);
+ return;
+ }
+
+ wsKeepaliveTimeoutId = setTimeout(keepAlive, keepAlivePeriod);
+ connected = true;
+ sessionId = json["session_id"] ? json["session_id"] : json.data["id"];
+
+ if (callbacks["reconnect"]) {
+ Janus$1.log("Claimed session: " + sessionId);
+ } else {
+ Janus$1.log("Created session: " + sessionId);
+ }
+
+ Janus$1.sessions[sessionId] = that;
+ callbacks.success();
+ };
+
+ ws.send(JSON.stringify(request));
+ },
+ 'message': function message(event) {
+ handleEvent(JSON.parse(event.data));
+ },
+ 'close': function close() {
+ if (server === null || !connected) {
+ return;
+ }
+
+ connected = false; // FIXME What if this is called when the page is closed?
+
+ gatewayCallbacks.error("Lost connection to the server (is it down?)");
+ }
+ };
+
+ for (var eventName in wsHandlers) {
+ ws.addEventListener(eventName, wsHandlers[eventName]);
+ }
+
+ return;
+ }
+
+ Janus$1.httpAPICall(server, {
+ verb: 'POST',
+ withCredentials: withCredentials,
+ body: request,
+ success: function success(json) {
+ Janus$1.debug(json);
+
+ if (json["rtcgw"] !== "success") {
+ Janus$1.error("Ooops: " + json["error"].code + " " + json["error"].reason); // FIXME
+
+ callbacks.error(json["error"].reason);
+ return;
+ }
+
+ connected = true;
+ sessionId = json["session_id"] ? json["session_id"] : json.data["id"];
+
+ if (callbacks["reconnect"]) {
+ Janus$1.log("Claimed session: " + sessionId);
+ } else {
+ Janus$1.log("Created session: " + sessionId);
+ }
+
+ Janus$1.sessions[sessionId] = that;
+ eventHandler();
+ callbacks.success();
+ },
+ error: function error(textStatus, errorThrown) {
+ Janus$1.error(textStatus + ":", errorThrown); // FIXME
+
+ if (Janus$1.isArray(servers) && !callbacks["reconnect"]) {
+ serversIndex++;
+
+ if (serversIndex == servers.length) {
+ // We tried all the servers the user gave us and they all failed
+ callbacks.error("Error connecting to any of the provided Janus servers: Is the server down?");
+ return;
+ } // Let's try the next server
+
+
+ server = null;
+ setTimeout(function () {
+ createSession(callbacks);
+ }, 200);
+ return;
+ }
+
+ if (errorThrown === "") callbacks.error(textStatus + ": Is the server down?");else callbacks.error(textStatus + ": " + errorThrown);
+ }
+ });
+ } // Private method to destroy a session
+
+
+ function destroySession(callbacks) {
+ callbacks = callbacks || {}; // FIXME This method triggers a success even when we fail
+
+ callbacks.success = typeof callbacks.success == "function" ? callbacks.success : Janus$1.noop;
+ var asyncRequest = true;
+ if (callbacks.asyncRequest !== undefined && callbacks.asyncRequest !== null) asyncRequest = callbacks.asyncRequest === true;
+ var notifyDestroyed = true;
+ if (callbacks.notifyDestroyed !== undefined && callbacks.notifyDestroyed !== null) notifyDestroyed = callbacks.notifyDestroyed === true;
+ var cleanupHandles = false;
+ if (callbacks.cleanupHandles !== undefined && callbacks.cleanupHandles !== null) cleanupHandles = callbacks.cleanupHandles === true;
+ Janus$1.log("Destroying session " + sessionId + " (async=" + asyncRequest + ")");
+
+ if (!connected) {
+ Janus$1.warn("Is the server down? (connected=false)");
+ callbacks.success();
+ return;
+ }
+
+ if (sessionId === undefined || sessionId === null) {
+ Janus$1.warn("No session to destroy");
+ callbacks.success();
+ if (notifyDestroyed) gatewayCallbacks.destroyed();
+ return;
+ }
+
+ if (cleanupHandles) {
+ for (var handleId in pluginHandles) {
+ destroyHandle(handleId, {
+ noRequest: true
+ });
+ }
+ } // No need to destroy all handles first, Janus will do that itself
+
+
+ var request = {
+ "rtcgw": "destroy",
+ "transaction": Janus$1.randomString(12)
+ };
+ if (token !== null && token !== undefined) request["token"] = token;
+ if (apisecret !== null && apisecret !== undefined) request["apisecret"] = apisecret;
+
+ if (websockets) {
+ request["session_id"] = sessionId;
+
+ var unbindWebSocket = function unbindWebSocket() {
+ for (var eventName in wsHandlers) {
+ ws.removeEventListener(eventName, wsHandlers[eventName]);
+ }
+
+ ws.removeEventListener('message', onUnbindMessage);
+ ws.removeEventListener('error', onUnbindError);
+
+ if (wsKeepaliveTimeoutId) {
+ clearTimeout(wsKeepaliveTimeoutId);
+ }
+
+ ws.close();
+ };
+
+ var onUnbindMessage = function onUnbindMessage(event) {
+ var data = JSON.parse(event.data);
+
+ if (data.session_id == request.session_id && data.transaction == request.transaction) {
+ unbindWebSocket();
+ callbacks.success();
+ if (notifyDestroyed) gatewayCallbacks.destroyed();
+ }
+ };
+
+ var onUnbindError = function onUnbindError(event) {
+ unbindWebSocket();
+ callbacks.error("Failed to destroy the server: Is the server down?");
+ if (notifyDestroyed) gatewayCallbacks.destroyed();
+ };
+
+ ws.addEventListener('message', onUnbindMessage);
+ ws.addEventListener('error', onUnbindError);
+ ws.send(JSON.stringify(request));
+ return;
+ }
+
+ Janus$1.httpAPICall(server + "/" + sessionId, {
+ verb: 'POST',
+ async: asyncRequest,
+ // Sometimes we need false here, or destroying in onbeforeunload won't work
+ withCredentials: withCredentials,
+ body: request,
+ success: function success(json) {
+ Janus$1.log("Destroyed session:");
+ Janus$1.debug(json);
+ sessionId = null;
+ connected = false;
+
+ if (json["rtcgw"] !== "success") {
+ Janus$1.error("Ooops: " + json["error"].code + " " + json["error"].reason); // FIXME
+ }
+
+ callbacks.success();
+ if (notifyDestroyed) gatewayCallbacks.destroyed();
+ },
+ error: function error(textStatus, errorThrown) {
+ Janus$1.error(textStatus + ":", errorThrown); // FIXME
+ // Reset everything anyway
+
+ sessionId = null;
+ connected = false;
+ callbacks.success();
+ if (notifyDestroyed) gatewayCallbacks.destroyed();
+ }
+ });
+ } // Private method to create a plugin handle
+
+
+ function createHandle(callbacks) {
+ callbacks = callbacks || {};
+ callbacks.success = typeof callbacks.success == "function" ? callbacks.success : Janus$1.noop;
+ callbacks.error = typeof callbacks.error == "function" ? callbacks.error : Janus$1.noop;
+ callbacks.consentDialog = typeof callbacks.consentDialog == "function" ? callbacks.consentDialog : Janus$1.noop;
+ callbacks.iceState = typeof callbacks.iceState == "function" ? callbacks.iceState : Janus$1.noop;
+ callbacks.mediaState = typeof callbacks.mediaState == "function" ? callbacks.mediaState : Janus$1.noop;
+ callbacks.webrtcState = typeof callbacks.webrtcState == "function" ? callbacks.webrtcState : Janus$1.noop;
+ callbacks.slowLink = typeof callbacks.slowLink == "function" ? callbacks.slowLink : Janus$1.noop;
+ callbacks.onmessage = typeof callbacks.onmessage == "function" ? callbacks.onmessage : Janus$1.noop;
+ callbacks.onlocalstream = typeof callbacks.onlocalstream == "function" ? callbacks.onlocalstream : Janus$1.noop;
+ callbacks.onremotestream = typeof callbacks.onremotestream == "function" ? callbacks.onremotestream : Janus$1.noop;
+ callbacks.ondata = typeof callbacks.ondata == "function" ? callbacks.ondata : Janus$1.noop;
+ callbacks.ondataopen = typeof callbacks.ondataopen == "function" ? callbacks.ondataopen : Janus$1.noop;
+ callbacks.oncleanup = typeof callbacks.oncleanup == "function" ? callbacks.oncleanup : Janus$1.noop;
+ callbacks.ondetached = typeof callbacks.ondetached == "function" ? callbacks.ondetached : Janus$1.noop;
+
+ if (!connected) {
+ Janus$1.warn("Is the server down? (connected=false)");
+ callbacks.error("Is the server down? (connected=false)");
+ return;
+ }
+
+ var plugin = callbacks.plugin;
+
+ if (plugin === undefined || plugin === null) {
+ Janus$1.error("Invalid plugin");
+ callbacks.error("Invalid plugin");
+ return;
+ }
+
+ var opaqueId = callbacks.opaqueId;
+ var handleToken = callbacks.token ? callbacks.token : token;
+ var transaction = Janus$1.randomString(12);
+ var request = {
+ "rtcgw": "attach",
+ "plugin": plugin,
+ "opaque_id": opaqueId,
+ "transaction": transaction
+ };
+ if (handleToken !== null && handleToken !== undefined) request["token"] = handleToken;
+ if (apisecret !== null && apisecret !== undefined) request["apisecret"] = apisecret;
+
+ if (websockets) {
+ transactions[transaction] = function (json) {
+ Janus$1.debug(json);
+
+ if (json["rtcgw"] !== "success") {
+ Janus$1.error("Ooops: " + json["error"].code + " " + json["error"].reason); // FIXME
+
+ callbacks.error("Ooops: " + json["error"].code + " " + json["error"].reason);
+ return;
+ }
+
+ var handleId = json.data["id"];
+ Janus$1.log("Created handle: " + handleId);
+ var pluginHandle = {
+ session: that,
+ plugin: plugin,
+ id: handleId,
+ token: handleToken,
+ detached: false,
+ webrtcStuff: {
+ started: false,
+ myStream: null,
+ streamExternal: false,
+ remoteStream: null,
+ mySdp: null,
+ mediaConstraints: null,
+ pc: null,
+ dataChannel: {},
+ dtmfSender: null,
+ trickle: true,
+ iceDone: false,
+ volume: {
+ value: null,
+ timer: null
+ },
+ bitrate: {
+ value: null,
+ bsnow: null,
+ bsbefore: null,
+ tsnow: null,
+ tsbefore: null,
+ timer: null
+ }
+ },
+ getId: function getId() {
+ return handleId;
+ },
+ getPlugin: function getPlugin() {
+ return plugin;
+ },
+ getVolume: function getVolume() {
+ return _getVolume(handleId, true);
+ },
+ getRemoteVolume: function getRemoteVolume() {
+ return _getVolume(handleId, true);
+ },
+ getLocalVolume: function getLocalVolume() {
+ return _getVolume(handleId, false);
+ },
+ isAudioMuted: function isAudioMuted() {
+ return isMuted(handleId, false);
+ },
+ muteAudio: function muteAudio() {
+ return mute(handleId, false, true);
+ },
+ unmuteAudio: function unmuteAudio() {
+ return mute(handleId, false, false);
+ },
+ isVideoMuted: function isVideoMuted() {
+ return isMuted(handleId, true);
+ },
+ muteVideo: function muteVideo() {
+ return mute(handleId, true, true);
+ },
+ unmuteVideo: function unmuteVideo() {
+ return mute(handleId, true, false);
+ },
+ getBitrate: function getBitrate() {
+ return _getBitrate(handleId);
+ },
+ send: function send(callbacks) {
+ sendMessage(handleId, callbacks);
+ },
+ data: function data(callbacks) {
+ sendData(handleId, callbacks);
+ },
+ dtmf: function dtmf(callbacks) {
+ sendDtmf(handleId, callbacks);
+ },
+ consentDialog: callbacks.consentDialog,
+ iceState: callbacks.iceState,
+ mediaState: callbacks.mediaState,
+ webrtcState: callbacks.webrtcState,
+ slowLink: callbacks.slowLink,
+ onmessage: callbacks.onmessage,
+ createOffer: function createOffer(callbacks) {
+ prepareWebrtc(handleId, true, callbacks);
+ },
+ createAnswer: function createAnswer(callbacks) {
+ prepareWebrtc(handleId, false, callbacks);
+ },
+ handleRemoteJsep: function handleRemoteJsep(callbacks) {
+ prepareWebrtcPeer(handleId, callbacks);
+ },
+ onlocalstream: callbacks.onlocalstream,
+ onremotestream: callbacks.onremotestream,
+ ondata: callbacks.ondata,
+ ondataopen: callbacks.ondataopen,
+ oncleanup: callbacks.oncleanup,
+ ondetached: callbacks.ondetached,
+ hangup: function hangup(sendRequest) {
+ cleanupWebrtc(handleId, sendRequest === true);
+ },
+ detach: function detach(callbacks) {
+ destroyHandle(handleId, callbacks);
+ }
+ };
+ pluginHandles[handleId] = pluginHandle;
+ callbacks.success(pluginHandle);
+ };
+
+ request["session_id"] = sessionId;
+ ws.send(JSON.stringify(request));
+ return;
+ }
+
+ Janus$1.httpAPICall(server + "/" + sessionId, {
+ verb: 'POST',
+ withCredentials: withCredentials,
+ body: request,
+ success: function success(json) {
+ Janus$1.debug(json);
+
+ if (json["rtcgw"] !== "success") {
+ Janus$1.error("Ooops: " + json["error"].code + " " + json["error"].reason); // FIXME
+
+ callbacks.error("Ooops: " + json["error"].code + " " + json["error"].reason);
+ return;
+ }
+
+ var handleId = json.data["id"];
+ Janus$1.log("Created handle: " + handleId);
+ var pluginHandle = {
+ session: that,
+ plugin: plugin,
+ id: handleId,
+ token: handleToken,
+ detached: false,
+ webrtcStuff: {
+ started: false,
+ myStream: null,
+ streamExternal: false,
+ remoteStream: null,
+ mySdp: null,
+ mediaConstraints: null,
+ pc: null,
+ dataChannel: {},
+ dtmfSender: null,
+ trickle: true,
+ iceDone: false,
+ volume: {
+ value: null,
+ timer: null
+ },
+ bitrate: {
+ value: null,
+ bsnow: null,
+ bsbefore: null,
+ tsnow: null,
+ tsbefore: null,
+ timer: null
+ }
+ },
+ getId: function getId() {
+ return handleId;
+ },
+ getPlugin: function getPlugin() {
+ return plugin;
+ },
+ getVolume: function getVolume() {
+ return _getVolume(handleId, true);
+ },
+ getRemoteVolume: function getRemoteVolume() {
+ return _getVolume(handleId, true);
+ },
+ getLocalVolume: function getLocalVolume() {
+ return _getVolume(handleId, false);
+ },
+ isAudioMuted: function isAudioMuted() {
+ return isMuted(handleId, false);
+ },
+ muteAudio: function muteAudio() {
+ return mute(handleId, false, true);
+ },
+ unmuteAudio: function unmuteAudio() {
+ return mute(handleId, false, false);
+ },
+ isVideoMuted: function isVideoMuted() {
+ return isMuted(handleId, true);
+ },
+ muteVideo: function muteVideo() {
+ return mute(handleId, true, true);
+ },
+ unmuteVideo: function unmuteVideo() {
+ return mute(handleId, true, false);
+ },
+ getBitrate: function getBitrate() {
+ return _getBitrate(handleId);
+ },
+ send: function send(callbacks) {
+ sendMessage(handleId, callbacks);
+ },
+ data: function data(callbacks) {
+ sendData(handleId, callbacks);
+ },
+ dtmf: function dtmf(callbacks) {
+ sendDtmf(handleId, callbacks);
+ },
+ consentDialog: callbacks.consentDialog,
+ iceState: callbacks.iceState,
+ mediaState: callbacks.mediaState,
+ webrtcState: callbacks.webrtcState,
+ slowLink: callbacks.slowLink,
+ onmessage: callbacks.onmessage,
+ createOffer: function createOffer(callbacks) {
+ prepareWebrtc(handleId, true, callbacks);
+ },
+ createAnswer: function createAnswer(callbacks) {
+ prepareWebrtc(handleId, false, callbacks);
+ },
+ handleRemoteJsep: function handleRemoteJsep(callbacks) {
+ prepareWebrtcPeer(handleId, callbacks);
+ },
+ onlocalstream: callbacks.onlocalstream,
+ onremotestream: callbacks.onremotestream,
+ ondata: callbacks.ondata,
+ ondataopen: callbacks.ondataopen,
+ oncleanup: callbacks.oncleanup,
+ ondetached: callbacks.ondetached,
+ hangup: function hangup(sendRequest) {
+ cleanupWebrtc(handleId, sendRequest === true);
+ },
+ detach: function detach(callbacks) {
+ destroyHandle(handleId, callbacks);
+ }
+ };
+ pluginHandles[handleId] = pluginHandle;
+ callbacks.success(pluginHandle);
+ },
+ error: function error(textStatus, errorThrown) {
+ Janus$1.error(textStatus + ":", errorThrown); // FIXME
+ }
+ });
+ } // Private method to send a message
+
+
+ function sendMessage(handleId, callbacks) {
+ callbacks = callbacks || {};
+ callbacks.success = typeof callbacks.success == "function" ? callbacks.success : Janus$1.noop;
+ callbacks.error = typeof callbacks.error == "function" ? callbacks.error : Janus$1.noop;
+
+ if (!connected) {
+ Janus$1.warn("Is the server down? (connected=false)");
+ callbacks.error("Is the server down? (connected=false)");
+ return;
+ }
+
+ var pluginHandle = pluginHandles[handleId];
+
+ if (pluginHandle === null || pluginHandle === undefined || pluginHandle.webrtcStuff === null || pluginHandle.webrtcStuff === undefined) {
+ Janus$1.warn("Invalid handle");
+ callbacks.error("Invalid handle");
+ return;
+ }
+
+ var message = callbacks.message;
+ var jsep = callbacks.jsep;
+ var transaction = Janus$1.randomString(12);
+ var request = {
+ "rtcgw": "message",
+ "body": message,
+ "transaction": transaction
+ };
+ if (pluginHandle.token !== null && pluginHandle.token !== undefined) request["token"] = pluginHandle.token;
+ if (apisecret !== null && apisecret !== undefined) request["apisecret"] = apisecret;
+ if (jsep !== null && jsep !== undefined) request.jsep = jsep;
+ Janus$1.debug("Sending message to plugin (handle=" + handleId + "):");
+ Janus$1.debug(request);
+
+ if (websockets) {
+ request["session_id"] = sessionId;
+ request["handle_id"] = handleId;
+
+ transactions[transaction] = function (json) {
+ Janus$1.debug("Message sent!");
+ Janus$1.debug(json);
+
+ if (json["rtcgw"] === "success") {
+ // We got a success, must have been a synchronous transaction
+ var plugindata = json["plugindata"];
+
+ if (plugindata === undefined || plugindata === null) {
+ Janus$1.warn("Request succeeded, but missing plugindata...");
+ callbacks.success();
+ return;
+ }
+
+ Janus$1.log("Synchronous transaction successful (" + plugindata["plugin"] + ")");
+ var data = plugindata["data"];
+ Janus$1.debug(data);
+ callbacks.success(data);
+ return;
+ } else if (json["rtcgw"] !== "ack") {
+ // Not a success and not an ack, must be an error
+ if (json["error"] !== undefined && json["error"] !== null) {
+ Janus$1.error("Ooops: " + json["error"].code + " " + json["error"].reason); // FIXME
+
+ callbacks.error(json["error"].code + " " + json["error"].reason);
+ } else {
+ Janus$1.error("Unknown error"); // FIXME
+
+ callbacks.error("Unknown error");
+ }
+
+ return;
+ } // If we got here, the plugin decided to handle the request asynchronously
+
+
+ callbacks.success();
+ };
+
+ ws.send(JSON.stringify(request));
+ return;
+ }
+
+ Janus$1.httpAPICall(server + "/" + sessionId + "/" + handleId, {
+ verb: 'POST',
+ withCredentials: withCredentials,
+ body: request,
+ success: function success(json) {
+ Janus$1.debug("Message sent!");
+ Janus$1.debug(json);
+
+ if (json["rtcgw"] === "success") {
+ // We got a success, must have been a synchronous transaction
+ var plugindata = json["plugindata"];
+
+ if (plugindata === undefined || plugindata === null) {
+ Janus$1.warn("Request succeeded, but missing plugindata...");
+ callbacks.success();
+ return;
+ }
+
+ Janus$1.log("Synchronous transaction successful (" + plugindata["plugin"] + ")");
+ var data = plugindata["data"];
+ Janus$1.debug(data);
+ callbacks.success(data);
+ return;
+ } else if (json["rtcgw"] !== "ack") {
+ // Not a success and not an ack, must be an error
+ if (json["error"] !== undefined && json["error"] !== null) {
+ Janus$1.error("Ooops: " + json["error"].code + " " + json["error"].reason); // FIXME
+
+ callbacks.error(json["error"].code + " " + json["error"].reason);
+ } else {
+ Janus$1.error("Unknown error"); // FIXME
+
+ callbacks.error("Unknown error");
+ }
+
+ return;
+ } // If we got here, the plugin decided to handle the request asynchronously
+
+
+ callbacks.success();
+ },
+ error: function error(textStatus, errorThrown) {
+ Janus$1.error(textStatus + ":", errorThrown); // FIXME
+
+ callbacks.error(textStatus + ": " + errorThrown);
+ }
+ });
+ } // Private method to send a trickle candidate
+
+
+ function sendTrickleCandidate(handleId, candidate) {
+ if (!connected) {
+ Janus$1.warn("Is the server down? (connected=false)");
+ return;
+ }
+
+ var pluginHandle = pluginHandles[handleId];
+
+ if (pluginHandle === null || pluginHandle === undefined || pluginHandle.webrtcStuff === null || pluginHandle.webrtcStuff === undefined) {
+ Janus$1.warn("Invalid handle");
+ return;
+ }
+
+ var request = {
+ "rtcgw": "trickle",
+ "candidate": candidate,
+ "transaction": Janus$1.randomString(12)
+ };
+ if (pluginHandle.token !== null && pluginHandle.token !== undefined) request["token"] = pluginHandle.token;
+ if (apisecret !== null && apisecret !== undefined) request["apisecret"] = apisecret;
+ Janus$1.vdebug("Sending trickle candidate (handle=" + handleId + "):");
+ Janus$1.vdebug(request);
+
+ if (websockets) {
+ request["session_id"] = sessionId;
+ request["handle_id"] = handleId;
+ ws.send(JSON.stringify(request));
+ return;
+ }
+
+ Janus$1.httpAPICall(server + "/" + sessionId + "/" + handleId, {
+ verb: 'POST',
+ withCredentials: withCredentials,
+ body: request,
+ success: function success(json) {
+ Janus$1.vdebug("Candidate sent!");
+ Janus$1.vdebug(json);
+
+ if (json["rtcgw"] !== "ack") {
+ Janus$1.error("Ooops: " + json["error"].code + " " + json["error"].reason); // FIXME
+
+ return;
+ }
+ },
+ error: function error(textStatus, errorThrown) {
+ Janus$1.error(textStatus + ":", errorThrown); // FIXME
+ }
+ });
+ } // Private method to create a data channel
+
+
+ function createDataChannel(handleId, dclabel, incoming, pendingText) {
+ var pluginHandle = pluginHandles[handleId];
+
+ if (pluginHandle === null || pluginHandle === undefined || pluginHandle.webrtcStuff === null || pluginHandle.webrtcStuff === undefined) {
+ Janus$1.warn("Invalid handle");
+ return;
+ }
+
+ var config = pluginHandle.webrtcStuff;
+
+ var onDataChannelMessage = function onDataChannelMessage(event) {
+ Janus$1.log('Received message on data channel:', event);
+ var label = event.target.label;
+ pluginHandle.ondata(event.data, label);
+ };
+
+ var onDataChannelStateChange = function onDataChannelStateChange(event) {
+ Janus$1.log('Received state change on data channel:', event);
+ var label = event.target.label;
+ var dcState = config.dataChannel[label] ? config.dataChannel[label].readyState : "null";
+ Janus$1.log('State change on <' + label + '> data channel: ' + dcState);
+
+ if (dcState === 'open') {
+ // Any pending messages to send?
+ if (config.dataChannel[label].pending && config.dataChannel[label].pending.length > 0) {
+ Janus$1.log("Sending pending messages on <" + label + ">:", config.dataChannel[label].pending.length);
+
+ for (var i in config.dataChannel[label].pending) {
+ var text = config.dataChannel[label].pending[i];
+ Janus$1.log("Sending string on data channel <" + label + ">: " + text);
+ config.dataChannel[label].send(text);
+ }
+
+ config.dataChannel[label].pending = [];
+ } // Notify the open data channel
+
+
+ pluginHandle.ondataopen(label);
+ }
+ };
+
+ var onDataChannelError = function onDataChannelError(error) {
+ Janus$1.error('Got error on data channel:', error); // TODO
+ };
+
+ if (!incoming) {
+ // FIXME Add options (ordered, maxRetransmits, etc.)
+ config.dataChannel[dclabel] = config.pc.createDataChannel(dclabel, {
+ ordered: false
+ });
+ } else {
+ // The channel was created by Janus
+ config.dataChannel[dclabel] = incoming;
+ }
+
+ config.dataChannel[dclabel].onmessage = onDataChannelMessage;
+ config.dataChannel[dclabel].onopen = onDataChannelStateChange;
+ config.dataChannel[dclabel].onclose = onDataChannelStateChange;
+ config.dataChannel[dclabel].onerror = onDataChannelError;
+ config.dataChannel[dclabel].pending = [];
+ if (pendingText) config.dataChannel[dclabel].pending.push(pendingText);
+ } // Private method to send a data channel message
+
+
+ function sendData(handleId, callbacks) {
+ callbacks = callbacks || {};
+ callbacks.success = typeof callbacks.success == "function" ? callbacks.success : Janus$1.noop;
+ callbacks.error = typeof callbacks.error == "function" ? callbacks.error : Janus$1.noop;
+ var pluginHandle = pluginHandles[handleId];
+
+ if (pluginHandle === null || pluginHandle === undefined || pluginHandle.webrtcStuff === null || pluginHandle.webrtcStuff === undefined) {
+ Janus$1.warn("Invalid handle");
+ callbacks.error("Invalid handle");
+ return;
+ }
+
+ var config = pluginHandle.webrtcStuff;
+ var text = callbacks.text;
+
+ if (text === null || text === undefined) {
+ Janus$1.warn("Invalid text");
+ callbacks.error("Invalid text");
+ return;
+ }
+
+ var label = callbacks.label ? callbacks.label : Janus$1.dataChanDefaultLabel;
+
+ if (!config.dataChannel[label]) {
+ // Create new data channel and wait for it to open
+ createDataChannel(handleId, label, false, text);
+ callbacks.success();
+ return;
+ }
+
+ if (config.dataChannel[label].readyState !== "open") {
+ config.dataChannel[label].pending.push(text);
+ callbacks.success();
+ return;
+ }
+
+ Janus$1.log("Sending string on data channel <" + label + ">: " + text);
+ config.dataChannel[label].send(text);
+ callbacks.success();
+ } // Private method to send a DTMF tone
+
+
+ function sendDtmf(handleId, callbacks) {
+ callbacks = callbacks || {};
+ callbacks.success = typeof callbacks.success == "function" ? callbacks.success : Janus$1.noop;
+ callbacks.error = typeof callbacks.error == "function" ? callbacks.error : Janus$1.noop;
+ var pluginHandle = pluginHandles[handleId];
+
+ if (pluginHandle === null || pluginHandle === undefined || pluginHandle.webrtcStuff === null || pluginHandle.webrtcStuff === undefined) {
+ Janus$1.warn("Invalid handle");
+ callbacks.error("Invalid handle");
+ return;
+ }
+
+ var config = pluginHandle.webrtcStuff;
+
+ if (config.dtmfSender === null || config.dtmfSender === undefined) {
+ // Create the DTMF sender the proper way, if possible
+ if (config.pc !== undefined && config.pc !== null) {
+ var senders = config.pc.getSenders();
+ var audioSender = senders.find(function (sender) {
+ return sender.track && sender.track.kind === 'audio';
+ });
+
+ if (!audioSender) {
+ Janus$1.warn("Invalid DTMF configuration (no audio track)");
+ callbacks.error("Invalid DTMF configuration (no audio track)");
+ return;
+ }
+
+ config.dtmfSender = audioSender.dtmf;
+
+ if (config.dtmfSender) {
+ Janus$1.log("Created DTMF Sender");
+
+ config.dtmfSender.ontonechange = function (tone) {
+ Janus$1.debug("Sent DTMF tone: " + tone.tone);
+ };
+ }
+ }
+
+ if (config.dtmfSender === null || config.dtmfSender === undefined) {
+ Janus$1.warn("Invalid DTMF configuration");
+ callbacks.error("Invalid DTMF configuration");
+ return;
+ }
+ }
+
+ var dtmf = callbacks.dtmf;
+
+ if (dtmf === null || dtmf === undefined) {
+ Janus$1.warn("Invalid DTMF parameters");
+ callbacks.error("Invalid DTMF parameters");
+ return;
+ }
+
+ var tones = dtmf.tones;
+
+ if (tones === null || tones === undefined) {
+ Janus$1.warn("Invalid DTMF string");
+ callbacks.error("Invalid DTMF string");
+ return;
+ }
+
+ var duration = dtmf.duration;
+ if (duration === null || duration === undefined) duration = 500; // We choose 500ms as the default duration for a tone
+
+ var gap = dtmf.gap;
+ if (gap === null || gap === undefined) gap = 50; // We choose 50ms as the default gap between tones
+
+ Janus$1.debug("Sending DTMF string " + tones + " (duration " + duration + "ms, gap " + gap + "ms)");
+ config.dtmfSender.insertDTMF(tones, duration, gap);
+ callbacks.success();
+ } // Private method to destroy a plugin handle
+
+
+ function destroyHandle(handleId, callbacks) {
+ callbacks = callbacks || {};
+ callbacks.success = typeof callbacks.success == "function" ? callbacks.success : Janus$1.noop;
+ callbacks.error = typeof callbacks.error == "function" ? callbacks.error : Janus$1.noop;
+ var asyncRequest = true;
+ if (callbacks.asyncRequest !== undefined && callbacks.asyncRequest !== null) asyncRequest = callbacks.asyncRequest === true;
+ var noRequest = true;
+ if (callbacks.noRequest !== undefined && callbacks.noRequest !== null) noRequest = callbacks.noRequest === true;
+ Janus$1.log("Destroying handle " + handleId + " (async=" + asyncRequest + ")");
+ cleanupWebrtc(handleId);
+ var pluginHandle = pluginHandles[handleId];
+
+ if (pluginHandle === null || pluginHandle === undefined || pluginHandle.detached) {
+ // Plugin was already detached by Janus, calling detach again will return a handle not found error, so just exit here
+ delete pluginHandles[handleId];
+ callbacks.success();
+ return;
+ }
+
+ if (noRequest) {
+ // We're only removing the handle locally
+ delete pluginHandles[handleId];
+ callbacks.success();
+ return;
+ }
+
+ if (!connected) {
+ Janus$1.warn("Is the server down? (connected=false)");
+ callbacks.error("Is the server down? (connected=false)");
+ return;
+ }
+
+ var request = {
+ "rtcgw": "detach",
+ "transaction": Janus$1.randomString(12)
+ };
+ if (pluginHandle.token !== null && pluginHandle.token !== undefined) request["token"] = pluginHandle.token;
+ if (apisecret !== null && apisecret !== undefined) request["apisecret"] = apisecret;
+
+ if (websockets) {
+ request["session_id"] = sessionId;
+ request["handle_id"] = handleId;
+ ws.send(JSON.stringify(request));
+ delete pluginHandles[handleId];
+ callbacks.success();
+ return;
+ }
+
+ Janus$1.httpAPICall(server + "/" + sessionId + "/" + handleId, {
+ verb: 'POST',
+ async: asyncRequest,
+ // Sometimes we need false here, or destroying in onbeforeunload won't work
+ withCredentials: withCredentials,
+ body: request,
+ success: function success(json) {
+ Janus$1.log("Destroyed handle:");
+ Janus$1.debug(json);
+
+ if (json["rtcgw"] !== "success") {
+ Janus$1.error("Ooops: " + json["error"].code + " " + json["error"].reason); // FIXME
+ }
+
+ delete pluginHandles[handleId];
+ callbacks.success();
+ },
+ error: function error(textStatus, errorThrown) {
+ Janus$1.error(textStatus + ":", errorThrown); // FIXME
+ // We cleanup anyway
+
+ delete pluginHandles[handleId];
+ callbacks.success();
+ }
+ });
+ } // WebRTC stuff
+
+
+ function streamsDone(handleId, jsep, media, callbacks, stream) {
+ var pluginHandle = pluginHandles[handleId];
+
+ if (pluginHandle === null || pluginHandle === undefined || pluginHandle.webrtcStuff === null || pluginHandle.webrtcStuff === undefined) {
+ Janus$1.warn("Invalid handle");
+ callbacks.error("Invalid handle");
+ return;
+ }
+
+ var config = pluginHandle.webrtcStuff;
+ Janus$1.debug("streamsDone:", stream);
+
+ if (stream) {
+ Janus$1.debug(" -- Audio tracks:", stream.getAudioTracks());
+ Janus$1.debug(" -- Video tracks:", stream.getVideoTracks());
+ } // We're now capturing the new stream: check if we're updating or if it's a new thing
+
+
+ var addTracks = false;
+
+ if (!config.myStream || !media.update || config.streamExternal) {
+ config.myStream = stream;
+ addTracks = true;
+ } else {
+ // We only need to update the existing stream
+ if ((!media.update && isAudioSendEnabled(media) || media.update && (media.addAudio || media.replaceAudio)) && stream.getAudioTracks() && stream.getAudioTracks().length) {
+ config.myStream.addTrack(stream.getAudioTracks()[0]);
+
+ if (Janus$1.unifiedPlan) {
+ // Use Transceivers
+ Janus$1.log((media.replaceAudio ? "Replacing" : "Adding") + " audio track:", stream.getAudioTracks()[0]);
+ var audioTransceiver = null;
+ var transceivers = config.pc.getTransceivers();
+
+ if (transceivers && transceivers.length > 0) {
+ for (var i in transceivers) {
+ var t = transceivers[i];
+
+ if (t.sender && t.sender.track && t.sender.track.kind === "audio" || t.receiver && t.receiver.track && t.receiver.track.kind === "audio") {
+ audioTransceiver = t;
+ break;
+ }
+ }
+ }
+
+ if (audioTransceiver && audioTransceiver.sender) {
+ audioTransceiver.sender.replaceTrack(stream.getAudioTracks()[0]);
+ } else {
+ config.pc.addTrack(stream.getAudioTracks()[0], stream);
+ }
+ } else {
+ Janus$1.log((media.replaceAudio ? "Replacing" : "Adding") + " audio track:", stream.getAudioTracks()[0]);
+ config.pc.addTrack(stream.getAudioTracks()[0], stream);
+ }
+ }
+
+ if ((!media.update && isVideoSendEnabled(media) || media.update && (media.addVideo || media.replaceVideo)) && stream.getVideoTracks() && stream.getVideoTracks().length) {
+ config.myStream.addTrack(stream.getVideoTracks()[0]);
+
+ if (Janus$1.unifiedPlan) {
+ // Use Transceivers
+ Janus$1.log((media.replaceVideo ? "Replacing" : "Adding") + " video track:", stream.getVideoTracks()[0]);
+ var videoTransceiver = null;
+ var transceivers = config.pc.getTransceivers();
+
+ if (transceivers && transceivers.length > 0) {
+ for (var i in transceivers) {
+ var t = transceivers[i];
+
+ if (t.sender && t.sender.track && t.sender.track.kind === "video" || t.receiver && t.receiver.track && t.receiver.track.kind === "video") {
+ videoTransceiver = t;
+ break;
+ }
+ }
+ }
+
+ if (videoTransceiver && videoTransceiver.sender) {
+ videoTransceiver.sender.replaceTrack(stream.getVideoTracks()[0]);
+ } else {
+ config.pc.addTrack(stream.getVideoTracks()[0], stream);
+ }
+ } else {
+ Janus$1.log((media.replaceVideo ? "Replacing" : "Adding") + " video track:", stream.getVideoTracks()[0]);
+ config.pc.addTrack(stream.getVideoTracks()[0], stream);
+ }
+ }
+ } // If we still need to create a PeerConnection, let's do that
+
+
+ if (!config.pc) {
+ var pc_config = {
+ "iceServers": iceServers,
+ "iceTransportPolicy": iceTransportPolicy,
+ "bundlePolicy": bundlePolicy
+ };
+
+ if (Janus$1.webRTCAdapter.browserDetails.browser === "chrome") {
+ // For Chrome versions before 72, we force a plan-b semantic, and unified-plan otherwise
+ pc_config["sdpSemantics"] = Janus$1.webRTCAdapter.browserDetails.version < 72 ? "plan-b" : "unified-plan";
+ }
+
+ var pc_constraints = {
+ "optional": [{
+ "DtlsSrtpKeyAgreement": true
+ }]
+ };
+
+ if (ipv6Support === true) {
+ pc_constraints.optional.push({
+ "googIPv6": true
+ });
+ } // Any custom constraint to add?
+
+
+ if (callbacks.rtcConstraints && _typeof(callbacks.rtcConstraints) === 'object') {
+ Janus$1.debug("Adding custom PeerConnection constraints:", callbacks.rtcConstraints);
+
+ for (var i in callbacks.rtcConstraints) {
+ pc_constraints.optional.push(callbacks.rtcConstraints[i]);
+ }
+ }
+
+ if (Janus$1.webRTCAdapter.browserDetails.browser === "edge") {
+ // This is Edge, enable BUNDLE explicitly
+ pc_config.bundlePolicy = "max-bundle";
+ }
+
+ Janus$1.log("Creating PeerConnection");
+ Janus$1.debug(pc_constraints);
+ config.pc = new RTCPeerConnection(pc_config, pc_constraints);
+ Janus$1.debug(config.pc);
+
+ if (config.pc.getStats) {
+ // FIXME
+ config.volume = {};
+ config.bitrate.value = "0 kbits/sec";
+ }
+
+ Janus$1.log("Preparing local SDP and gathering candidates (trickle=" + config.trickle + ")");
+
+ config.pc.oniceconnectionstatechange = function (e) {
+ if (config.pc) pluginHandle.iceState(config.pc.iceConnectionState);
+ };
+
+ config.pc.onicecandidate = function (event) {
+ if (event.candidate == null || Janus$1.webRTCAdapter.browserDetails.browser === 'edge' && event.candidate.candidate.indexOf('endOfCandidates') > 0) {
+ Janus$1.log("End of candidates.");
+ config.iceDone = true;
+
+ if (config.trickle === true) {
+ // Notify end of candidates
+ sendTrickleCandidate(handleId, {
+ "completed": true
+ });
+ } else {
+ // No trickle, time to send the complete SDP (including all candidates)
+ sendSDP(handleId, callbacks);
+ }
+ } else {
+ // JSON.stringify doesn't work on some WebRTC objects anymore
+ // See https://code.google.com/p/chromium/issues/detail?id=467366
+ var candidate = {
+ "candidate": event.candidate.candidate,
+ "sdpMid": event.candidate.sdpMid,
+ "sdpMLineIndex": event.candidate.sdpMLineIndex
+ };
+
+ if (config.trickle === true) {
+ // Send candidate
+ sendTrickleCandidate(handleId, candidate);
+ }
+ }
+ };
+
+ config.pc.ontrack = function (event) {
+ Janus$1.log("Handling Remote Track");
+ Janus$1.debug(event);
+ if (!event.streams) return;
+ config.remoteStream = event.streams[0];
+ pluginHandle.onremotestream(config.remoteStream);
+ if (event.track.onended) return;
+ Janus$1.log("Adding onended callback to track:", event.track);
+
+ event.track.onended = function (ev) {
+ Janus$1.log("Remote track muted/removed:", ev);
+
+ if (config.remoteStream) {
+ config.remoteStream.removeTrack(ev.target);
+ pluginHandle.onremotestream(config.remoteStream);
+ }
+ };
+
+ event.track.onmute = event.track.onended;
+
+ event.track.onunmute = function (ev) {
+ Janus$1.log("Remote track flowing again:", ev);
+
+ try {
+ config.remoteStream.addTrack(ev.target);
+ pluginHandle.onremotestream(config.remoteStream);
+ } catch (e) {
+ Janus$1.error(e);
+ }
+ };
+ };
+ }
+
+ if (addTracks && stream !== null && stream !== undefined) {
+ Janus$1.log('Adding local stream');
+ var simulcast2 = callbacks.simulcast2 === true ? true : false;
+ stream.getTracks().forEach(function (track) {
+ Janus$1.log('Adding local track:', track);
+
+ if (!simulcast2) {
+ config.pc.addTrack(track, stream);
+ } else {
+ if (track.kind === "audio") {
+ config.pc.addTrack(track, stream);
+ } else {
+ Janus$1.log('Enabling rid-based simulcasting:', track);
+ var maxBitrates = getMaxBitrates(callbacks.simulcastMaxBitrates);
+ config.pc.addTransceiver(track, {
+ direction: "sendrecv",
+ streams: [stream],
+ sendEncodings: [{
+ rid: "h",
+ active: true,
+ maxBitrate: maxBitrates.high
+ }, {
+ rid: "m",
+ active: true,
+ maxBitrate: maxBitrates.medium,
+ scaleResolutionDownBy: 2
+ }, {
+ rid: "l",
+ active: true,
+ maxBitrate: maxBitrates.low,
+ scaleResolutionDownBy: 4
+ }]
+ });
+ }
+ }
+ });
+ } // Any data channel to create?
+
+
+ if (isDataEnabled(media) && !config.dataChannel[Janus$1.dataChanDefaultLabel]) {
+ Janus$1.log("Creating data channel");
+ createDataChannel(handleId, Janus$1.dataChanDefaultLabel, false);
+
+ config.pc.ondatachannel = function (event) {
+ Janus$1.log("Data channel created by Janus:", event);
+ createDataChannel(handleId, event.channel.label, event.channel);
+ };
+ } // If there's a new local stream, let's notify the application
+
+
+ if (config.myStream) pluginHandle.onlocalstream(config.myStream); // Create offer/answer now
+
+ if (jsep === null || jsep === undefined) {
+ createOffer(handleId, media, callbacks);
+ } else {
+ config.pc.setRemoteDescription(jsep).then(function () {
+ Janus$1.log("Remote description accepted!");
+ config.remoteSdp = jsep.sdp; // Any trickle candidate we cached?
+
+ if (config.candidates && config.candidates.length > 0) {
+ for (var i = 0; i < config.candidates.length; i++) {
+ var candidate = config.candidates[i];
+ Janus$1.debug("Adding remote candidate:", candidate);
+
+ if (!candidate || candidate.completed === true) {
+ // end-of-candidates
+ config.pc.addIceCandidate(Janus$1.endOfCandidates);
+ } else {
+ // New candidate
+ config.pc.addIceCandidate(candidate);
+ }
+ }
+
+ config.candidates = [];
+ } // Create the answer now
+
+
+ createAnswer(handleId, media, callbacks);
+ }, callbacks.error);
+ }
+ }
+
+ function prepareWebrtc(handleId, offer, callbacks) {
+ callbacks = callbacks || {};
+ callbacks.success = typeof callbacks.success == "function" ? callbacks.success : Janus$1.noop;
+ callbacks.error = typeof callbacks.error == "function" ? callbacks.error : webrtcError;
+ var jsep = callbacks.jsep;
+
+ if (offer && jsep) {
+ Janus$1.error("Provided a JSEP to a createOffer");
+ callbacks.error("Provided a JSEP to a createOffer");
+ return;
+ } else if (!offer && (!jsep || !jsep.type || !jsep.sdp)) {
+ Janus$1.error("A valid JSEP is required for createAnswer");
+ callbacks.error("A valid JSEP is required for createAnswer");
+ return;
+ }
+
+ callbacks.media = callbacks.media || {
+ audio: true,
+ video: true
+ };
+ var media = callbacks.media;
+ var pluginHandle = pluginHandles[handleId];
+
+ if (pluginHandle === null || pluginHandle === undefined || pluginHandle.webrtcStuff === null || pluginHandle.webrtcStuff === undefined) {
+ Janus$1.warn("Invalid handle");
+ callbacks.error("Invalid handle");
+ return;
+ }
+
+ var config = pluginHandle.webrtcStuff;
+ config.trickle = isTrickleEnabled(callbacks.trickle); // Are we updating a session?
+
+ if (config.pc === undefined || config.pc === null) {
+ // Nope, new PeerConnection
+ media.update = false;
+ media.keepAudio = false;
+ media.keepVideo = false;
+ } else if (config.pc !== undefined && config.pc !== null) {
+ Janus$1.log("Updating existing media session");
+ media.update = true; // Check if there's anything to add/remove/replace, or if we
+ // can go directly to preparing the new SDP offer or answer
+
+ if (callbacks.stream !== null && callbacks.stream !== undefined) {
+ // External stream: is this the same as the one we were using before?
+ if (callbacks.stream !== config.myStream) {
+ Janus$1.log("Renegotiation involves a new external stream");
+ }
+ } else {
+ // Check if there are changes on audio
+ if (media.addAudio) {
+ media.keepAudio = false;
+ media.replaceAudio = false;
+ media.removeAudio = false;
+ media.audioSend = true;
+
+ if (config.myStream && config.myStream.getAudioTracks() && config.myStream.getAudioTracks().length) {
+ Janus$1.error("Can't add audio stream, there already is one");
+ callbacks.error("Can't add audio stream, there already is one");
+ return;
+ }
+ } else if (media.removeAudio) {
+ media.keepAudio = false;
+ media.replaceAudio = false;
+ media.addAudio = false;
+ media.audioSend = false;
+ } else if (media.replaceAudio) {
+ media.keepAudio = false;
+ media.addAudio = false;
+ media.removeAudio = false;
+ media.audioSend = true;
+ }
+
+ if (config.myStream === null || config.myStream === undefined) {
+ // No media stream: if we were asked to replace, it's actually an "add"
+ if (media.replaceAudio) {
+ media.keepAudio = false;
+ media.replaceAudio = false;
+ media.addAudio = true;
+ media.audioSend = true;
+ }
+
+ if (isAudioSendEnabled(media)) {
+ media.keepAudio = false;
+ media.addAudio = true;
+ }
+ } else {
+ if (config.myStream.getAudioTracks() === null || config.myStream.getAudioTracks() === undefined || config.myStream.getAudioTracks().length === 0) {
+ // No audio track: if we were asked to replace, it's actually an "add"
+ if (media.replaceAudio) {
+ media.keepAudio = false;
+ media.replaceAudio = false;
+ media.addAudio = true;
+ media.audioSend = true;
+ }
+
+ if (isAudioSendEnabled(media)) {
+ media.keepVideo = false;
+ media.addAudio = true;
+ }
+ } else {
+ // We have an audio track: should we keep it as it is?
+ if (isAudioSendEnabled(media) && !media.removeAudio && !media.replaceAudio) {
+ media.keepAudio = true;
+ }
+ }
+ } // Check if there are changes on video
+
+
+ if (media.addVideo) {
+ media.keepVideo = false;
+ media.replaceVideo = false;
+ media.removeVideo = false;
+ media.videoSend = true;
+
+ if (config.myStream && config.myStream.getVideoTracks() && config.myStream.getVideoTracks().length) {
+ Janus$1.error("Can't add video stream, there already is one");
+ callbacks.error("Can't add video stream, there already is one");
+ return;
+ }
+ } else if (media.removeVideo) {
+ media.keepVideo = false;
+ media.replaceVideo = false;
+ media.addVideo = false;
+ media.videoSend = false;
+ } else if (media.replaceVideo) {
+ media.keepVideo = false;
+ media.addVideo = false;
+ media.removeVideo = false;
+ media.videoSend = true;
+ }
+
+ if (config.myStream === null || config.myStream === undefined) {
+ // No media stream: if we were asked to replace, it's actually an "add"
+ if (media.replaceVideo) {
+ media.keepVideo = false;
+ media.replaceVideo = false;
+ media.addVideo = true;
+ media.videoSend = true;
+ }
+
+ if (isVideoSendEnabled(media)) {
+ media.keepVideo = false;
+ media.addVideo = true;
+ }
+ } else {
+ if (config.myStream.getVideoTracks() === null || config.myStream.getVideoTracks() === undefined || config.myStream.getVideoTracks().length === 0) {
+ // No video track: if we were asked to replace, it's actually an "add"
+ if (media.replaceVideo) {
+ media.keepVideo = false;
+ media.replaceVideo = false;
+ media.addVideo = true;
+ media.videoSend = true;
+ }
+
+ if (isVideoSendEnabled(media)) {
+ media.keepVideo = false;
+ media.addVideo = true;
+ }
+ } else {
+ // We have a video track: should we keep it as it is?
+ if (isVideoSendEnabled(media) && !media.removeVideo && !media.replaceVideo) {
+ media.keepVideo = true;
+ }
+ }
+ } // Data channels can only be added
+
+
+ if (media.addData) media.data = true;
+ } // If we're updating and keeping all tracks, let's skip the getUserMedia part
+
+
+ if (isAudioSendEnabled(media) && media.keepAudio && isVideoSendEnabled(media) && media.keepVideo) {
+ pluginHandle.consentDialog(false);
+ streamsDone(handleId, jsep, media, callbacks, config.myStream);
+ return;
+ }
+ } // If we're updating, check if we need to remove/replace one of the tracks
+
+
+ if (media.update && !config.streamExternal) {
+ if (media.removeAudio || media.replaceAudio) {
+ if (config.myStream && config.myStream.getAudioTracks() && config.myStream.getAudioTracks().length) {
+ var s = config.myStream.getAudioTracks()[0];
+ Janus$1.log("Removing audio track:", s);
+ config.myStream.removeTrack(s);
+
+ try {
+ s.stop();
+ } catch (e) {}
+ }
+
+ if (config.pc.getSenders() && config.pc.getSenders().length) {
+ var ra = true;
+
+ if (media.replaceAudio && Janus$1.unifiedPlan) {
+ // We can use replaceTrack
+ ra = false;
+ }
+
+ if (ra) {
+ for (var index in config.pc.getSenders()) {
+ var s = config.pc.getSenders()[index];
+
+ if (s && s.track && s.track.kind === "audio") {
+ Janus$1.log("Removing audio sender:", s);
+ config.pc.removeTrack(s);
+ }
+ }
+ }
+ }
+ }
+
+ if (media.removeVideo || media.replaceVideo) {
+ if (config.myStream && config.myStream.getVideoTracks() && config.myStream.getVideoTracks().length) {
+ var s = config.myStream.getVideoTracks()[0];
+ Janus$1.log("Removing video track:", s);
+ config.myStream.removeTrack(s);
+
+ try {
+ s.stop();
+ } catch (e) {}
+ }
+
+ if (config.pc.getSenders() && config.pc.getSenders().length) {
+ var rv = true;
+
+ if (media.replaceVideo && Janus$1.unifiedPlan) {
+ // We can use replaceTrack
+ rv = false;
+ }
+
+ if (rv) {
+ for (var index in config.pc.getSenders()) {
+ var s = config.pc.getSenders()[index];
+
+ if (s && s.track && s.track.kind === "video") {
+ Janus$1.log("Removing video sender:", s);
+ config.pc.removeTrack(s);
+ }
+ }
+ }
+ }
+ }
+ } // Was a MediaStream object passed, or do we need to take care of that?
+
+
+ if (callbacks.stream !== null && callbacks.stream !== undefined) {
+ var stream = callbacks.stream;
+ Janus$1.log("MediaStream provided by the application");
+ Janus$1.debug(stream); // If this is an update, let's check if we need to release the previous stream
+
+ if (media.update) {
+ if (config.myStream && config.myStream !== callbacks.stream && !config.streamExternal) {
+ // We're replacing a stream we captured ourselves with an external one
+ try {
+ // Try a MediaStreamTrack.stop() for each track
+ var tracks = config.myStream.getTracks();
+
+ for (var i in tracks) {
+ var mst = tracks[i];
+ Janus$1.log(mst);
+ if (mst !== null && mst !== undefined) mst.stop();
+ }
+ } catch (e) {// Do nothing if this fails
+ }
+
+ config.myStream = null;
+ }
+ } // Skip the getUserMedia part
+
+
+ config.streamExternal = true;
+ pluginHandle.consentDialog(false);
+ streamsDone(handleId, jsep, media, callbacks, stream);
+ return;
+ }
+
+ if (isAudioSendEnabled(media) || isVideoSendEnabled(media)) {
+ if (!Janus$1.isGetUserMediaAvailable()) {
+ callbacks.error("getUserMedia not available");
+ return;
+ }
+
+ var constraints = {
+ mandatory: {},
+ optional: []
+ };
+ pluginHandle.consentDialog(true);
+ var audioSupport = isAudioSendEnabled(media);
+
+ if (audioSupport === true && media != undefined && media != null) {
+ if (_typeof(media.audio) === 'object') {
+ audioSupport = media.audio;
+ }
+ }
+
+ var videoSupport = isVideoSendEnabled(media);
+
+ if (videoSupport === true && media != undefined && media != null) {
+ var simulcast = callbacks.simulcast === true ? true : false;
+ var simulcast2 = callbacks.simulcast2 === true ? true : false;
+ if ((simulcast || simulcast2) && !jsep && (media.video === undefined || media.video === false)) media.video = "hires";
+
+ if (media.video && media.video != 'screen' && media.video != 'window') {
+ if (_typeof(media.video) === 'object') {
+ videoSupport = media.video;
+ } else {
+ var width = 0;
+ var height = 0;
+
+ if (media.video === 'lowres') {
+ // Small resolution, 4:3
+ height = 240;
+ width = 320;
+ } else if (media.video === 'lowres-16:9') {
+ // Small resolution, 16:9
+ height = 180;
+ width = 320;
+ } else if (media.video === 'hires' || media.video === 'hires-16:9' || media.video === 'hdres') {
+ // High(HD) resolution is only 16:9
+ height = 720;
+ width = 1280;
+ } else if (media.video === 'fhdres') {
+ // Full HD resolution is only 16:9
+ height = 1080;
+ width = 1920;
+ } else if (media.video === '4kres') {
+ // 4K resolution is only 16:9
+ height = 2160;
+ width = 3840;
+ } else if (media.video === 'stdres') {
+ // Normal resolution, 4:3
+ height = 480;
+ width = 640;
+ } else if (media.video === 'stdres-16:9') {
+ // Normal resolution, 16:9
+ height = 360;
+ width = 640;
+ } else {
+ Janus$1.log("Default video setting is stdres 4:3");
+ height = 480;
+ width = 640;
+ }
+
+ Janus$1.log("Adding media constraint:", media.video);
+ videoSupport = {
+ 'height': {
+ 'ideal': height
+ },
+ 'width': {
+ 'ideal': width
+ }
+ };
+ Janus$1.log("Adding video constraint:", videoSupport);
+ }
+ } else if (media.video === 'screen' || media.video === 'window') {
+ // We're going to try and use the extension for Chrome 34+, the old approach
+ // for older versions of Chrome, or the experimental support in Firefox 33+
+ var callbackUserMedia = function callbackUserMedia(error, stream) {
+ pluginHandle.consentDialog(false);
+
+ if (error) {
+ callbacks.error(error);
+ } else {
+ streamsDone(handleId, jsep, media, callbacks, stream);
+ }
+ };
+
+ var getScreenMedia = function getScreenMedia(constraints, gsmCallback, useAudio) {
+ Janus$1.log("Adding media constraint (screen capture)");
+ Janus$1.debug(constraints);
+ navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {
+ if (useAudio) {
+ navigator.mediaDevices.getUserMedia({
+ audio: true,
+ video: false
+ }).then(function (audioStream) {
+ stream.addTrack(audioStream.getAudioTracks()[0]);
+ gsmCallback(null, stream);
+ });
+ } else {
+ gsmCallback(null, stream);
+ }
+ })["catch"](function (error) {
+ pluginHandle.consentDialog(false);
+ gsmCallback(error);
+ });
+ };
+
+ if (!media.screenshareFrameRate) {
+ media.screenshareFrameRate = 3;
+ }
+
+ if (navigator.mediaDevices && navigator.mediaDevices.getDisplayMedia) {
+ // The new experimental getDisplayMedia API is available, let's use that
+ // https://groups.google.com/forum/#!topic/discuss-webrtc/Uf0SrR4uxzk
+ // https://webrtchacks.com/chrome-screensharing-getdisplaymedia/
+ navigator.mediaDevices.getDisplayMedia({
+ video: true
+ }).then(function (stream) {
+ pluginHandle.consentDialog(false);
+
+ if (isAudioSendEnabled(media) && !media.keepAudio) {
+ navigator.mediaDevices.getUserMedia({
+ audio: true,
+ video: false
+ }).then(function (audioStream) {
+ stream.addTrack(audioStream.getAudioTracks()[0]);
+ streamsDone(handleId, jsep, media, callbacks, stream);
+ });
+ } else {
+ streamsDone(handleId, jsep, media, callbacks, stream);
+ }
+ }, function (error) {
+ pluginHandle.consentDialog(false);
+ callbacks.error(error);
+ });
+ return;
+ }
+
+ if (Janus$1.webRTCAdapter.browserDetails.browser === 'chrome') {
+ var chromever = Janus$1.webRTCAdapter.browserDetails.version;
+ var maxver = 33;
+ if (window.navigator.userAgent.match('Linux')) maxver = 35; // "known" crash in chrome 34 and 35 on linux
+
+ if (chromever >= 26 && chromever <= maxver) {
+ // Chrome 26->33 requires some awkward chrome://flags manipulation
+ constraints = {
+ video: {
+ mandatory: {
+ googLeakyBucket: true,
+ maxWidth: window.screen.width,
+ maxHeight: window.screen.height,
+ minFrameRate: media.screenshareFrameRate,
+ maxFrameRate: media.screenshareFrameRate,
+ chromeMediaSource: 'screen'
+ }
+ },
+ audio: isAudioSendEnabled(media) && !media.keepAudio
+ };
+ getScreenMedia(constraints, callbackUserMedia);
+ } else {
+ // Chrome 34+ requires an extension
+ Janus$1.extension.getScreen(function (error, sourceId) {
+ if (error) {
+ pluginHandle.consentDialog(false);
+ return callbacks.error(error);
+ }
+
+ constraints = {
+ audio: false,
+ video: {
+ mandatory: {
+ chromeMediaSource: 'desktop',
+ maxWidth: window.screen.width,
+ maxHeight: window.screen.height,
+ minFrameRate: media.screenshareFrameRate,
+ maxFrameRate: media.screenshareFrameRate
+ },
+ optional: [{
+ googLeakyBucket: true
+ }, {
+ googTemporalLayeredScreencast: true
+ }]
+ }
+ };
+ constraints.video.mandatory.chromeMediaSourceId = sourceId;
+ getScreenMedia(constraints, callbackUserMedia, isAudioSendEnabled(media) && !media.keepAudio);
+ });
+ }
+ } else if (Janus$1.webRTCAdapter.browserDetails.browser === 'firefox') {
+ if (Janus$1.webRTCAdapter.browserDetails.version >= 33) {
+ // Firefox 33+ has experimental support for screen sharing
+ constraints = {
+ video: {
+ mozMediaSource: media.video,
+ mediaSource: media.video
+ },
+ audio: isAudioSendEnabled(media) && !media.keepAudio
+ };
+ getScreenMedia(constraints, function (err, stream) {
+ callbackUserMedia(err, stream); // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=1045810
+
+ if (!err) {
+ var lastTime = stream.currentTime;
+ var polly = window.setInterval(function () {
+ if (!stream) window.clearInterval(polly);
+
+ if (stream.currentTime == lastTime) {
+ window.clearInterval(polly);
+
+ if (stream.onended) {
+ stream.onended();
+ }
+ }
+
+ lastTime = stream.currentTime;
+ }, 500);
+ }
+ });
+ } else {
+ var error = new Error('NavigatorUserMediaError');
+ error.name = 'Your version of Firefox does not support screen sharing, please install Firefox 33 (or more recent versions)';
+ pluginHandle.consentDialog(false);
+ callbacks.error(error);
+ return;
+ }
+ }
+
+ return;
+ }
+ } // If we got here, we're not screensharing
+
+
+ if (media === null || media === undefined || media.video !== 'screen') {
+ // Check whether all media sources are actually available or not
+ navigator.mediaDevices.enumerateDevices().then(function (devices) {
+ var audioExist = devices.some(function (device) {
+ return device.kind === 'audioinput';
+ }),
+ videoExist = isScreenSendEnabled(media) || devices.some(function (device) {
+ return device.kind === 'videoinput';
+ }); // Check whether a missing device is really a problem
+
+ var audioSend = isAudioSendEnabled(media);
+ var videoSend = isVideoSendEnabled(media);
+ var needAudioDevice = isAudioSendRequired(media);
+ var needVideoDevice = isVideoSendRequired(media);
+
+ if (audioSend || videoSend || needAudioDevice || needVideoDevice) {
+ // We need to send either audio or video
+ var haveAudioDevice = audioSend ? audioExist : false;
+ var haveVideoDevice = videoSend ? videoExist : false;
+
+ if (!haveAudioDevice && !haveVideoDevice) {
+ // FIXME Should we really give up, or just assume recvonly for both?
+ pluginHandle.consentDialog(false);
+ callbacks.error('No capture device found');
+ return false;
+ } else if (!haveAudioDevice && needAudioDevice) {
+ pluginHandle.consentDialog(false);
+ callbacks.error('Audio capture is required, but no capture device found');
+ return false;
+ } else if (!haveVideoDevice && needVideoDevice) {
+ pluginHandle.consentDialog(false);
+ callbacks.error('Video capture is required, but no capture device found');
+ return false;
+ }
+ }
+
+ var gumConstraints = {
+ audio: audioExist && !media.keepAudio ? audioSupport : false,
+ video: videoExist && !media.keepVideo ? videoSupport : false
+ };
+ Janus$1.debug("getUserMedia constraints", gumConstraints);
+
+ if (!gumConstraints.audio && !gumConstraints.video) {
+ pluginHandle.consentDialog(false);
+ streamsDone(handleId, jsep, media, callbacks, stream);
+ } else {
+ navigator.mediaDevices.getUserMedia(gumConstraints).then(function (stream) {
+ pluginHandle.consentDialog(false);
+ streamsDone(handleId, jsep, media, callbacks, stream);
+ })["catch"](function (error) {
+ pluginHandle.consentDialog(false);
+ callbacks.error({
+ code: error.code,
+ name: error.name,
+ message: error.message
+ });
+ });
+ }
+ })["catch"](function (error) {
+ pluginHandle.consentDialog(false);
+ callbacks.error('enumerateDevices error', error);
+ });
+ }
+ } else {
+ // No need to do a getUserMedia, create offer/answer right away
+ streamsDone(handleId, jsep, media, callbacks);
+ }
+ }
+
+ function prepareWebrtcPeer(handleId, callbacks) {
+ callbacks = callbacks || {};
+ callbacks.success = typeof callbacks.success == "function" ? callbacks.success : Janus$1.noop;
+ callbacks.error = typeof callbacks.error == "function" ? callbacks.error : webrtcError;
+ var jsep = callbacks.jsep;
+ var pluginHandle = pluginHandles[handleId];
+
+ if (pluginHandle === null || pluginHandle === undefined || pluginHandle.webrtcStuff === null || pluginHandle.webrtcStuff === undefined) {
+ Janus$1.warn("Invalid handle");
+ callbacks.error("Invalid handle");
+ return;
+ }
+
+ var config = pluginHandle.webrtcStuff;
+
+ if (jsep !== undefined && jsep !== null) {
+ if (config.pc === null) {
+ Janus$1.warn("Wait, no PeerConnection?? if this is an answer, use createAnswer and not handleRemoteJsep");
+ callbacks.error("No PeerConnection: if this is an answer, use createAnswer and not handleRemoteJsep");
+ return;
+ }
+
+ config.pc.setRemoteDescription(jsep).then(function () {
+ Janus$1.log("Remote description accepted!");
+ config.remoteSdp = jsep.sdp; // Any trickle candidate we cached?
+
+ if (config.candidates && config.candidates.length > 0) {
+ for (var i = 0; i < config.candidates.length; i++) {
+ var candidate = config.candidates[i];
+ Janus$1.debug("Adding remote candidate:", candidate);
+
+ if (!candidate || candidate.completed === true) {
+ // end-of-candidates
+ config.pc.addIceCandidate(Janus$1.endOfCandidates);
+ } else {
+ // New candidate
+ config.pc.addIceCandidate(candidate);
+ }
+ }
+
+ config.candidates = [];
+ } // Done
+
+
+ callbacks.success();
+ }, callbacks.error);
+ } else {
+ callbacks.error("Invalid JSEP");
+ }
+ }
+
+ function createOffer(handleId, media, callbacks) {
+ callbacks = callbacks || {};
+ callbacks.success = typeof callbacks.success == "function" ? callbacks.success : Janus$1.noop;
+ callbacks.error = typeof callbacks.error == "function" ? callbacks.error : Janus$1.noop;
+ callbacks.customizeSdp = typeof callbacks.customizeSdp == "function" ? callbacks.customizeSdp : Janus$1.noop;
+ var pluginHandle = pluginHandles[handleId];
+
+ if (pluginHandle === null || pluginHandle === undefined || pluginHandle.webrtcStuff === null || pluginHandle.webrtcStuff === undefined) {
+ Janus$1.warn("Invalid handle");
+ callbacks.error("Invalid handle");
+ return;
+ }
+
+ var config = pluginHandle.webrtcStuff;
+ var simulcast = callbacks.simulcast === true ? true : false;
+
+ if (!simulcast) {
+ Janus$1.log("Creating offer (iceDone=" + config.iceDone + ")");
+ } else {
+ Janus$1.log("Creating offer (iceDone=" + config.iceDone + ", simulcast=" + simulcast + ")");
+ } // https://code.google.com/p/webrtc/issues/detail?id=3508
+
+
+ var mediaConstraints = {};
+
+ if (Janus$1.unifiedPlan) {
+ // We can use Transceivers
+ var audioTransceiver = null,
+ videoTransceiver = null;
+ var transceivers = config.pc.getTransceivers();
+
+ if (transceivers && transceivers.length > 0) {
+ for (var i in transceivers) {
+ var t = transceivers[i];
+
+ if (t.sender && t.sender.track && t.sender.track.kind === "audio" || t.receiver && t.receiver.track && t.receiver.track.kind === "audio") {
+ if (!audioTransceiver) audioTransceiver = t;
+ continue;
+ }
+
+ if (t.sender && t.sender.track && t.sender.track.kind === "video" || t.receiver && t.receiver.track && t.receiver.track.kind === "video") {
+ if (!videoTransceiver) videoTransceiver = t;
+ continue;
+ }
+ }
+ } // Handle audio (and related changes, if any)
+
+
+ var audioSend = isAudioSendEnabled(media);
+ var audioRecv = isAudioRecvEnabled(media);
+
+ if (!audioSend && !audioRecv) {
+ // Audio disabled: have we removed it?
+ if (media.removeAudio && audioTransceiver) {
+ if (audioTransceiver.setDirection) {
+ audioTransceiver.setDirection("inactive");
+ } else {
+ audioTransceiver.direction = "inactive";
+ }
+
+ Janus$1.log("Setting audio transceiver to inactive:", audioTransceiver);
+ }
+ } else {
+ // Take care of audio m-line
+ if (audioSend && audioRecv) {
+ if (audioTransceiver) {
+ if (audioTransceiver.setDirection) {
+ audioTransceiver.setDirection("sendrecv");
+ } else {
+ audioTransceiver.direction = "sendrecv";
+ }
+
+ Janus$1.log("Setting audio transceiver to sendrecv:", audioTransceiver);
+ }
+ } else if (audioSend && !audioRecv) {
+ if (audioTransceiver) {
+ if (audioTransceiver.setDirection) {
+ audioTransceiver.setDirection("sendonly");
+ } else {
+ audioTransceiver.direction = "sendonly";
+ }
+
+ Janus$1.log("Setting audio transceiver to sendonly:", audioTransceiver);
+ }
+ } else if (!audioSend && audioRecv) {
+ if (audioTransceiver) {
+ if (audioTransceiver.setDirection) {
+ audioTransceiver.setDirection("recvonly");
+ } else {
+ audioTransceiver.direction = "recvonly";
+ }
+
+ Janus$1.log("Setting audio transceiver to recvonly:", audioTransceiver);
+ } else {
+ // In theory, this is the only case where we might not have a transceiver yet
+ audioTransceiver = config.pc.addTransceiver("audio", {
+ direction: "recvonly"
+ });
+ Janus$1.log("Adding recvonly audio transceiver:", audioTransceiver);
+ }
+ }
+ } // Handle video (and related changes, if any)
+
+
+ var videoSend = isVideoSendEnabled(media);
+ var videoRecv = isVideoRecvEnabled(media);
+
+ if (!videoSend && !videoRecv) {
+ // Video disabled: have we removed it?
+ if (media.removeVideo && videoTransceiver) {
+ if (videoTransceiver.setDirection) {
+ videoTransceiver.setDirection("inactive");
+ } else {
+ videoTransceiver.direction = "inactive";
+ }
+
+ Janus$1.log("Setting video transceiver to inactive:", videoTransceiver);
+ }
+ } else {
+ // Take care of video m-line
+ if (videoSend && videoRecv) {
+ if (videoTransceiver) {
+ if (videoTransceiver.setDirection) {
+ videoTransceiver.setDirection("sendrecv");
+ } else {
+ videoTransceiver.direction = "sendrecv";
+ }
+
+ Janus$1.log("Setting video transceiver to sendrecv:", videoTransceiver);
+ }
+ } else if (videoSend && !videoRecv) {
+ if (videoTransceiver) {
+ if (videoTransceiver.setDirection) {
+ videoTransceiver.setDirection("sendonly");
+ } else {
+ videoTransceiver.direction = "sendonly";
+ }
+
+ Janus$1.log("Setting video transceiver to sendonly:", videoTransceiver);
+ }
+ } else if (!videoSend && videoRecv) {
+ if (videoTransceiver) {
+ if (videoTransceiver.setDirection) {
+ videoTransceiver.setDirection("recvonly");
+ } else {
+ videoTransceiver.direction = "recvonly";
+ }
+
+ Janus$1.log("Setting video transceiver to recvonly:", videoTransceiver);
+ } else {
+ // In theory, this is the only case where we might not have a transceiver yet
+ videoTransceiver = config.pc.addTransceiver("video", {
+ direction: "recvonly"
+ });
+ Janus$1.log("Adding recvonly video transceiver:", videoTransceiver);
+ }
+ }
+ }
+ } else {
+ mediaConstraints["offerToReceiveAudio"] = isAudioRecvEnabled(media);
+ mediaConstraints["offerToReceiveVideo"] = isVideoRecvEnabled(media);
+ }
+
+ var iceRestart = callbacks.iceRestart === true ? true : false;
+
+ if (iceRestart) {
+ mediaConstraints["iceRestart"] = true;
+ }
+
+ Janus$1.debug(mediaConstraints); // Check if this is Firefox and we've been asked to do simulcasting
+
+ var sendVideo = isVideoSendEnabled(media);
+
+ if (sendVideo && simulcast && Janus$1.webRTCAdapter.browserDetails.browser === "firefox") {
+ // FIXME Based on https://gist.github.com/voluntas/088bc3cc62094730647b
+ Janus$1.log("Enabling Simulcasting for Firefox (RID)");
+ var sender = config.pc.getSenders().find(function (s) {
+ return s.track.kind == "video";
+ });
+
+ if (sender) {
+ var parameters = sender.getParameters();
+ if (!parameters) parameters = {};
+ var maxBitrates = getMaxBitrates(callbacks.simulcastMaxBitrates);
+ parameters.encodings = [{
+ rid: "h",
+ active: true,
+ maxBitrate: maxBitrates.high
+ }, {
+ rid: "m",
+ active: true,
+ maxBitrate: maxBitrates.medium,
+ scaleResolutionDownBy: 2
+ }, {
+ rid: "l",
+ active: true,
+ maxBitrate: maxBitrates.low,
+ scaleResolutionDownBy: 4
+ }];
+ sender.setParameters(parameters);
+ }
+ }
+
+ config.pc.createOffer(mediaConstraints).then(function (offer) {
+ Janus$1.debug(offer); // JSON.stringify doesn't work on some WebRTC objects anymore
+ // See https://code.google.com/p/chromium/issues/detail?id=467366
+
+ var jsep = {
+ "type": offer.type,
+ "sdp": offer.sdp
+ };
+ callbacks.customizeSdp(jsep);
+ offer.sdp = jsep.sdp;
+ Janus$1.log("Setting local description");
+
+ if (sendVideo && simulcast) {
+ // This SDP munging only works with Chrome (Safari STP may support it too)
+ if (Janus$1.webRTCAdapter.browserDetails.browser === "chrome" || Janus$1.webRTCAdapter.browserDetails.browser === "safari") {
+ Janus$1.log("Enabling Simulcasting for Chrome (SDP munging)");
+ offer.sdp = mungeSdpForSimulcasting(offer.sdp);
+ } else if (Janus$1.webRTCAdapter.browserDetails.browser !== "firefox") {
+ Janus$1.warn("simulcast=true, but this is not Chrome nor Firefox, ignoring");
+ }
+ }
+
+ config.mySdp = offer.sdp;
+ config.pc.setLocalDescription(offer)["catch"](callbacks.error);
+ config.mediaConstraints = mediaConstraints;
+
+ if (!config.iceDone && !config.trickle) {
+ // Don't do anything until we have all candidates
+ Janus$1.log("Waiting for all candidates...");
+ return;
+ }
+
+ Janus$1.log("Offer ready");
+ Janus$1.debug(callbacks);
+ callbacks.success(offer);
+ }, callbacks.error);
+ }
+
+ function createAnswer(handleId, media, callbacks) {
+ callbacks = callbacks || {};
+ callbacks.success = typeof callbacks.success == "function" ? callbacks.success : Janus$1.noop;
+ callbacks.error = typeof callbacks.error == "function" ? callbacks.error : Janus$1.noop;
+ callbacks.customizeSdp = typeof callbacks.customizeSdp == "function" ? callbacks.customizeSdp : Janus$1.noop;
+ var pluginHandle = pluginHandles[handleId];
+
+ if (pluginHandle === null || pluginHandle === undefined || pluginHandle.webrtcStuff === null || pluginHandle.webrtcStuff === undefined) {
+ Janus$1.warn("Invalid handle");
+ callbacks.error("Invalid handle");
+ return;
+ }
+
+ var config = pluginHandle.webrtcStuff;
+ var simulcast = callbacks.simulcast === true ? true : false;
+
+ if (!simulcast) {
+ Janus$1.log("Creating answer (iceDone=" + config.iceDone + ")");
+ } else {
+ Janus$1.log("Creating answer (iceDone=" + config.iceDone + ", simulcast=" + simulcast + ")");
+ }
+
+ var mediaConstraints = null;
+
+ if (Janus$1.unifiedPlan) {
+ // We can use Transceivers
+ mediaConstraints = {};
+ var audioTransceiver = null,
+ videoTransceiver = null;
+ var transceivers = config.pc.getTransceivers();
+
+ if (transceivers && transceivers.length > 0) {
+ for (var i in transceivers) {
+ var t = transceivers[i];
+
+ if (t.sender && t.sender.track && t.sender.track.kind === "audio" || t.receiver && t.receiver.track && t.receiver.track.kind === "audio") {
+ if (!audioTransceiver) audioTransceiver = t;
+ continue;
+ }
+
+ if (t.sender && t.sender.track && t.sender.track.kind === "video" || t.receiver && t.receiver.track && t.receiver.track.kind === "video") {
+ if (!videoTransceiver) videoTransceiver = t;
+ continue;
+ }
+ }
+ } // Handle audio (and related changes, if any)
+
+
+ var audioSend = isAudioSendEnabled(media);
+ var audioRecv = isAudioRecvEnabled(media);
+
+ if (!audioSend && !audioRecv) {
+ // Audio disabled: have we removed it?
+ if (media.removeAudio && audioTransceiver) {
+ try {
+ if (audioTransceiver.setDirection) {
+ audioTransceiver.setDirection("inactive");
+ } else {
+ audioTransceiver.direction = "inactive";
+ }
+
+ Janus$1.log("Setting audio transceiver to inactive:", audioTransceiver);
+ } catch (e) {
+ Janus$1.error(e);
+ }
+ }
+ } else {
+ // Take care of audio m-line
+ if (audioSend && audioRecv) {
+ if (audioTransceiver) {
+ try {
+ if (audioTransceiver.setDirection) {
+ audioTransceiver.setDirection("sendrecv");
+ } else {
+ audioTransceiver.direction = "sendrecv";
+ }
+
+ Janus$1.log("Setting audio transceiver to sendrecv:", audioTransceiver);
+ } catch (e) {
+ Janus$1.error(e);
+ }
+ }
+ } else if (audioSend && !audioRecv) {
+ try {
+ if (audioTransceiver) {
+ if (audioTransceiver.setDirection) {
+ audioTransceiver.setDirection("sendonly");
+ } else {
+ audioTransceiver.direction = "sendonly";
+ }
+
+ Janus$1.log("Setting audio transceiver to sendonly:", audioTransceiver);
+ }
+ } catch (e) {
+ Janus$1.error(e);
+ }
+ } else if (!audioSend && audioRecv) {
+ if (audioTransceiver) {
+ try {
+ if (audioTransceiver.setDirection) {
+ audioTransceiver.setDirection("recvonly");
+ } else {
+ audioTransceiver.direction = "recvonly";
+ }
+
+ Janus$1.log("Setting audio transceiver to recvonly:", audioTransceiver);
+ } catch (e) {
+ Janus$1.error(e);
+ }
+ } else {
+ // In theory, this is the only case where we might not have a transceiver yet
+ audioTransceiver = config.pc.addTransceiver("audio", {
+ direction: "recvonly"
+ });
+ Janus$1.log("Adding recvonly audio transceiver:", audioTransceiver);
+ }
+ }
+ } // Handle video (and related changes, if any)
+
+
+ var videoSend = isVideoSendEnabled(media);
+ var videoRecv = isVideoRecvEnabled(media);
+
+ if (!videoSend && !videoRecv) {
+ // Video disabled: have we removed it?
+ if (media.removeVideo && videoTransceiver) {
+ try {
+ if (videoTransceiver.setDirection) {
+ videoTransceiver.setDirection("inactive");
+ } else {
+ videoTransceiver.direction = "inactive";
+ }
+
+ Janus$1.log("Setting video transceiver to inactive:", videoTransceiver);
+ } catch (e) {
+ Janus$1.error(e);
+ }
+ }
+ } else {
+ // Take care of video m-line
+ if (videoSend && videoRecv) {
+ if (videoTransceiver) {
+ try {
+ if (videoTransceiver.setDirection) {
+ videoTransceiver.setDirection("sendrecv");
+ } else {
+ videoTransceiver.direction = "sendrecv";
+ }
+
+ Janus$1.log("Setting video transceiver to sendrecv:", videoTransceiver);
+ } catch (e) {
+ Janus$1.error(e);
+ }
+ }
+ } else if (videoSend && !videoRecv) {
+ if (videoTransceiver) {
+ try {
+ if (videoTransceiver.setDirection) {
+ videoTransceiver.setDirection("sendonly");
+ } else {
+ videoTransceiver.direction = "sendonly";
+ }
+
+ Janus$1.log("Setting video transceiver to sendonly:", videoTransceiver);
+ } catch (e) {
+ Janus$1.error(e);
+ }
+ }
+ } else if (!videoSend && videoRecv) {
+ if (videoTransceiver) {
+ try {
+ if (videoTransceiver.setDirection) {
+ videoTransceiver.setDirection("recvonly");
+ } else {
+ videoTransceiver.direction = "recvonly";
+ }
+
+ Janus$1.log("Setting video transceiver to recvonly:", videoTransceiver);
+ } catch (e) {
+ Janus$1.error(e);
+ }
+ } else {
+ // In theory, this is the only case where we might not have a transceiver yet
+ videoTransceiver = config.pc.addTransceiver("video", {
+ direction: "recvonly"
+ });
+ Janus$1.log("Adding recvonly video transceiver:", videoTransceiver);
+ }
+ }
+ }
+ } else {
+ if (Janus$1.webRTCAdapter.browserDetails.browser == "firefox" || Janus$1.webRTCAdapter.browserDetails.browser == "edge") {
+ mediaConstraints = {
+ offerToReceiveAudio: isAudioRecvEnabled(media),
+ offerToReceiveVideo: isVideoRecvEnabled(media)
+ };
+ } else {
+ mediaConstraints = {
+ mandatory: {
+ OfferToReceiveAudio: isAudioRecvEnabled(media),
+ OfferToReceiveVideo: isVideoRecvEnabled(media)
+ }
+ };
+ }
+ }
+
+ Janus$1.debug(mediaConstraints); // Check if this is Firefox and we've been asked to do simulcasting
+
+ var sendVideo = isVideoSendEnabled(media);
+
+ if (sendVideo && simulcast && Janus$1.webRTCAdapter.browserDetails.browser === "firefox") {
+ // FIXME Based on https://gist.github.com/voluntas/088bc3cc62094730647b
+ Janus$1.log("Enabling Simulcasting for Firefox (RID)");
+ var sender = config.pc.getSenders()[1];
+ Janus$1.log(sender);
+ var parameters = sender.getParameters();
+ Janus$1.log(parameters);
+ var maxBitrates = getMaxBitrates(callbacks.simulcastMaxBitrates);
+ sender.setParameters({
+ encodings: [{
+ rid: "high",
+ active: true,
+ priority: "high",
+ maxBitrate: maxBitrates.high
+ }, {
+ rid: "medium",
+ active: true,
+ priority: "medium",
+ maxBitrate: maxBitrates.medium
+ }, {
+ rid: "low",
+ active: true,
+ priority: "low",
+ maxBitrate: maxBitrates.low
+ }]
+ });
+ }
+
+ config.pc.createAnswer(mediaConstraints).then(function (answer) {
+ Janus$1.debug(answer); // JSON.stringify doesn't work on some WebRTC objects anymore
+ // See https://code.google.com/p/chromium/issues/detail?id=467366
+
+ var jsep = {
+ "type": answer.type,
+ "sdp": answer.sdp
+ };
+ callbacks.customizeSdp(jsep);
+ answer.sdp = jsep.sdp;
+ Janus$1.log("Setting local description");
+
+ if (sendVideo && simulcast) {
+ // This SDP munging only works with Chrome
+ if (Janus$1.webRTCAdapter.browserDetails.browser === "chrome") {
+ // FIXME Apparently trying to simulcast when answering breaks video in Chrome...
+ //~ Janus.log("Enabling Simulcasting for Chrome (SDP munging)");
+ //~ answer.sdp = mungeSdpForSimulcasting(answer.sdp);
+ Janus$1.warn("simulcast=true, but this is an answer, and video breaks in Chrome if we enable it");
+ } else if (Janus$1.webRTCAdapter.browserDetails.browser !== "firefox") {
+ Janus$1.warn("simulcast=true, but this is not Chrome nor Firefox, ignoring");
+ }
+ }
+
+ config.mySdp = answer.sdp;
+ config.pc.setLocalDescription(answer)["catch"](callbacks.error);
+ config.mediaConstraints = mediaConstraints;
+
+ if (!config.iceDone && !config.trickle) {
+ // Don't do anything until we have all candidates
+ Janus$1.log("Waiting for all candidates...");
+ return;
+ }
+
+ callbacks.success(answer);
+ }, callbacks.error);
+ }
+
+ function sendSDP(handleId, callbacks) {
+ callbacks = callbacks || {};
+ callbacks.success = typeof callbacks.success == "function" ? callbacks.success : Janus$1.noop;
+ callbacks.error = typeof callbacks.error == "function" ? callbacks.error : Janus$1.noop;
+ var pluginHandle = pluginHandles[handleId];
+
+ if (pluginHandle === null || pluginHandle === undefined || pluginHandle.webrtcStuff === null || pluginHandle.webrtcStuff === undefined) {
+ Janus$1.warn("Invalid handle, not sending anything");
+ return;
+ }
+
+ var config = pluginHandle.webrtcStuff;
+ Janus$1.log("Sending offer/answer SDP...");
+
+ if (config.mySdp === null || config.mySdp === undefined) {
+ Janus$1.warn("Local SDP instance is invalid, not sending anything...");
+ return;
+ }
+
+ config.mySdp = {
+ "type": config.pc.localDescription.type,
+ "sdp": config.pc.localDescription.sdp
+ };
+ if (config.trickle === false) config.mySdp["trickle"] = false;
+ Janus$1.debug(callbacks);
+ config.sdpSent = true;
+ callbacks.success(config.mySdp);
+ }
+
+ function _getVolume(handleId, remote) {
+ var pluginHandle = pluginHandles[handleId];
+
+ if (pluginHandle === null || pluginHandle === undefined || pluginHandle.webrtcStuff === null || pluginHandle.webrtcStuff === undefined) {
+ Janus$1.warn("Invalid handle");
+ return 0;
+ }
+
+ var stream = remote ? "remote" : "local";
+ var config = pluginHandle.webrtcStuff;
+ if (!config.volume[stream]) config.volume[stream] = {
+ value: 0
+ }; // Start getting the volume, if getStats is supported
+
+ if (config.pc.getStats && Janus$1.webRTCAdapter.browserDetails.browser === "chrome") {
+ if (remote && (config.remoteStream === null || config.remoteStream === undefined)) {
+ Janus$1.warn("Remote stream unavailable");
+ return 0;
+ } else if (!remote && (config.myStream === null || config.myStream === undefined)) {
+ Janus$1.warn("Local stream unavailable");
+ return 0;
+ }
+
+ if (config.volume[stream].timer === null || config.volume[stream].timer === undefined) {
+ Janus$1.log("Starting " + stream + " volume monitor");
+ config.volume[stream].timer = setInterval(function () {
+ config.pc.getStats(function (stats) {
+ var results = stats.result();
+
+ for (var i = 0; i < results.length; i++) {
+ var res = results[i];
+
+ if (res.type == 'ssrc') {
+ if (remote && res.stat('audioOutputLevel')) config.volume[stream].value = parseInt(res.stat('audioOutputLevel'));else if (!remote && res.stat('audioInputLevel')) config.volume[stream].value = parseInt(res.stat('audioInputLevel'));
+ }
+ }
+ });
+ }, 200);
+ return 0; // We don't have a volume to return yet
+ }
+
+ return config.volume[stream].value;
+ } else {
+ // audioInputLevel and audioOutputLevel seem only available in Chrome? audioLevel
+ // seems to be available on Chrome and Firefox, but they don't seem to work
+ Janus$1.warn("Getting the " + stream + " volume unsupported by browser");
+ return 0;
+ }
+ }
+
+ function isMuted(handleId, video) {
+ var pluginHandle = pluginHandles[handleId];
+
+ if (pluginHandle === null || pluginHandle === undefined || pluginHandle.webrtcStuff === null || pluginHandle.webrtcStuff === undefined) {
+ Janus$1.warn("Invalid handle");
+ return true;
+ }
+
+ var config = pluginHandle.webrtcStuff;
+
+ if (config.pc === null || config.pc === undefined) {
+ Janus$1.warn("Invalid PeerConnection");
+ return true;
+ }
+
+ if (config.myStream === undefined || config.myStream === null) {
+ Janus$1.warn("Invalid local MediaStream");
+ return true;
+ }
+
+ if (video) {
+ // Check video track
+ if (config.myStream.getVideoTracks() === null || config.myStream.getVideoTracks() === undefined || config.myStream.getVideoTracks().length === 0) {
+ Janus$1.warn("No video track");
+ return true;
+ }
+
+ return !config.myStream.getVideoTracks()[0].enabled;
+ } else {
+ // Check audio track
+ if (config.myStream.getAudioTracks() === null || config.myStream.getAudioTracks() === undefined || config.myStream.getAudioTracks().length === 0) {
+ Janus$1.warn("No audio track");
+ return true;
+ }
+
+ return !config.myStream.getAudioTracks()[0].enabled;
+ }
+ }
+
+ function mute(handleId, video, mute) {
+ var pluginHandle = pluginHandles[handleId];
+
+ if (pluginHandle === null || pluginHandle === undefined || pluginHandle.webrtcStuff === null || pluginHandle.webrtcStuff === undefined) {
+ Janus$1.warn("Invalid handle");
+ return false;
+ }
+
+ var config = pluginHandle.webrtcStuff;
+
+ if (config.pc === null || config.pc === undefined) {
+ Janus$1.warn("Invalid PeerConnection");
+ return false;
+ }
+
+ if (config.myStream === undefined || config.myStream === null) {
+ Janus$1.warn("Invalid local MediaStream");
+ return false;
+ }
+
+ if (video) {
+ // Mute/unmute video track
+ if (config.myStream.getVideoTracks() === null || config.myStream.getVideoTracks() === undefined || config.myStream.getVideoTracks().length === 0) {
+ Janus$1.warn("No video track");
+ return false;
+ }
+
+ config.myStream.getVideoTracks()[0].enabled = mute ? false : true;
+ return true;
+ } else {
+ // Mute/unmute audio track
+ if (config.myStream.getAudioTracks() === null || config.myStream.getAudioTracks() === undefined || config.myStream.getAudioTracks().length === 0) {
+ Janus$1.warn("No audio track");
+ return false;
+ }
+
+ config.myStream.getAudioTracks()[0].enabled = mute ? false : true;
+ return true;
+ }
+ }
+
+ function _getBitrate(handleId) {
+ var pluginHandle = pluginHandles[handleId];
+
+ if (pluginHandle === null || pluginHandle === undefined || pluginHandle.webrtcStuff === null || pluginHandle.webrtcStuff === undefined) {
+ Janus$1.warn("Invalid handle");
+ return "Invalid handle";
+ }
+
+ var config = pluginHandle.webrtcStuff;
+ if (config.pc === null || config.pc === undefined) return "Invalid PeerConnection"; // Start getting the bitrate, if getStats is supported
+
+ if (config.pc.getStats) {
+ if (config.bitrate.timer === null || config.bitrate.timer === undefined) {
+ Janus$1.log("Starting bitrate timer (via getStats)");
+ config.bitrate.timer = setInterval(function () {
+ config.pc.getStats().then(function (stats) {
+ stats.forEach(function (res) {
+ if (!res) return;
+ var inStats = false; // Check if these are statistics on incoming media
+
+ if ((res.mediaType === "video" || res.id.toLowerCase().indexOf("video") > -1) && res.type === "inbound-rtp" && res.id.indexOf("rtcp") < 0) {
+ // New stats
+ inStats = true;
+ } else if (res.type == 'ssrc' && res.bytesReceived && (res.googCodecName === "VP8" || res.googCodecName === "")) {
+ // Older Chromer versions
+ inStats = true;
+ } // Parse stats now
+
+
+ if (inStats) {
+ config.bitrate.bsnow = res.bytesReceived;
+ config.bitrate.tsnow = res.timestamp;
+
+ if (config.bitrate.bsbefore === null || config.bitrate.tsbefore === null) {
+ // Skip this round
+ config.bitrate.bsbefore = config.bitrate.bsnow;
+ config.bitrate.tsbefore = config.bitrate.tsnow;
+ } else {
+ // Calculate bitrate
+ var timePassed = config.bitrate.tsnow - config.bitrate.tsbefore;
+ if (Janus$1.webRTCAdapter.browserDetails.browser == "safari") timePassed = timePassed / 1000; // Apparently the timestamp is in microseconds, in Safari
+
+ var bitRate = Math.round((config.bitrate.bsnow - config.bitrate.bsbefore) * 8 / timePassed);
+ if (Janus$1.webRTCAdapter.browserDetails.browser === 'safari') bitRate = parseInt(bitRate / 1000);
+ config.bitrate.value = bitRate + ' kbits/sec'; //~ Janus.log("Estimated bitrate is " + config.bitrate.value);
+
+ config.bitrate.bsbefore = config.bitrate.bsnow;
+ config.bitrate.tsbefore = config.bitrate.tsnow;
+ }
+ }
+ });
+ });
+ }, 1000);
+ return "0 kbits/sec"; // We don't have a bitrate value yet
+ }
+
+ return config.bitrate.value;
+ } else {
+ Janus$1.warn("Getting the video bitrate unsupported by browser");
+ return "Feature unsupported by browser";
+ }
+ }
+
+ function webrtcError(error) {
+ Janus$1.error("WebRTC error:", error);
+ }
+
+ function cleanupWebrtc(handleId, hangupRequest) {
+ Janus$1.log("Cleaning WebRTC stuff");
+ var pluginHandle = pluginHandles[handleId];
+
+ if (pluginHandle === null || pluginHandle === undefined) {
+ // Nothing to clean
+ return;
+ }
+
+ var config = pluginHandle.webrtcStuff;
+
+ if (config !== null && config !== undefined) {
+ if (hangupRequest === true) {
+ // Send a hangup request (we don't really care about the response)
+ var request = {
+ "rtcgw": "hangup",
+ "transaction": Janus$1.randomString(12)
+ };
+ if (pluginHandle.token !== null && pluginHandle.token !== undefined) request["token"] = pluginHandle.token;
+ if (apisecret !== null && apisecret !== undefined) request["apisecret"] = apisecret;
+ Janus$1.debug("Sending hangup request (handle=" + handleId + "):");
+ Janus$1.debug(request);
+
+ if (websockets) {
+ request["session_id"] = sessionId;
+ request["handle_id"] = handleId;
+ ws.send(JSON.stringify(request));
+ } else {
+ Janus$1.httpAPICall(server + "/" + sessionId + "/" + handleId, {
+ verb: 'POST',
+ withCredentials: withCredentials,
+ body: request
+ });
+ }
+ } // Cleanup stack
+
+
+ config.remoteStream = null;
+
+ if (config.volume) {
+ if (config.volume["local"] && config.volume["local"].timer) clearInterval(config.volume["local"].timer);
+ if (config.volume["remote"] && config.volume["remote"].timer) clearInterval(config.volume["remote"].timer);
+ }
+
+ config.volume = {};
+ if (config.bitrate.timer) clearInterval(config.bitrate.timer);
+ config.bitrate.timer = null;
+ config.bitrate.bsnow = null;
+ config.bitrate.bsbefore = null;
+ config.bitrate.tsnow = null;
+ config.bitrate.tsbefore = null;
+ config.bitrate.value = null;
+
+ try {
+ // Try a MediaStreamTrack.stop() for each track
+ if (!config.streamExternal && config.myStream !== null && config.myStream !== undefined) {
+ Janus$1.log("Stopping local stream tracks");
+ var tracks = config.myStream.getTracks();
+
+ for (var i in tracks) {
+ var mst = tracks[i];
+ Janus$1.log(mst);
+ if (mst !== null && mst !== undefined) mst.stop();
+ }
+ }
+ } catch (e) {// Do nothing if this fails
+ }
+
+ config.streamExternal = false;
+ config.myStream = null; // Close PeerConnection
+
+ try {
+ config.pc.close();
+ } catch (e) {// Do nothing
+ }
+
+ config.pc = null;
+ config.candidates = null;
+ config.mySdp = null;
+ config.remoteSdp = null;
+ config.iceDone = false;
+ config.dataChannel = {};
+ config.dtmfSender = null;
+ }
+
+ pluginHandle.oncleanup();
+ } // Helper method to munge an SDP to enable simulcasting (Chrome only)
+
+
+ function mungeSdpForSimulcasting(sdp) {
+ // Let's munge the SDP to add the attributes for enabling simulcasting
+ // (based on https://gist.github.com/ggarber/a19b4c33510028b9c657)
+ var lines = sdp.split("\r\n");
+ var video = false;
+ var ssrc = [-1],
+ ssrc_fid = [-1];
+ var cname = null,
+ msid = null,
+ mslabel = null,
+ label = null;
+ var insertAt = -1;
+
+ for (var i = 0; i < lines.length; i++) {
+ var mline = lines[i].match(/m=(\w+) */);
+
+ if (mline) {
+ var medium = mline[1];
+
+ if (medium === "video") {
+ // New video m-line: make sure it's the first one
+ if (ssrc[0] < 0) {
+ video = true;
+ } else {
+ // We're done, let's add the new attributes here
+ insertAt = i;
+ break;
+ }
+ } else {
+ // New non-video m-line: do we have what we were looking for?
+ if (ssrc[0] > -1) {
+ // We're done, let's add the new attributes here
+ insertAt = i;
+ break;
+ }
+ }
+
+ continue;
+ }
+
+ if (!video) continue;
+ var fid = lines[i].match(/a=ssrc-group:FID (\d+) (\d+)/);
+
+ if (fid) {
+ ssrc[0] = fid[1];
+ ssrc_fid[0] = fid[2];
+ lines.splice(i, 1);
+ i--;
+ continue;
+ }
+
+ if (ssrc[0]) {
+ var match = lines[i].match('a=ssrc:' + ssrc[0] + ' cname:(.+)');
+
+ if (match) {
+ cname = match[1];
+ }
+
+ match = lines[i].match('a=ssrc:' + ssrc[0] + ' msid:(.+)');
+
+ if (match) {
+ msid = match[1];
+ }
+
+ match = lines[i].match('a=ssrc:' + ssrc[0] + ' mslabel:(.+)');
+
+ if (match) {
+ mslabel = match[1];
+ }
+
+ match = lines[i].match('a=ssrc:' + ssrc[0] + ' label:(.+)');
+
+ if (match) {
+ label = match[1];
+ }
+
+ if (lines[i].indexOf('a=ssrc:' + ssrc_fid[0]) === 0) {
+ lines.splice(i, 1);
+ i--;
+ continue;
+ }
+
+ if (lines[i].indexOf('a=ssrc:' + ssrc[0]) === 0) {
+ lines.splice(i, 1);
+ i--;
+ continue;
+ }
+ }
+
+ if (lines[i].length == 0) {
+ lines.splice(i, 1);
+ i--;
+ continue;
+ }
+ }
+
+ if (ssrc[0] < 0) {
+ // Couldn't find a FID attribute, let's just take the first video SSRC we find
+ insertAt = -1;
+ video = false;
+
+ for (var i = 0; i < lines.length; i++) {
+ var mline = lines[i].match(/m=(\w+) */);
+
+ if (mline) {
+ var medium = mline[1];
+
+ if (medium === "video") {
+ // New video m-line: make sure it's the first one
+ if (ssrc[0] < 0) {
+ video = true;
+ } else {
+ // We're done, let's add the new attributes here
+ insertAt = i;
+ break;
+ }
+ } else {
+ // New non-video m-line: do we have what we were looking for?
+ if (ssrc[0] > -1) {
+ // We're done, let's add the new attributes here
+ insertAt = i;
+ break;
+ }
+ }
+
+ continue;
+ }
+
+ if (!video) continue;
+
+ if (ssrc[0] < 0) {
+ var value = lines[i].match(/a=ssrc:(\d+)/);
+
+ if (value) {
+ ssrc[0] = value[1];
+ lines.splice(i, 1);
+ i--;
+ continue;
+ }
+ } else {
+ var match = lines[i].match('a=ssrc:' + ssrc[0] + ' cname:(.+)');
+
+ if (match) {
+ cname = match[1];
+ }
+
+ match = lines[i].match('a=ssrc:' + ssrc[0] + ' msid:(.+)');
+
+ if (match) {
+ msid = match[1];
+ }
+
+ match = lines[i].match('a=ssrc:' + ssrc[0] + ' mslabel:(.+)');
+
+ if (match) {
+ mslabel = match[1];
+ }
+
+ match = lines[i].match('a=ssrc:' + ssrc[0] + ' label:(.+)');
+
+ if (match) {
+ label = match[1];
+ }
+
+ if (lines[i].indexOf('a=ssrc:' + ssrc_fid[0]) === 0) {
+ lines.splice(i, 1);
+ i--;
+ continue;
+ }
+
+ if (lines[i].indexOf('a=ssrc:' + ssrc[0]) === 0) {
+ lines.splice(i, 1);
+ i--;
+ continue;
+ }
+ }
+
+ if (lines[i].length == 0) {
+ lines.splice(i, 1);
+ i--;
+ continue;
+ }
+ }
+ }
+
+ if (ssrc[0] < 0) {
+ // Still nothing, let's just return the SDP we were asked to munge
+ Janus$1.warn("Couldn't find the video SSRC, simulcasting NOT enabled");
+ return sdp;
+ }
+
+ if (insertAt < 0) {
+ // Append at the end
+ insertAt = lines.length;
+ } // Generate a couple of SSRCs (for retransmissions too)
+ // Note: should we check if there are conflicts, here?
+
+
+ ssrc[1] = Math.floor(Math.random() * 0xFFFFFFFF);
+ ssrc[2] = Math.floor(Math.random() * 0xFFFFFFFF);
+ ssrc_fid[1] = Math.floor(Math.random() * 0xFFFFFFFF);
+ ssrc_fid[2] = Math.floor(Math.random() * 0xFFFFFFFF); // Add attributes to the SDP
+
+ for (var i = 0; i < ssrc.length; i++) {
+ if (cname) {
+ lines.splice(insertAt, 0, 'a=ssrc:' + ssrc[i] + ' cname:' + cname);
+ insertAt++;
+ }
+
+ if (msid) {
+ lines.splice(insertAt, 0, 'a=ssrc:' + ssrc[i] + ' msid:' + msid);
+ insertAt++;
+ }
+
+ if (mslabel) {
+ lines.splice(insertAt, 0, 'a=ssrc:' + ssrc[i] + ' mslabel:' + mslabel);
+ insertAt++;
+ }
+
+ if (label) {
+ lines.splice(insertAt, 0, 'a=ssrc:' + ssrc[i] + ' label:' + label);
+ insertAt++;
+ } // Add the same info for the retransmission SSRC
+
+
+ if (cname) {
+ lines.splice(insertAt, 0, 'a=ssrc:' + ssrc_fid[i] + ' cname:' + cname);
+ insertAt++;
+ }
+
+ if (msid) {
+ lines.splice(insertAt, 0, 'a=ssrc:' + ssrc_fid[i] + ' msid:' + msid);
+ insertAt++;
+ }
+
+ if (mslabel) {
+ lines.splice(insertAt, 0, 'a=ssrc:' + ssrc_fid[i] + ' mslabel:' + mslabel);
+ insertAt++;
+ }
+
+ if (label) {
+ lines.splice(insertAt, 0, 'a=ssrc:' + ssrc_fid[i] + ' label:' + label);
+ insertAt++;
+ }
+ }
+
+ lines.splice(insertAt, 0, 'a=ssrc-group:FID ' + ssrc[2] + ' ' + ssrc_fid[2]);
+ lines.splice(insertAt, 0, 'a=ssrc-group:FID ' + ssrc[1] + ' ' + ssrc_fid[1]);
+ lines.splice(insertAt, 0, 'a=ssrc-group:FID ' + ssrc[0] + ' ' + ssrc_fid[0]);
+ lines.splice(insertAt, 0, 'a=ssrc-group:SIM ' + ssrc[0] + ' ' + ssrc[1] + ' ' + ssrc[2]);
+ sdp = lines.join("\r\n");
+ if (!sdp.endsWith("\r\n")) sdp += "\r\n";
+ return sdp;
+ } // Helper methods to parse a media object
+
+
+ function isAudioSendEnabled(media) {
+ Janus$1.debug("isAudioSendEnabled:", media);
+ if (media === undefined || media === null) return true; // Default
+
+ if (media.audio === false) return false; // Generic audio has precedence
+
+ if (media.audioSend === undefined || media.audioSend === null) return true; // Default
+
+ return media.audioSend === true;
+ }
+
+ function isAudioSendRequired(media) {
+ Janus$1.debug("isAudioSendRequired:", media);
+ if (media === undefined || media === null) return false; // Default
+
+ if (media.audio === false || media.audioSend === false) return false; // If we're not asking to capture audio, it's not required
+
+ if (media.failIfNoAudio === undefined || media.failIfNoAudio === null) return false; // Default
+
+ return media.failIfNoAudio === true;
+ }
+
+ function isAudioRecvEnabled(media) {
+ Janus$1.debug("isAudioRecvEnabled:", media);
+ if (media === undefined || media === null) return true; // Default
+
+ if (media.audio === false) return false; // Generic audio has precedence
+
+ if (media.audioRecv === undefined || media.audioRecv === null) return true; // Default
+
+ return media.audioRecv === true;
+ }
+
+ function isVideoSendEnabled(media) {
+ Janus$1.debug("isVideoSendEnabled:", media);
+ if (media === undefined || media === null) return true; // Default
+
+ if (media.video === false) return false; // Generic video has precedence
+
+ if (media.videoSend === undefined || media.videoSend === null) return true; // Default
+
+ return media.videoSend === true;
+ }
+
+ function isVideoSendRequired(media) {
+ Janus$1.debug("isVideoSendRequired:", media);
+ if (media === undefined || media === null) return false; // Default
+
+ if (media.video === false || media.videoSend === false) return false; // If we're not asking to capture video, it's not required
+
+ if (media.failIfNoVideo === undefined || media.failIfNoVideo === null) return false; // Default
+
+ return media.failIfNoVideo === true;
+ }
+
+ function isVideoRecvEnabled(media) {
+ Janus$1.debug("isVideoRecvEnabled:", media);
+ if (media === undefined || media === null) return true; // Default
+
+ if (media.video === false) return false; // Generic video has precedence
+
+ if (media.videoRecv === undefined || media.videoRecv === null) return true; // Default
+
+ return media.videoRecv === true;
+ }
+
+ function isScreenSendEnabled(media) {
+ Janus$1.debug("isScreenSendEnabled:", media);
+ if (media === undefined || media === null) return false;
+ if (_typeof(media.video) !== 'object' || _typeof(media.video.mandatory) !== 'object') return false;
+ var constraints = media.video.mandatory;
+ if (constraints.chromeMediaSource) return constraints.chromeMediaSource === 'desktop' || constraints.chromeMediaSource === 'screen';else if (constraints.mozMediaSource) return constraints.mozMediaSource === 'window' || constraints.mozMediaSource === 'screen';else if (constraints.mediaSource) return constraints.mediaSource === 'window' || constraints.mediaSource === 'screen';
+ return false;
+ }
+
+ function isDataEnabled(media) {
+ Janus$1.debug("isDataEnabled:", media);
+
+ if (Janus$1.webRTCAdapter.browserDetails.browser == "edge") {
+ Janus$1.warn("Edge doesn't support data channels yet");
+ return false;
+ }
+
+ if (media === undefined || media === null) return false; // Default
+
+ return media.data === true;
+ }
+
+ function isTrickleEnabled(trickle) {
+ Janus$1.debug("isTrickleEnabled:", trickle);
+ if (trickle === undefined || trickle === null) return true; // Default is true
+
+ return trickle === true;
+ }
+}
+window.Janus = Janus$1;
+
+// We make use of this 'server' variable to provide the address of the
+var janus = null;
+var tts = null;
+var opaqueId = "tts-" + Janus.randomString(12);
+var spinner = null;
+Janus = window.Janus; // Initialize the library (all console debuggers enabled)
+
+Janus.init({
+ debug: "all",
+ callback: function callback() {
+ window.stopTalk = function () {
+ janus.destroy();
+ }; // debugger;
+
+
+ window.startTalk = function () {
+ // Make sure the browser supports WebRTC
+ if (!Janus.isWebrtcSupported()) {
+ bootbox.alert("No WebRTC support... ");
+ return;
+ } // if($('#tts_url').val().length == 0){
+ // bootbox.alert("Please input tts url... ");
+ // return;
+ // }
+ // $(this).attr('disabled', true).unbind('click');
+ // Create session
+
+
+ janus = new Janus({
+ server: window.EZUIKit.opt.rtcUrl,
+ // No "iceServers" is provided, meaning janus.js will use a default STUN server
+ // Here are some examples of how an iceServers field may look like to support TURN
+ // iceServers: [{urls: "turn:yourturnserver.com:3478", username: "janususer", credential: "januspwd"}],
+ // iceServers: [{urls: "turn:yourturnserver.com:443?transport=tcp", username: "janususer", credential: "januspwd"}],
+ // iceServers: [{urls: "turns:yourturnserver.com:443?transport=tcp", username: "janususer", credential: "januspwd"}],
+ // Should the Janus API require authentication, you can specify either the API secret or user token here too
+ // token: "mytoken",
+ // or
+ // apisecret: "serversecret",
+ success: function success() {
+ // Attach to tts plugin
+ janus.attach({
+ plugin: "rtcgw.plugin.tts",
+ opaqueId: opaqueId,
+ success: function success(pluginHandle) {
+ // $('#details').remove();
+ tts = pluginHandle;
+ Janus.log("Plugin attached! (" + tts.getPlugin() + ", id=" + tts.getId() + ")"); // Negotiate WebRTC
+ //var url = "tts://61.130.6.23:8664/talk://D13781761:0:1:cas.ys7.com:6500?97fbd2a75fa94b7682c994d3d1fac8ca:ut.5porslgu79e9r7ca48z32k8abgl3rp58-77bhb6i7xr-1kmumtg-jkhy7pvfr:0:3"
+ //var url = "tts://10.86.15.209:8664/talk://D13781761:0:1:cas.ys7.com:6500?32db2578ba7c4a84be22ecc0bcd0f8db:ut.5lqpkhim5m7cdk2y5w60g7hm9vd7i3v0-3d2pwhxe2t-11wx2ge-sh4yazbll:0:3"
+ //var url = "tts://10.86.15.209:8664/talk://D13781761:0:1:cas.ys7.com:6500"
+ //test12.ys.com
+ //var url = "tts://10.86.15.209:8664/talk://D08197169:0:1:cas.ys7.com:6500"
+ //test10.ys.com
+ //var url = "tts://10.86.29.210:8664/talk://D08197169:0:1:cas.ys7.com:6500"
+
+ var url = window.EZUIKit.opt.talkLink;
+ console.log("ttsUlr", url);
+ var body = {
+ "request": "start",
+ "url": url,
+ "codec": "opus",
+ "dir": "sendrecv",
+ "audio_debug": 1
+ };
+
+ if (window.EZUIKit.opt.talkType === 'gb28181') {
+ body['devProto'] = 'gb28181';
+ } //tts.send({"message": body});
+
+
+ Janus.debug("Trying a createOffer too (audio/video sendrecv)");
+ tts.createOffer({
+ // No media provided: by default, it's sendrecv for audio and video
+ media: {
+ audio: true,
+ video: false,
+ data: false
+ },
+ // Audio only
+ // If you want to test simulcasting (Chrome and Firefox only), then
+ // pass a ?simulcast=true when opening this demo page: it will turn
+ // the following 'simulcast' property to pass to janus.js to true
+ simulcast: false,
+ simulcast2: false,
+ success: function success(jsep) {
+ Janus.debug("Got SDP!");
+ Janus.debug(jsep);
+ tts.send({
+ "message": body,
+ "jsep": jsep
+ });
+
+ if (typeof window.EZUIKit.handleTalkSuccess !== 'undefined') {
+ window.EZUIKit.handleTalkSuccess();
+ }
+ },
+ error: function error(_error) {
+ Janus.error("WebRTC error:", _error); // bootbox.alert("WebRTC error... " + JSON.stringify(error));
+
+ if (typeof window.EZUIKit.handleTalkError !== 'undefined') {
+ window.EZUIKit.handleTalkError(_error);
+ }
+ }
+ }); // $('#start').removeAttr('disabled').html("Stop")
+ // .click(function() {
+ // $(this).attr('disabled', true);
+ // janus.destroy();
+ // });
+ },
+ error: function error(_error2) {
+ console.error(" -- Error attaching plugin...", _error2);
+ bootbox.alert("Error attaching plugin... " + _error2);
+
+ if (window.EZUIKit.handleTalkError !== 'undefined') {
+ window.EZUIKit.handleTalkError(_error2);
+ }
+ },
+ consentDialog: function consentDialog(on) {
+ Janus.debug("Consent dialog should be " + (on ? "on" : "off") + " now");
+ },
+ iceState: function iceState(state) {
+ Janus.log("ICE state changed to " + state);
+ },
+ mediaState: function mediaState(medium, on) {
+ Janus.log("Janus " + (on ? "started" : "stopped") + " receiving our " + medium);
+ },
+ webrtcState: function webrtcState(on) {
+ Janus.log("Janus says our WebRTC PeerConnection is " + (on ? "up" : "down") + " now"); // $("#audioleft").parent().unblock();
+ },
+ slowLink: function slowLink(uplink, lost) {
+ Janus.warn("Janus reports problems " + (uplink ? "sending" : "receiving") + " packets on this PeerConnection (" + lost + " lost packets)");
+ },
+ onmessage: function onmessage(msg, jsep) {
+ Janus.debug(" ::: Got a message :::");
+ Janus.debug(msg);
+
+ if (jsep !== undefined && jsep !== null) {
+ Janus.debug("Handling SDP as well...");
+ Janus.debug(jsep);
+ tts.handleRemoteJsep({
+ jsep: jsep
+ });
+ }
+
+ var result = msg["result"];
+
+ if (result !== null && result !== undefined) {
+ if (result === "done") {
+ // The plugin closed
+ bootbox.alert("The TTS Test is over");
+ if (spinner !== null && spinner !== undefined) spinner.stop();
+ spinner = null; // $('#myaudio').remove();
+ //$('#waitingvideo').remove();
+ // $('#peeraudio').remove();
+
+ return;
+ }
+
+ if (result === "msg") {
+ if (typeof window.EZUIKit.handleTalkMessage !== 'undefined') {
+ window.EZUIKit.handleTalkMessage(msg);
+ }
+ } // Any loss?
+
+
+ var status = result["status"];
+
+ if (status === "slow_link") {
+ //~ var bitrate = result["bitrate"];
+ //~ toastr.warning("The bitrate has been cut to " + (bitrate/1000) + "kbps", "Packet loss?", {timeOut: 2000});
+ toastr.warning("Janus apparently missed many packets we sent, maybe we should reduce the bitrate", "Packet loss?", {
+ timeOut: 2000
+ });
+ }
+ }
+ },
+ onlocalstream: function onlocalstream(stream) {
+ Janus.debug(" ::: Got a local stream :::");
+ Janus.debug(stream); // if($('#myaudio').length === 0) {
+ // $('#audios').removeClass('hide').show();
+ // $('#audioleft').append('<audio id="myaudio" autoplay controls muted>Your browser does not support audio tag</audio>');
+ // }
+
+ Janus.attachMediaStream(document.getElementById("myaudio"), stream); //$("#myaudio").get(0).muted = "muted";
+
+ if (tts.webrtcStuff.pc.iceConnectionState !== "completed" && tts.webrtcStuff.pc.iceConnectionState !== "connected") {
+ // $("#audioleft").parent().block({
+ // message: '<b>Publishing...</b>',
+ // css: {
+ // border: 'none',
+ // backgroundColor: 'transparent',
+ // color: 'white'
+ // }
+ // });
+ // No remote video yet
+ //$('#audioright').append('<video class="rounded centered" id="waitingvideo" width=320 height=240 />');
+ if (spinner == null) {
+ document.getElementById('audioright'); //spinner = new Spinner({top:100}).spin(target);
+ } else {
+ spinner.spin();
+ }
+ }
+
+ var audioTracks = stream.getAudioTracks();
+
+ if (audioTracks === null || audioTracks === undefined || audioTracks.length === 0) ;
+ },
+ onremotestream: function onremotestream(stream) {
+ Janus.debug(" ::: Got a remote stream :::");
+ Janus.debug(stream); // if($('#peeraudio').length === 0) {
+ // $('#audios').removeClass('hide').show();
+ // // $('#audioright').append('<audio id="peeraudio" autoplay controls>Your browser does not support audio tag</audio>');
+ // // Show the video, hide the spinner and show the resolution when we get a playing event
+ // var audio = $('<audio id="peeraudio" autoplay controls playsinline preload="preload" loop="true"></audio>');
+ // audio = audio.get(0);
+ // audio.setAttribute("id", 'peeraudio');
+ // audio.setAttribute("preload","preload");
+ // // 鑷姩鎾斁瑙e喅鑻规灉涓嶅吋瀹筧utoplay灞炴��
+ // audio.setAttribute("loop",true);
+ // $('#audioright').append(audio);
+ // $("#peeraudio").bind("playing", function () {
+ // //$('#waitingvideo').remove();
+ // $('#peeraudio').removeClass('hide').show();
+ // if(spinner !== null && spinner !== undefined)
+ // spinner.stop();
+ // spinner = null;
+ // });
+ // }
+
+ Janus.attachMediaStream(document.getElementById("peeraudio"), stream);
+ var audioTracks = stream.getAudioTracks();
+
+ if (audioTracks === null || audioTracks === undefined || audioTracks.length === 0) ; else {
+ // $('#peeraudio').removeClass('hide').show();
+ document.getElementById('peeraudio').play();
+ }
+ },
+ ondataopen: function ondataopen(data) {
+ Janus.log("The DataChannel is available!");
+ },
+ ondata: function ondata(data) {
+ Janus.debug("We got data from the DataChannel! " + data);
+ },
+ oncleanup: function oncleanup() {
+ Janus.log(" ::: Got a cleanup notification :::");
+ if (spinner !== null && spinner !== undefined) spinner.stop();
+ spinner = null; // $('#myaudio').remove();
+ // //$('#waitingvideo').remove();
+ // $("#audioleft").parent().unblock();
+ // $('#peeraudio').remove();
+ }
+ });
+ },
+ error: function error(_error3) {
+ Janus.error(_error3);
+
+ if (window.EZUIKit.handleTalkError !== 'undefined') {
+ window.EZUIKit.handleTalkError(_error3);
+ }
+ },
+ destroyed: function destroyed() {// window.location.reload();
+ }
+ });
+ };
+ }
+});
+
+window.janus = janus;
+window.tts = tts;
+
+var Talk = /*#__PURE__*/function () {
+ function Talk(jSPlugin) {
+ var _this = this;
+
+ _classCallCheck$1(this, Talk);
+
+ this.jSPlugin = jSPlugin;
+ var audioLeft = document.createElement('div');
+ audioLeft.id = "audioleft";
+ var audioRight = document.createElement('div');
+ audioRight.id = "audioright";
+ audioRight.style = "display:none;";
+ var audioLeftDOM = document.createElement('audio');
+ audioLeftDOM.id = "myaudio";
+ audioLeftDOM.muted = true;
+ audioLeftDOM.setAttribute("autoplay", true);
+ audioLeftDOM.setAttribute("controls", true);
+ audioLeft.appendChild(audioLeftDOM);
+ audioLeft.style = "display:none;";
+ var audioRightDOM = document.createElement('audio');
+ audioRightDOM.id = "peeraudio";
+ audioRightDOM.setAttribute("autoplay", true);
+ audioRightDOM.setAttribute("controls", true);
+ audioRight.appendChild(audioRightDOM); // addJs(`${this.jSPlugin.staticPath}/talk/adapeter.js`, () => {
+ // addJs(`${this.jSPlugin.staticPath}/talk/janus.js`, () => {
+ // addJs(`${this.jSPlugin.staticPath}/talk/tts-v4.js`, () => {
+ // 涓存椂澶勭悊
+
+ window.EZUIKit["handleTalkError"] = function (err) {
+ console.log("talk err", err);
+
+ if (typeof _this.jSPlugin.handleTalkError !== 'undefined') {
+ _this.jSPlugin.handleTalkError(err);
+ }
+ };
+
+ window.EZUIKit["handleTalkSuccess"] = function (data) {
+ console.log("talk success", data);
+
+ if (typeof _this.jSPlugin.handleTalkSuccess !== 'undefined') {
+ _this.jSPlugin.handleTalkSuccess(data);
+ }
+ };
+
+ window.EZUIKit.opt = {
+ rtcUrl: "",
+ talkLink: "",
+ ttsUrl: "",
+ stream: "",
+ deviceSerial: matchEzopenUrl(this.jSPlugin.url).deviceSerial,
+ channelNo: matchEzopenUrl(this.jSPlugin.url).channelNo
+ };
+ document.body.appendChild(audioLeft);
+ document.body.appendChild(audioRight); // });
+ // });
+ // });
+ }
+
+ _createClass$1(Talk, [{
+ key: "toString",
+ value: function toString() {
+ return "".concat(this.coreX, "-").concat(this.coreY);
+ }
+ }, {
+ key: "startTalk",
+ value: function startTalk() {
+ var _this2 = this;
+
+ if (this.jSPlugin.capacity && this.jSPlugin.capacity.support_talk && !(this.jSPlugin.capacity && (this.jSPlugin.capacity.support_talk === '3' || this.jSPlugin.capacity.support_talk === '1'))) {
+ if (typeof this.jSPlugin.params.handleError === 'function') {
+ this.jSPlugin.params.handleError({
+ msg: "璁惧涓嶆敮鎸佸璁�",
+ retcode: -1000,
+ id: this.jSPlugin.params.id,
+ type: "handleError"
+ });
+ }
+ console.log("璁惧涓嶆敮鎸佸璁�");
+ return false;
+ }
+
+ var formData = new FormData();
+ formData.append("accessToken", this.jSPlugin.accessToken);
+ formData.append("deviceSerial", matchEzopenUrl(this.jSPlugin.url).deviceSerial);
+ formData.append("channelNo", matchEzopenUrl(this.jSPlugin.url).channelNo);
+ fetch(this.jSPlugin.env.domain + "/api/lapp/live/talk/url", {
+ method: "POST",
+ // headers: {
+ // 'Content-Type': 'application/json'
+ // },
+ body: formData
+ }).then(function (response) {
+ return response.json();
+ }).then(function (data) {
+ if (data.code == 200) {
+ var apiResult = data.data;
+
+ if (apiResult) {
+ // 涓存椂灏唄ttps杞崲涓簑ebsocket
+ var rtcTrunk = apiResult.rtcUrl;
+
+ if (rtcTrunk.indexOf("ws") === -1) {
+ rtcTrunk = rtcTrunk.replace("https", "wss").replace("rtcgw", "rtcgw-ws");
+ }
+
+ window.EZUIKit.opt.rtcUrl = rtcTrunk;
+ window.EZUIKit.opt.ttsUrl = "tts://" + apiResult.ttsUrl;
+ window.EZUIKit.opt.deviceSerial = matchEzopenUrl(_this2.jSPlugin.url).deviceSerial;
+ window.EZUIKit.opt.channelNo = matchEzopenUrl(_this2.jSPlugin.url).channelNo;
+ var urlList = window.EZUIKit.opt.ttsUrl.split("?");
+
+ if (urlList.length === 2) {
+ // 鍥芥爣璁惧
+ var talk = "talk?dev=" + window.EZUIKit.opt.deviceSerial + "&chann=" + window.EZUIKit.opt.channelNo + "&encodetype=2";
+ window.EZUIKit.opt.talkLink = window.EZUIKit.opt.ttsUrl.split("?")[0] + "/" + talk;
+ window.EZUIKit.opt.talkType = "gb28181";
+ } else {
+ // 鏅�氳澶�
+ var talk = "talk://" + window.EZUIKit.opt.deviceSerial + ":0:" + window.EZUIKit.opt.channelNo + ":cas.ys7.com:6500";
+ window.EZUIKit.opt.talkLink = window.EZUIKit.opt.ttsUrl.split("?")[0] + "/" + talk;
+ }
+
+ window.EZUIKit.opt.stream = apiResult.stream;
+ window.startTalk();
+ }
+ } else {
+ if (typeof _this2.jSPlugin.params.handleError === 'function') {
+ _this2.jSPlugin.params.handleError({
+ msg: data.msg,
+ retcode: data.code,
+ id: _this2.jSPlugin.params.id,
+ type: "handleError"
+ });
+ }
+ }
+ })["catch"](function (err) {
+ console.log("err", err);
+ });
+ }
+ }, {
+ key: "stopTalk",
+ value: function stopTalk() {
+ window.stopTalk();
+
+ if (document.getElementById("myaudio") && document.getElementById("myaudio").srcObject) {
+ document.getElementById("myaudio").srcObject.getTracks()[0].stop();
+ }
+ }
+ }]);
+
+ return Talk;
+}();
+
+var MobilePtz = /*#__PURE__*/function () {
+ function MobilePtz(jSPlugin) {
+ var _this = this;
+
+ _classCallCheck$1(this, MobilePtz);
+
+ this.jSPlugin = jSPlugin;
+ var oS = document.createElement('style');
+ oS.innerHTML = "\n body{\n padding: 0;\n margin: 0;\n }\n #mobile-ez-ptz-container {\n display: inline-block;\n width: 375px;\n text-align: center;\n }\n .live-ptz-title{\n height: 25px;\n font-size: 18px;\n color: #2c2c2c;\n text-align: center;\n font-weight: 700;\n margin: 24px 0 12px;\n }\n .live-ptz-intro {\n margin-bottom: 24px;\n color: #aaaaaa;\n }\n .mobile-ez-ptz-wrap {\n background-image: linear-gradient(180deg, #f6f8ff 0%, #ededed6b 50%)\n }\n #mobile-ez-ptz-container .mobile-ez-ptz-container {\n position: relative;\n width: 260px;\n height: 260px;\n background: rgba(255, 255, 255, 0.80);\n border: 1px solid rgba(255, 255, 255, 0.80);\n border-radius: 100%;\n cursor: pointer;\n overflow: hidden;\n margin: auto;\n }\n\n #mobile-ez-ptz-container .mobile-ez-ptz-container .mobile-ez-ptz-icon.top {\n width: 0;\n height: 0;\n border-left: 6px solid transparent;\n border-right: 6px solid transparent;\n border-bottom: 6px solid #aaaaaa;\n position: absolute;\n display: inline-block;\n left: calc(50% - 6px);\n top: 10px;\n }\n\n #mobile-ez-ptz-container .mobile-ez-ptz-container .mobile-ez-ptz-icon.top.active {\n border-bottom-color: #1890FF;\n }\n\n #mobile-ez-ptz-container .mobile-ez-ptz-container .mobile-ez-ptz-icon.bottom {\n width: 0;\n height: 0;\n border-left: 6px solid transparent;\n border-right: 6px solid transparent;\n border-top: 6px solid #aaaaaa;\n position: absolute;\n display: inline-block;\n left: calc(50% - 6px);\n bottom: 10px;\n }\n\n #mobile-ez-ptz-container .mobile-ez-ptz-container .mobile-ez-ptz-icon.bottom.active {\n border-top-color: #1890FF;\n\n }\n\n #mobile-ez-ptz-container .mobile-ez-ptz-container .mobile-ez-ptz-icon.right {\n width: 0;\n height: 0;\n border-top: 6px solid transparent;\n border-bottom: 6px solid transparent;\n border-left: 6px solid #aaaaaa;\n position: absolute;\n display: inline-block;\n top: calc(50% - 6px);\n right: 10px;\n }\n\n #mobile-ez-ptz-container .mobile-ez-ptz-container .mobile-ez-ptz-icon.right.active {\n border-left-color: #1890FF;\n\n }\n\n #mobile-ez-ptz-container .mobile-ez-ptz-container .mobile-ez-ptz-icon.left {\n width: 0;\n height: 0;\n border-top: 6px solid transparent;\n border-bottom: 6px solid transparent;\n border-right: 6px solid #aaaaaa;\n position: absolute;\n display: inline-block;\n top: calc(50% - 6px);\n left: 10px;\n }\n\n #mobile-ez-ptz-container .mobile-ez-ptz-container .mobile-ez-ptz-icon.left.active {\n border-right-color: #1890FF;\n\n }\n\n #mobile-ez-ptz-container .mobile-ez-ptz-container .ez-ptz-main.center {\n width: 52px;\n height: 52px;\n background: #FFFFFF;\n border: 2px solid #eee;\n border-radius: 100%;\n top: calc(50% - 26px);\n left: calc(50% - 26px);\n position: absolute;\n /* box-shadow: 0px -39px 40px 6px #1890ff; */\n }\n\n #mobile-ez-ptz-container .mobile-ez-ptz-wrap {\n display: inline-block;\n padding: 24px 24px;\n border-radius: 100%;\n overflow: hidden;\n }\n\n #mobile-ez-ptz-container .ez-ptz-close {\n position: absolute;\n color: #FFFFFF;\n top: 0;\n right: 0px;\n }";
+ document.getElementsByTagName("head")[0].appendChild(oS);
+ var mobileContainer = document.createElement('div');
+ mobileContainer.className = "mobile-ez-ptz-container";
+ mobileContainer.id = "mobile-ez-ptz-container";
+ mobileContainer.style = "display:inline-block;width: ".concat(this.jSPlugin.width, "px;text-align:center;");
+ var mobileContainerTitle = document.createElement('div');
+ mobileContainerTitle.className = "live-ptz-title";
+ mobileContainerTitle.id = "live-ptz-title";
+ mobileContainerTitle.innerHTML = "浜戝彴鎺у埗";
+
+ if (!document.getElementById("live-ptz-title")) {
+ mobileContainer.appendChild(mobileContainerTitle);
+ }
+
+ var mobileContainerIntro = document.createElement('div');
+ mobileContainerIntro.className = "live-ptz-intro";
+ mobileContainerIntro.id = "live-ptz-intro";
+ mobileContainerIntro.innerHTML = "璇烽�氳繃鎿嶆帶浜戝彴鏉ヨ皟鏁存憚鍍忔満瑙嗚";
+
+ if (!document.getElementById("live-ptz-intro")) {
+ mobileContainer.appendChild(mobileContainerIntro);
+ }
+
+ var ptzWrap = document.createElement('div');
+ ptzWrap.id = "mobile-ez-ptz-item";
+ ptzWrap.className = "mobile-ez-ptz-wrap";
+ ptzWrap.innerHTML = "\n <div class=\"mobile-ez-ptz-container\" id=\"mobile-ez-ptz-container\">\n <div class=\"ez-ptz-main center\"></div>\n <div class=\"mobile-ez-ptz-icon top default\"></div>\n <div class=\"mobile-ez-ptz-icon left default\"></div>\n <div class=\"mobile-ez-ptz-icon bottom default\"></div>\n <div class=\"mobile-ez-ptz-icon right default\"></div>\n </div>\n ";
+
+ if (!document.getElementById("mobile-ez-ptz-item")) {
+ mobileContainer.appendChild(ptzWrap);
+ } //document.getElementById(jSPlugin.id).appendChild(mobileContainer);
+
+
+ insertAfter$1(mobileContainer, document.getElementById("".concat(this.jSPlugin.id, "-wrap"))); // 浜戝彴鎺у埗浜嬩欢缁戝畾
+ // 浜戝彴鎺у埗
+
+ document.getElementById("mobile-ez-ptz-item").ontouchstart = function (e) {
+ e.preventDefault();
+ console.log("瑙︽懜寮�濮�");
+
+ _this._handlePtzTouch(e, 'start');
+ };
+
+ document.getElementById("mobile-ez-ptz-item").ontouchend = function (e) {
+ e.preventDefault();
+ console.log("瑙︽懜缁撴潫", e);
+
+ _this._handlePtzTouch(e, 'stop');
+ }; // 浜戝彴鎺у埗
+
+
+ document.getElementById("mobile-ez-ptz-item").onmousedown = function (e) {
+ e.preventDefault();
+ console.log("瑙︽懜寮�濮�");
+
+ _this._handlePtzTouch(e, 'start');
+ };
+
+ document.getElementById("mobile-ez-ptz-item").onmouseup = function (e) {
+ e.preventDefault();
+ console.log("瑙︽懜缁撴潫", e);
+
+ _this._handlePtzTouch(e, 'stop');
+ };
+ }
+
+ _createClass$1(MobilePtz, [{
+ key: "show",
+ value: function show() {
+ document.getElementById("mobile-ez-ptz-item").style = "display: inline-block";
+ }
+ }, {
+ key: "hide",
+ value: function hide() {
+ document.getElementById("mobile-ez-ptz-item").style = "display: none";
+ }
+ }, {
+ key: "_handlePtzTouch",
+ value: function _handlePtzTouch(e, type) {
+ var container = document.getElementById('mobile-ez-ptz-item').getBoundingClientRect();
+ var containerCenterX = container.left + 130;
+ var containerCenterY = container.top + 130;
+ var eventX = e.x || e.changedTouches[0].clientX;
+ var eventY = e.y || e.changedTouches[0].clientY;
+ var left = eventX - containerCenterX;
+ var top = eventY - containerCenterY;
+ var direction = 0; //鎿嶄綔鍛戒护锛�0-涓婏紝1-涓嬶紝2-宸︼紝3鍙筹紝4-宸︿笂锛�5-宸︿笅锛�6-鍙充笂锛�7-鍙充笅锛�8-鏀惧ぇ锛�9-缂╁皬锛�10-杩戠劍璺濓紝11-杩滅劍璺�
+
+ var url = this.jSPlugin.env.domain + "/api/lapp/device/ptz/start"; // var nextPtzImg = ptzNormalImg;
+ // var nextPtzImgFailed = ptzNormalImg;
+ // 鍒よ鏂逛綅
+
+ if (Math.abs(left) > Math.abs(top)) {
+ if (left > 0) {
+ direction = 3;
+ document.getElementsByClassName("mobile-ez-ptz-icon")[3].className = document.getElementsByClassName("mobile-ez-ptz-icon")[3].className.replace("default", "active");
+ } else {
+ direction = 2;
+ document.getElementsByClassName("mobile-ez-ptz-icon")[1].className = document.getElementsByClassName("mobile-ez-ptz-icon")[1].className.replace("default", "active");
+ }
+ } else {
+ if (top > 0) {
+ direction = 1;
+ document.getElementsByClassName("mobile-ez-ptz-icon")[2].className = document.getElementsByClassName("mobile-ez-ptz-icon")[2].className.replace("default", "active");
+ } else {
+ direction = 0;
+ document.getElementsByClassName("mobile-ez-ptz-icon")[0].className = document.getElementsByClassName("mobile-ez-ptz-icon")[0].className.replace("default", "active");
+ }
+ }
+
+ document.getElementById("mobile-ez-ptz-item").style = "background-image:linear-gradient(".concat(direction === 0 ? 180 : direction === 1 ? 0 : direction === 2 ? 90 : 270, "deg, #c0ddf1 0%, rgba(100,143,252,0.00) 50%)");
+
+ if (type === 'stop') {
+ url = this.jSPlugin.env.domain + '/api/lapp/device/ptz/stop';
+ document.getElementById("mobile-ez-ptz-item").style = "";
+ document.getElementsByClassName("mobile-ez-ptz-icon")[3].className = document.getElementsByClassName("mobile-ez-ptz-icon")[3].className.replace("active", "default");
+ document.getElementsByClassName("mobile-ez-ptz-icon")[1].className = document.getElementsByClassName("mobile-ez-ptz-icon")[1].className.replace("active", "default");
+ document.getElementsByClassName("mobile-ez-ptz-icon")[2].className = document.getElementsByClassName("mobile-ez-ptz-icon")[2].className.replace("active", "default");
+ document.getElementsByClassName("mobile-ez-ptz-icon")[0].className = document.getElementsByClassName("mobile-ez-ptz-icon")[0].className.replace("active", "default");
+ }
+
+ var data = new FormData();
+ data.append("deviceSerial", matchEzopenUrl(this.jSPlugin.url).deviceSerial);
+ data.append("channelNo", matchEzopenUrl(this.jSPlugin.url).channelNo);
+ data.append("speed", 1);
+ data.append("direction", direction);
+ data.append("accessToken", this.jSPlugin.accessToken);
+ fetch(url, {
+ method: "POST",
+ body: data
+ }).then(function (response) {
+ return response.json();
+ }).then(function (rt) {
+ if (rt.code == 200) ; else {
+ //document.getElementById('ptz-img-container').childNodes[0].src = nextPtzImgFailed;
+ // layer.msg(data.msg);
+ if (rt.code == 60005 || rt.code == 60002 || rt.code == 60003 || rt.code == 60004) {
+ document.getElementById("mobile-ez-ptz-item").style = "background-image:linear-gradient(".concat(direction === 0 ? 180 : direction === 1 ? 0 : direction === 2 ? 90 : 270, "deg, #f45656 0%, rgba(100,143,252,0.00) 50%)");
+ }
+ }
+ })["catch"](function (err) {
+ console.log("浜戝彴璋冪敤寮傚父", err);
+ });
+ }
+ }]);
+
+ return MobilePtz;
+}();
+
+var retcode = 0;
+var msg = "鎴愬姛";
+var data$7 = {
+ header: {
+ color: "#FFFFFF",
+ backgroundColor: "#000000",
+ activeColor: "#1890FF",
+ btnList: [
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-header-0",
+ iconId: "deviceID",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0,
+ themeId: "f7896c8942c9476fb439370dd974f1c0"
+ },
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-header-1",
+ iconId: "deviceName",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0,
+ themeId: "f7896c8942c9476fb439370dd974f1c0"
+ },
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-header-2",
+ iconId: "cloudRec",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0,
+ themeId: "f7896c8942c9476fb439370dd974f1c0"
+ },
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-header-3",
+ iconId: "rec",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0,
+ themeId: "f7896c8942c9476fb439370dd974f1c0"
+ }
+ ]
+ },
+ footer: {
+ color: "#FFFFFF",
+ backgroundColor: "rgb(0 0 0 / 0%)",
+ activeColor: "#1890FF",
+ btnList: [
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-footer-0",
+ iconId: "play",
+ part: "left",
+ defaultActive: 1,
+ isrender: 0,
+ themeId: "f7896c8942c9476fb439370dd974f1c0"
+ },
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-footer-1",
+ iconId: "capturePicture",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0,
+ themeId: "f7896c8942c9476fb439370dd974f1c0"
+ },
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-footer-2",
+ iconId: "sound",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0,
+ themeId: "f7896c8942c9476fb439370dd974f1c0"
+ },
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-footer-3",
+ iconId: "pantile",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0,
+ themeId: "f7896c8942c9476fb439370dd974f1c0"
+ },
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-footer-4",
+ iconId: "recordvideo",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0,
+ themeId: "f7896c8942c9476fb439370dd974f1c0"
+ },
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-footer-5",
+ iconId: "talk",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0,
+ themeId: "f7896c8942c9476fb439370dd974f1c0"
+ },
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-footer-6",
+ iconId: "hd",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0,
+ themeId: "f7896c8942c9476fb439370dd974f1c0"
+ },
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-footer-7",
+ iconId: "webExpend",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0,
+ themeId: "f7896c8942c9476fb439370dd974f1c0"
+ },
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-footer-8",
+ iconId: "expend",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0,
+ themeId: "f7896c8942c9476fb439370dd974f1c0"
+ }
+ ]
+ }
+};
+var emptyData = {
+ retcode: retcode,
+ msg: msg,
+ data: data$7
+};
+
+var data$6 = {
+ header: {
+ color: "#FFFFFF",
+ backgroundColor: "#000000",
+ activeColor: "#1890FF",
+ btnList: [
+ {
+ iconId: "deviceID",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "deviceName",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "cloudRec",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "rec",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ }
+ ]
+ },
+ footer: {
+ color: "#FFFFFF",
+ backgroundColor: "#00000080",
+ activeColor: "#1890FF",
+ btnList: [
+ {
+ iconId: "play",
+ part: "left",
+ defaultActive: 1,
+ isrender: 1
+ },
+ {
+ iconId: "capturePicture",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "sound",
+ part: "left",
+ defaultActive: 1,
+ isrender: 1
+ },
+ {
+ iconId: "pantile",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "recordvideo",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "talk",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "zoom",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "hd",
+ part: "right",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "webExpend",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "expend",
+ part: "right",
+ defaultActive: 0,
+ isrender: 1
+ }
+ ]
+ }
+};
+var mobileLiveFullData = {
+ data: data$6
+};
+
+var data$5 = {
+ header: {
+ color: "#FFFFFF",
+ backgroundColor: "#000000",
+ activeColor: "#1890FF",
+ btnList: [
+ {
+ iconId: "deviceID",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "deviceName",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "cloudRec",
+ part: "right",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "rec",
+ part: "right",
+ defaultActive: 0,
+ isrender: 1
+ }
+ ]
+ },
+ footer: {
+ color: "#FFFFFF",
+ backgroundColor: "#00000080",
+ activeColor: "#1890FF",
+ btnList: [
+ {
+ iconId: "play",
+ part: "left",
+ defaultActive: 1,
+ isrender: 1
+ },
+ {
+ iconId: "capturePicture",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "sound",
+ part: "left",
+ defaultActive: 1,
+ isrender: 1
+ },
+ {
+ iconId: "pantile",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "recordvideo",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "talk",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "zoom",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "speed",
+ part: "right",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "hd",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "webExpend",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "expend",
+ part: "right",
+ defaultActive: 0,
+ isrender: 1
+ }
+ ]
+ }
+};
+var mobileRecFullData = {
+ data: data$5
+};
+
+var data$4 = {
+ header: {
+ color: "#FFFFFF",
+ backgroundColor: "#000000",
+ activeColor: "#1890FF",
+ btnList: [
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-header-0",
+ iconId: "deviceID",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-header-1",
+ iconId: "deviceName",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-header-2",
+ iconId: "cloudRec",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-header-3",
+ iconId: "rec",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ }
+ ]
+ },
+ footer: {
+ color: "#FFFFFF",
+ backgroundColor: "#00000080",
+ activeColor: "#1890FF",
+ btnList: [
+ {
+ iconId: "play",
+ part: "left",
+ defaultActive: 1,
+ isrender: 1
+ },
+ {
+ iconId: "capturePicture",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "sound",
+ part: "left",
+ defaultActive: 1,
+ isrender: 1
+ },
+ {
+ iconId: "pantile",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "recordvideo",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "talk",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "zoom",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "speed",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "hd",
+ part: "right",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "webExpend",
+ part: "right",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "expend",
+ part: "right",
+ defaultActive: 0,
+ isrender: 1
+ }
+ ]
+ }
+};
+var pcLiveFullData = {
+ data: data$4
+};
+
+var data$3 = {
+ header: {
+ color: "#FFFFFF",
+ backgroundColor: "#000000",
+ activeColor: "#1890FF",
+ btnList: [
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-header-0",
+ iconId: "deviceID",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-header-1",
+ iconId: "deviceName",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-header-2",
+ iconId: "cloudRec",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ btnKey: "c1cbc1d4e86d49a0981f54beea95280a-f7896c8942c9476fb439370dd974f1c0-header-3",
+ iconId: "rec",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ }
+ ]
+ },
+ footer: {
+ color: "#FFFFFF",
+ backgroundColor: "#00000080",
+ activeColor: "#1890FF",
+ btnList: [
+ {
+ iconId: "play",
+ part: "left",
+ defaultActive: 1,
+ isrender: 1
+ },
+ {
+ iconId: "talk",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "sound",
+ part: "left",
+ defaultActive: 1,
+ isrender: 1
+ },
+ {
+ iconId: "capturePicture",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "recordvideo",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "pantile",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "zoom",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "hd",
+ part: "right",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "webExpend",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "expend",
+ part: "right",
+ defaultActive: 0,
+ isrender: 1
+ }
+ ]
+ }
+};
+var pcLiveSecurityData = {
+ data: data$3
+};
+
+var data$2 = {
+ header: {
+ color: "#FFFFFF",
+ backgroundColor: "#000000",
+ activeColor: "#1890FF",
+ btnList: [
+ {
+ iconId: "deviceID",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "deviceName",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "cloudRec",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "rec",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ }
+ ]
+ },
+ footer: {
+ color: "#FFFFFF",
+ backgroundColor: "#000000",
+ activeColor: "#1890FF",
+ btnList: [
+ {
+ iconId: "play",
+ part: "left",
+ defaultActive: 1,
+ isrender: 0
+ },
+ {
+ iconId: "capturePicture",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "sound",
+ part: "left",
+ defaultActive: 1,
+ isrender: 0
+ },
+ {
+ iconId: "pantile",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "recordvideo",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "talk",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "zoom",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "hd",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "webExpend",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "expend",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ }
+ ]
+ }
+};
+var pcLiveSimpleData = {
+ data: data$2
+};
+
+var data$1 = {
+ header: {
+ color: "#FFFFFF",
+ backgroundColor: "#000000",
+ activeColor: "#1890FF",
+ btnList: [
+ {
+ iconId: "deviceID",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "deviceName",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "cloudRec",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "rec",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ }
+ ]
+ },
+ footer: {
+ color: "#FFFFFF",
+ backgroundColor: "#00000080",
+ activeColor: "#1890FF",
+ btnList: [
+ {
+ iconId: "play",
+ part: "left",
+ defaultActive: 1,
+ isrender: 1
+ },
+ {
+ iconId: "capturePicture",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "talk",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "sound",
+ part: "left",
+ defaultActive: 1,
+ isrender: 1
+ },
+ {
+ iconId: "pantile",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "recordvideo",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "hd",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "zoom",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "webExpend",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "expend",
+ part: "right",
+ defaultActive: 0,
+ isrender: 1
+ }
+ ]
+ }
+};
+var pcLiveVoiceData = {
+ data: data$1
+};
+
+var data = {
+ header: {
+ color: "#FFFFFF",
+ backgroundColor: "#000000",
+ activeColor: "#1890FF",
+ btnList: [
+ {
+ iconId: "deviceID",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "deviceName",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "cloudRec",
+ part: "right",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "rec",
+ part: "right",
+ defaultActive: 0,
+ isrender: 1
+ }
+ ]
+ },
+ footer: {
+ color: "#FFFFFF",
+ backgroundColor: "#00000080",
+ activeColor: "#1890FF",
+ btnList: [
+ {
+ iconId: "play",
+ part: "left",
+ defaultActive: 1,
+ isrender: 1
+ },
+ {
+ iconId: "capturePicture",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "sound",
+ part: "left",
+ defaultActive: 1,
+ isrender: 1
+ },
+ {
+ iconId: "pantile",
+ part: "left",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "recordvideo",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "zoom",
+ part: "left",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "speed",
+ part: "right",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "hd",
+ part: "right",
+ defaultActive: 0,
+ isrender: 0
+ },
+ {
+ iconId: "webExpend",
+ part: "right",
+ defaultActive: 0,
+ isrender: 1
+ },
+ {
+ iconId: "expend",
+ part: "right",
+ defaultActive: 0,
+ isrender: 1
+ }
+ ]
+ }
+};
+var pcRecFullDataData = {
+ data: data
+};
+
+var officeTemplateList = [{
+ autoFocus: 5,
+ createTime: '2021-06-14T08:04:37.000Z',
+ themeId: 'pcLive',
+ themeIntro: 'PC鐩存挱鍏ㄩ噺鐗�',
+ themeName: 'PC鐩存挱鍏ㄩ噺鐗�',
+ themeType: 'webLive',
+ updateTime: '2021-06-14T08:04:37.000Z',
+ label: '瀹樻柟',
+ labelPic: "https://resource.eziot.com/group1/M00/00/8A/CtwQEmLr_DmANlElAAA-xyivSaw030.png",
+ poster: "https://resource.eziot.com/group1/M00/00/89/CtwQEmLl8r-AZU7wAAETKlvgerU237.png",
+ header: pcLiveFullData.data.header,
+ footer: pcLiveFullData.data.footer
+}, {
+ autoFocus: 5,
+ createTime: '2021-06-14T08:04:37.000Z',
+ themeId: 'security',
+ themeIntro: 'PC鐩存挱瀹夐槻鐗�',
+ themeName: 'PC鐩存挱瀹夐槻鐗�',
+ themeType: 'webLive',
+ updateTime: '2021-06-14T08:04:37.000Z',
+ label: '瀹樻柟',
+ labelPic: "https://resource.eziot.com/group1/M00/00/8A/CtwQEmLr_DmANlElAAA-xyivSaw030.png",
+ poster: "https://resource.eziot.com/group1/M00/00/89/CtwQEmLl8r-AZU7wAAETKlvgerU237.png",
+ header: pcLiveSecurityData.data.header,
+ footer: pcLiveSecurityData.data.footer
+}, {
+ autoFocus: 5,
+ createTime: '2021-06-14T08:04:37.000Z',
+ themeId: 'voice',
+ themeIntro: 'PC鐩存挱璇煶鐗�',
+ themeName: 'PC鐩存挱璇煶鐗�',
+ themeType: 'webLive',
+ updateTime: '2021-06-14T08:04:37.000Z',
+ label: '瀹樻柟',
+ labelPic: "https://resource.eziot.com/group1/M00/00/8A/CtwQEmLr_DmANlElAAA-xyivSaw030.png",
+ poster: "https://resource.eziot.com/group1/M00/00/89/CtwQEmLl8r-AZU7wAAETKlvgerU237.png",
+ header: pcLiveVoiceData.data.header,
+ footer: pcLiveVoiceData.data.footer
+}, {
+ autoFocus: 5,
+ createTime: '2021-06-14T08:04:37.000Z',
+ themeId: 'simple',
+ themeIntro: 'PC鐩存挱鏋佺畝鐗�',
+ themeName: 'PC鐩存挱鏋佺畝鐗�',
+ themeType: 'webLive',
+ updateTime: '2021-06-14T08:04:37.000Z',
+ label: '瀹樻柟',
+ labelPic: "https://resource.eziot.com/group1/M00/00/8A/CtwQEmLr_DmANlElAAA-xyivSaw030.png",
+ poster: "",
+ header: pcLiveSimpleData.data.header,
+ footer: pcLiveSimpleData.data.footer
+}, {
+ autoFocus: 5,
+ createTime: '2021-06-14T08:04:37.000Z',
+ themeId: 'pcRec',
+ themeIntro: 'PC鍥炴斁鍏ㄩ噺鐗�',
+ themeName: 'PC鍥炴斁鍏ㄩ噺鐗�',
+ themeType: 'webRec',
+ updateTime: '2021-06-14T08:04:37.000Z',
+ label: '瀹樻柟',
+ labelPic: "https://resource.eziot.com/group1/M00/00/8A/CtwQEmLr_DmANlElAAA-xyivSaw030.png",
+ poster: "https://resource.eziot.com/group1/M00/00/89/CtwQEmLl8r-AZU7wAAETKlvgerU237.png",
+ header: pcRecFullDataData.data.header,
+ footer: pcRecFullDataData.data.footer
+}, {
+ autoFocus: 5,
+ createTime: '2021-06-14T08:04:37.000Z',
+ themeId: 'mobileLive',
+ themeIntro: 'Mobile鐩存挱鍏ㄩ噺鐗�',
+ themeName: 'Mobile鐩存挱鍏ㄩ噺鐗�',
+ themeType: 'mobileLive',
+ updateTime: '2021-06-14T08:04:37.000Z',
+ label: '瀹樻柟',
+ labelPic: "https://resource.eziot.com/group1/M00/00/8A/CtwQEmLr_GmAL5IhAABZs1vUK0s564.png",
+ poster: "https://resource.eziot.com/group1/M00/00/89/CtwQEmLl8r-AZU7wAAETKlvgerU237.png",
+ header: mobileLiveFullData.data.header,
+ footer: mobileLiveFullData.data.footer
+}, {
+ autoFocus: 5,
+ createTime: '2021-06-14T08:04:37.000Z',
+ themeId: 'mobileRec',
+ themeIntro: 'Mobile鍥炴斁鍏ㄩ噺鐗�',
+ themeName: 'Mobile鍥炴斁鍏ㄩ噺鐗�',
+ themeType: 'mobileRec',
+ updateTime: '2021-06-14T08:04:37.000Z',
+ label: '瀹樻柟',
+ labelPic: "https://resource.eziot.com/group1/M00/00/8A/CtwQEmLr_GmAL5IhAABZs1vUK0s564.png",
+ poster: "https://resource.eziot.com/group1/M00/00/89/CtwQEmLl8r-AZU7wAAETKlvgerU237.png",
+ header: mobileRecFullData.data.header,
+ footer: mobileRecFullData.data.footer
+}];
+
+var Zoom = /*#__PURE__*/function () {
+ function Zoom(jSPlugin) {
+ var _this = this;
+
+ _classCallCheck$1(this, Zoom);
+
+ this.jSPlugin = jSPlugin;
+ this.enableZoom = false;
+ this.isMouseDown = false, this.videoWidth = 1920;
+ this.videoHeight = 1080;
+ this.currentScale = 1;
+ this.currentPosition = {
+ x: 0,
+ //鎿嶄綔鐐� -x
+ y: 0,
+ //
+ xPercent: 0.10,
+ // 鐧惧垎姣� -x
+ yPercent: 0.10,
+ // 鐧惧垎姣�
+ xCurrentVideo: 0,
+ // 褰撳墠鏀惧ぇ鍚庡彲瑙嗚棰戝乏涓婅璧风偣
+ yCurrentVideo: 0,
+ left: 0,
+ top: 0,
+ right: 1920,
+ bottom: 1080
+ };
+ this.DOM = document.getElementById(jSPlugin.id);
+ this.clientRect = document.getElementById(jSPlugin.id).getBoundingClientRect(); //audioControls-left
+
+ var scaleDOMContainer = document.createElement('div');
+ scaleDOMContainer.id = "".concat(jSPlugin.id, "-zoom-container");
+ scaleDOMContainer.style = "position: absolute;\n display:none;\n left: 12px;\n bottom: 80px;";
+ var scaleDOMHTML = "\n <div\n style=\"display: inline-flex;flex-direction: column;width: 38px;height: 160px;background:rgba(0,0,0,0.60);border-radius: 8px;align-items: center;\">\n <div id=\"".concat(this.jSPlugin.id, "-scale-value\" style=\"font-size: 12px;color:#FFFFFF;margin-top:10px;margin-bottom:4px;\">2.0X</div>\n <div style=\"width: 24px;\" id=\"").concat(this.jSPlugin.id, "-addScale\">\n <?xml version=\"1.0\" encoding=\"utf-8\"?>\n <svg version=\"1.1\" fill=\"#FFFFFF\" id=\"\u56FE\u5C42_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n viewBox=\"0 0 20 20\" style=\"enable-background:new 0 0 20 20;\" xml:space=\"preserve\">\n <title>\u653E\u5927</title>\n <g id=\"\u77E9\u5F62\">\n <rect class=\"st0\" width=\"20\" height=\"20\" fill=\"none\"/>\n </g>\n <g id=\"\u5F62\u72B6\u7ED3\u5408\">\n <path class=\"st1\" d=\"M10,3.8c3.5,0,6.2,2.8,6.2,6.2s-2.8,6.2-6.2,6.2S3.8,13.5,3.8,10S6.5,3.8,10,3.8z M10,5c-2.8,0-5,2.2-5,5\n s2.2,5,5,5s5-2.2,5-5S12.8,5,10,5z\"/>\n </g>\n <g id=\"\u8DEF\u5F84-4\">\n <path class=\"st2\" d=\"M12.5,10.7h-5c-0.3,0-0.6-0.3-0.6-0.6s0.3-0.6,0.6-0.6h5c0.3,0,0.6,0.3,0.6,0.6S12.8,10.7,12.5,10.7z\"/>\n </g>\n <g id=\"\u8DEF\u5F84-4\u5907\u4EFD\">\n <path class=\"st2\" d=\"M10,13.2c-0.3,0-0.6-0.3-0.6-0.6v-5c0-0.3,0.3-0.6,0.6-0.6s0.6,0.3,0.6,0.6v5C10.6,12.9,10.3,13.2,10,13.2z\"/>\n </g>\n </svg>\n </div>\n <div style=\"\n position: relative;\n width: 1px;\n height: 64px;\n border: 1px solid rgba(255,255,255,0.75);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-end;\">\n <div class=\"scale-body-line-dot\" id=\"").concat(this.jSPlugin.id, "-scale-body-line-dot\" style=\"width: 8px;\n height: 8px;\n background: #FFFFFF;\n border-radius: 100%;\n position: absolute;\n border: 1.5px solid rgba(64,122,255,1);\"></div>\n <div id=\"").concat(this.jSPlugin.id, "-line-dot\" style=\"width: 1px;\n height: 0%;\n background: #1890FF;\n bottom: 0;\"></div>\n </div>\n <div style=\"width: 24px;margin-top: 6px;\" id=\"").concat(this.jSPlugin.id, "-subScale\">\n <?xml version=\"1.0\" encoding=\"utf-8\"?>\n <svg fill=\"#FFFFFF\" version=\"1.1\" id=\"\u56FE\u5C42_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n viewBox=\"0 0 20 20\" style=\"enable-background:new 0 0 20 20;\" xml:space=\"preserve\">\n <title>\u7F29\u5C0F</title>\n <g id=\"\u77E9\u5F62\">\n <rect class=\"st0\" width=\"20\" height=\"20\" fill=\"none\"/>\n </g>\n <g id=\"\u5F62\u72B6\u7ED3\u5408\">\n <path class=\"st1\" d=\"M10,3.8c3.5,0,6.2,2.8,6.2,6.2s-2.8,6.2-6.2,6.2S3.8,13.5,3.8,10S6.5,3.8,10,3.8z M10,5c-2.8,0-5,2.2-5,5\n s2.2,5,5,5s5-2.2,5-5S12.8,5,10,5z\"/>\n </g>\n <g id=\"\u8DEF\u5F84-4\">\n <path class=\"st2\" d=\"M12.5,10.7h-5c-0.3,0-0.6-0.3-0.6-0.6s0.3-0.6,0.6-0.6h5c0.3,0,0.6,0.3,0.6,0.6S12.8,10.7,12.5,10.7z\"/>\n </g>\n </svg>\n </div>\n </div>\n ");
+ scaleDOMContainer.innerHTML = scaleDOMHTML;
+ document.getElementById("".concat(jSPlugin.id, "-audioControls-left")).parentNode.appendChild(scaleDOMContainer);
+
+ document.getElementById("".concat(jSPlugin.id, "-addScale")).onclick = function () {
+ _this.addScale();
+ };
+
+ document.getElementById("".concat(jSPlugin.id, "-subScale")).onclick = function () {
+ _this.subScale();
+ }; // document.getElementById("video-container").addEventListener("mouseenter",(event)=> {
+ // console.log("榧犳爣杩涘叆", event);
+ // });
+
+ }
+
+ _createClass$1(Zoom, [{
+ key: "onMouseDown",
+ value: function onMouseDown(event) {
+ this.currentPosition;
+ this.currentScale;
+ this.moveX = event.clientX;
+ this.moveY = event.clientY;
+ this.isMouseDown = true;
+ }
+ }, {
+ key: "onMouseUp",
+ value: function onMouseUp(event) {
+ var currentPosition = this.currentPosition;
+ this.enableZoom;
+ this.isMouseDown = false;
+ currentPosition.left = currentPosition.left - (event.clientX - this.moveX);
+ currentPosition.top = currentPosition.top - (event.clientY - this.moveY);
+ this.doScale();
+ }
+ }, {
+ key: "onMouseOut",
+ value: function onMouseOut(event) {
+ if (this.isMouseDown) {
+ console.log("榧犳爣鎸変笂", event);
+ this.isMouseDown = false;
+ }
+
+ this.isMouseDown = false;
+ }
+ }, {
+ key: "renderDot",
+ value: function renderDot() {
+ var currentScale = this.currentScale;
+ document.getElementById("".concat(this.jSPlugin.id, "-scale-value")).innerHTML = "".concat(currentScale, ".0X");
+ document.getElementById("".concat(this.jSPlugin.id, "-line-dot")).style.height = "".concat((currentScale - 1) / 7 * 100, "%");
+ document.getElementById("".concat(this.jSPlugin.id, "-scale-body-line-dot")).style.bottom = "calc(".concat((currentScale - 1) / 7 * 100, "% - 6px)");
+ }
+ }, {
+ key: "startZoom",
+ value: function startZoom() {
+ var _this2 = this;
+
+ var info = this.jSPlugin.jSPlugin._JSPlayM4_GetFrameInfo(0);
+
+ this.videoWidth = info.width;
+ this.videoHeight = info.height;
+ this.currentPosition.right = info.width;
+ this.currentPosition.bottom = info.height;
+ this.currentScale = 1;
+ document.getElementById("".concat(this.jSPlugin.id, "-zoom-container")).style.display = "block";
+
+ this.jSPlugin.jSPlugin._JSPlayM4_SetDisplayRegion(0, this.videoWidth, 0, this.videoHeight);
+
+ this.renderDot();
+ this.enableZoom = true;
+
+ if (document.getElementById("".concat(this.jSPlugin.id, "canvas_draw0"))) {
+ document.getElementById("".concat(this.jSPlugin.id, "canvas_draw0")).addEventListener("mousedown", function (event) {
+ return _this2.onMouseDown(event);
+ });
+ document.getElementById("".concat(this.jSPlugin.id, "canvas_draw0")).addEventListener("mouseup", function (event) {
+ return _this2.onMouseUp(event);
+ });
+ document.getElementById("".concat(this.jSPlugin.id, "canvas_draw0")).addEventListener("mouseout", function (event) {
+ return _this2.onMouseOut(event);
+ });
+ } else if (document.getElementById("".concat(this.jSPlugin.id, "-player"))) {
+ document.getElementById("".concat(this.jSPlugin.id, "-player")).addEventListener("mousedown", function (event) {
+ return _this2.onMouseDown(event);
+ });
+ document.getElementById("".concat(this.jSPlugin.id, "-player")).addEventListener("mouseup", function (event) {
+ return _this2.onMouseUp(event);
+ });
+ document.getElementById("".concat(this.jSPlugin.id, "-player")).addEventListener("mouseout", function (event) {
+ return _this2.onMouseOut(event);
+ });
+ }
+ }
+ }, {
+ key: "stopZoom",
+ value: function stopZoom() {
+ var _this3 = this;
+
+ this.currentScale = 1;
+
+ this.jSPlugin.jSPlugin._JSPlayM4_SetDisplayRegion(0, this.videoWidth, 0, this.videoHeight);
+
+ document.getElementById("".concat(this.jSPlugin.id, "-zoom-container")).style.display = "none";
+ this.renderDot();
+ this.enableZoom = false;
+ document.getElementById(this.jSPlugin.id).removeEventListener("mousedown", function (event) {
+ return _this3.onMouseDown(event);
+ });
+ document.getElementById(this.jSPlugin.id).removeEventListener("mouseup", function (event) {
+ return _this3.onMouseUp(event);
+ });
+ document.getElementById(this.jSPlugin.id).removeEventListener("mouseout", function (event) {
+ return _this3.onMouseOut(event);
+ });
+ } // scrollFunc(e) {
+ // e = e || window.event;
+ // if (e.wheelDelta) { //鍒ゆ柇娴忚鍣↖E锛岃胺姝屾粦杞簨浠�
+ // if (e.wheelDelta > 0) { //褰撴粦杞悜涓婃粴鍔ㄦ椂
+ // this.isScrollOverVideo(e, 'up');
+ // }
+ // if (e.wheelDelta < 0) { //褰撴粦杞悜涓嬫粴鍔ㄦ椂
+ // this.isScrollOverVideo(e, 'down');
+ // }
+ // } else if (e.detail) { //Firefox婊戣疆浜嬩欢
+ // if (e.detail > 0) { //褰撴粦杞悜涓嬫粴鍔ㄦ椂
+ // this.isScrollOverVideo(e, 'down');
+ // }
+ // if (e.detail < 0) { //褰撴粦杞悜涓婃粴鍔ㄦ椂
+ // this.isScrollOverVideo(e, 'up');
+ // }
+ // }
+ // }
+ // isScrollOverVideo(e, type) {
+ // const { clientRect } = this;
+ // if (e.clientX > clientRect.x && e.clientX < (clientRect.x + clientRect.width)) {
+ // if (e.clientY > clientRect.y && e.clientY < (clientRect.y + clientRect.height)) {
+ // if (type == 'up' && currentScale < 8) {
+ // this.currentScale++;
+ // console.log("褰撳墠鏀惧ぇ灏哄害", currentScale)
+ // this.calCurrentPosition(e);
+ // }
+ // if (type == 'down' && currentScale > 1) {
+ // this.currentScale--;
+ // console.log("褰撳墠鏀惧ぇ灏哄害", currentScale)
+ // this.calCurrentPosition(e);
+ // }
+ // return;
+ // }
+ // }
+ // return false
+ // }
+
+ }, {
+ key: "doScale",
+ value: function doScale() {
+ console.log("鎵ц鏀惧ぇ");
+ var currentPosition = this.currentPosition,
+ currentScale = this.currentScale;
+ currentPosition.left = currentPosition.left + currentPosition.xPercent * (currentPosition.right - currentPosition.left) - 1 / 2 * (this.videoWidth / currentScale);
+
+ if (currentPosition.left < 0) {
+ currentPosition.left = 0;
+ } else if (currentPosition.left > this.videoWidth - this.videoWidth / currentScale) {
+ currentPosition.left = this.videoWidth - this.videoWidth / currentScale;
+ }
+
+ currentPosition.right = currentPosition.left + this.videoWidth / currentScale;
+ currentPosition.top = currentPosition.top + currentPosition.yPercent * (currentPosition.bottom - currentPosition.top) - 1 / 2 * (this.videoHeight / currentScale);
+
+ if (currentPosition.top < 0) {
+ currentPosition.top = 0;
+ } else if (currentPosition.top > this.videoHeight - this.videoHeight / currentScale) {
+ currentPosition.top = this.videoHeight - this.videoHeight / currentScale;
+ }
+
+ currentPosition.bottom = currentPosition.top + this.videoHeight / currentScale; //鏁存暟鍖�
+
+ currentPosition.left = parseInt(currentPosition.left, 10);
+ currentPosition.right = parseInt(currentPosition.right, 10);
+ currentPosition.top = parseInt(currentPosition.top, 10);
+ currentPosition.bottom = parseInt(currentPosition.bottom, 10);
+ console.log("璁$畻鍚庯紝", this.jSPlugin.jSPlugin, currentPosition.left, currentPosition.right, currentPosition.top, currentPosition.bottom, currentPosition.xPercent, currentPosition.yPercent);
+
+ this.jSPlugin.jSPlugin._JSPlayM4_SetDisplayRegion(currentPosition.left, currentPosition.right, currentPosition.top, currentPosition.bottom);
+
+ this.renderDot();
+ }
+ }, {
+ key: "calCurrentPosition",
+ value: function calCurrentPosition(e) {
+ var currentPosition = this.currentPosition,
+ clientRect = this.clientRect;
+ currentPosition.x = e.clientX;
+ currentPosition.y = e.clientY;
+ currentPosition.xPercent = (e.clientX - clientRect.x) / clientRect.width;
+ currentPosition.yPercent = (e.clientY - clientRect.y) / clientRect.height;
+ this.doScale();
+ return;
+ }
+ }, {
+ key: "addScale",
+ value: function addScale() {
+ var currentScale = this.currentScale,
+ currentPosition = this.currentPosition;
+
+ if (currentScale >= 8) {
+ console.log("杈惧埌鏈�澶у�嶇巼浜�");
+
+ if (this.jSPlugin.Message) {
+ this.jSPlugin.Message["default"]("宸茬粡鏀惧ぇ鍒版渶澶у�嶆暟8.0X");
+ }
+
+ return false;
+ }
+
+ this.currentScale++;
+ currentPosition.xPercent = 0.5;
+ currentPosition.yPercent = 0.5;
+ this.doScale();
+ }
+ }, {
+ key: "subScale",
+ value: function subScale() {
+ var currentScale = this.currentScale,
+ currentPosition = this.currentPosition;
+
+ if (currentScale <= 1) {
+ console.log("杈惧埌鏈�灏忓�嶇巼浜�");
+ return false;
+ }
+
+ this.currentScale--;
+ currentPosition.xPercent = 0.5;
+ currentPosition.yPercent = 0.5;
+ this.doScale();
+ }
+ }]);
+
+ return Zoom;
+}();
+
+function lineLength(point1, point2) {
+ return Math.abs(point2.clientX - point1.clientX) * Math.abs(point2.clientX - point1.clientX) + Math.abs(point2.clientY - point1.clientY) * Math.abs(point2.clientY - point1.clientY);
+}
+
+var MobileZoom = /*#__PURE__*/function () {
+ function MobileZoom(jSPlugin) {
+ var _this = this;
+
+ _classCallCheck$1(this, MobileZoom);
+
+ this.jSPlugin = jSPlugin;
+ this.enableZoom = false;
+ this.isDubboTouch = false, this.videoWidth = 0;
+ this.videoHeight = 0;
+ this.currentScale = 1;
+ this.currentPosition = {
+ x: 0,
+ //鎿嶄綔鐐� -x
+ y: 0,
+ //
+ xPercent: 0.10,
+ // 鐧惧垎姣� -x
+ yPercent: 0.10,
+ // 鐧惧垎姣�
+ xCurrentVideo: 0,
+ // 褰撳墠鏀惧ぇ鍚庡彲瑙嗚棰戝乏涓婅璧风偣
+ yCurrentVideo: 0,
+ left: 0,
+ top: 0,
+ right: 1920,
+ bottom: 1080
+ };
+ this.DOM = document.getElementById(jSPlugin.id);
+ this.clientRect = document.getElementById(jSPlugin.id).getBoundingClientRect();
+ this.point1 = {
+ clientX: 0,
+ clientY: 0
+ };
+ this.point2 = {
+ clientX: 0,
+ clientY: 0
+ };
+ this.touchLineLength = 0;
+ this.inited = false;
+ var scaleDOMContainer = document.createElement('div');
+ scaleDOMContainer.id = "".concat(jSPlugin.id, "-zoom-container");
+ scaleDOMContainer.style = "display:none;\n position: absolute;\n left: 10px;\n top: -30px;\n border: 1px solid rgba(0,0,0,0.6);\n color: #FFFFFF;\n background: rgba(0,0,0,0.6);\n border-radius: 10px;\n width: 36px;\n font-size: 12px;\n text-align: center;\n height: 22px;\n line-height: 22px;";
+ var scaleDOMHTML = "1X";
+ scaleDOMContainer.innerHTML = scaleDOMHTML;
+ document.getElementById("".concat(jSPlugin.id, "-audioControls-left")).parentNode.appendChild(scaleDOMContainer); // document.getElementById(this.jSPlugin.id).addEventListener("mousedown",(event)=>this.onMouseDown(event));
+ // document.getElementById(this.jSPlugin.id).addEventListener("mouseup",(event)=>this.onMouseUp(event));
+ // document.getElementById(this.jSPlugin.id).addEventListener("mouseout",(event)=>this.onMouseOut(event));
+
+ document.getElementById(this.jSPlugin.id).addEventListener("touchstart", function (event) {
+ return _this.onTouchstart(event);
+ });
+ document.getElementById(this.jSPlugin.id).addEventListener("touchmove", function (event) {
+ return _this.onTouchmove(event);
+ }); // var info = jSPlugin.jSPlugin._JSPlayM4_GetFrameInfo(0);
+ // this.videoWidth = info.width;
+ // this.videoHeight = info.height;
+ // this.currentPosition.right = info.width;
+ // this.currentPosition.bottom = info.height;
+ }
+
+ _createClass$1(MobileZoom, [{
+ key: "onTouchstart",
+ value: function onTouchstart(event) {
+ if (!this.inited) {
+ var info = this.jSPlugin.jSPlugin._JSPlayM4_GetFrameInfo(0);
+
+ this.videoWidth = info.width;
+ this.videoHeight = info.height;
+ this.currentPosition.right = info.width;
+ this.currentPosition.bottom = info.height;
+ this.inited = true;
+ }
+
+ var currentPosition = this.currentPosition;
+ this.currentScale;
+ console.log("鍙屾寚鎸変笅", currentPosition);
+ var touches = event.touches;
+ var events = touches[0];
+ var events2 = touches[1];
+
+ if (events) {
+ this.point1.clientX = events.clientX;
+ this.point1.clientY = events.clientY;
+ }
+
+ if (events2) {
+ this.point2.clientX = events2.clientX;
+ this.point2.clientY = events2.clientY;
+ this.touchLineLength = lineLength(this.point1, this.point2);
+ this.isDubboTouch = true;
+ this.moveX = events.clientX;
+ this.moveY = events.clientY;
+ }
+
+ console.log("鍙屾寚鎸変笅2", currentPosition);
+ }
+ }, {
+ key: "onTouchmove",
+ value: function onTouchmove(event) {
+ var isDubboTouch = this.isDubboTouch,
+ currentPosition = this.currentPosition,
+ clientRect = this.clientRect; // console.log("event.touches.lenght",event.touches.length);
+
+ if (event.touches.length === 1) {
+ var events = event.touches[0]; //console.log("currentPosition.xPercent",event.touches)
+
+ currentPosition.xPercent = currentPosition.xPercent + (this.point1.clientX - events.clientX) / clientRect.width / this.currentScale;
+ currentPosition.yPercent = currentPosition.yPercent + (this.point1.clientY - events.clientY) / clientRect.height / this.currentScale;
+ this.doScale();
+ this.point1.clientX = events.clientX;
+ this.point1.clientY = events.clientY;
+ return false;
+ }
+
+ if (!isDubboTouch) {
+ return false;
+ }
+
+ var touches = event.touches;
+ var events = touches[0];
+ var events2 = touches[1];
+
+ if (events) {
+ this.point1.clientX = events.clientX;
+ this.point1.clientY = events.clientY;
+ }
+
+ if (events2) {
+ this.point2.clientX = events2.clientX;
+ this.point2.clientY = events2.clientY;
+ var newtTouchLineLength = lineLength(this.point1, this.point2);
+
+ if (newtTouchLineLength !== this.touchLineLength) {
+ if (newtTouchLineLength > this.touchLineLength) {
+ if (this.currentScale < 8) {
+ ++this.currentScale;
+ currentPosition.xPercent = (this.point1.clientX + this.point2.clientX) / 2 / clientRect.width;
+ currentPosition.yPercent = (this.point1.clientY + this.point2.clientY) / 2 / clientRect.height;
+ this.doScale();
+ } else {
+ console.log("宸茬粡鏄渶澶�8鍊嶇巼浜�");
+ }
+ } else {
+ if (this.currentScale > 1) {
+ --this.currentScale;
+ currentPosition.xPercent = (this.point1.clientX + this.point2.clientX) / 2 / clientRect.width;
+ currentPosition.yPercent = (this.point1.clientY + this.point2.clientY) / 2 / clientRect.height;
+ this.doScale();
+ } else {
+ console.log("宸茬粡鏄渶灏�1鍊嶇巼浜�");
+ }
+ }
+
+ this.isDubboTouch = false;
+ }
+ }
+ }
+ }, {
+ key: "startZoom",
+ value: function startZoom() {
+ var info = this.jSPlugin.jSPlugin._JSPlayM4_GetFrameInfo(0);
+
+ this.videoWidth = info.width;
+ this.videoHeight = info.height;
+ this.currentPosition.right = info.width;
+ this.currentPosition.bottom = info.height;
+ this.currentScale = 1;
+ document.getElementById("".concat(this.jSPlugin.id, "-zoom-container")).style.display = "block";
+
+ this.jSPlugin.jSPlugin._JSPlayM4_SetDisplayRegion(0, this.videoWidth, 0, this.videoHeight);
+
+ this.renderDot();
+ }
+ }, {
+ key: "stopZoom",
+ value: function stopZoom() {
+ this.currentScale = 1;
+
+ this.jSPlugin.jSPlugin._JSPlayM4_SetDisplayRegion(0, this.videoWidth, 0, this.videoHeight);
+
+ document.getElementById("".concat(this.jSPlugin.id, "-zoom-container")).style.display = "none";
+ this.renderDot();
+ }
+ }, {
+ key: "doScale",
+ value: function doScale() {
+ var currentPosition = this.currentPosition,
+ currentScale = this.currentScale;
+ currentPosition.left = currentPosition.left + currentPosition.xPercent * (currentPosition.right - currentPosition.left) - 1 / 2 * (this.videoWidth / currentScale);
+
+ if (currentPosition.left < 0) {
+ currentPosition.left = 0;
+ } else if (currentPosition.left > this.videoWidth - this.videoWidth / currentScale) {
+ currentPosition.left = this.videoWidth - this.videoWidth / currentScale;
+ }
+
+ currentPosition.right = currentPosition.left + this.videoWidth / currentScale;
+ currentPosition.top = currentPosition.top + currentPosition.yPercent * (currentPosition.bottom - currentPosition.top) - 1 / 2 * (this.videoHeight / currentScale);
+
+ if (currentPosition.top < 0) {
+ currentPosition.top = 0;
+ } else if (currentPosition.top > this.videoHeight - this.videoHeight / currentScale) {
+ currentPosition.top = this.videoHeight - this.videoHeight / currentScale;
+ }
+
+ currentPosition.bottom = currentPosition.top + this.videoHeight / currentScale; //鏁存暟鍖�
+
+ currentPosition.left = parseInt(currentPosition.left, 10);
+ currentPosition.right = parseInt(currentPosition.right, 10);
+ currentPosition.top = parseInt(currentPosition.top, 10);
+ currentPosition.bottom = parseInt(currentPosition.bottom, 10);
+ console.log("瑙嗛瀹介珮", this.videoWidth, this.videoHeight);
+ console.log("璁$畻鍚庯紝", currentPosition.left, currentPosition.right, currentPosition.top, currentPosition.bottom, currentPosition.xPercent, currentPosition.yPercent); // 娉ㄦ剰锛屽拰PC
+
+ if (currentPosition.left < currentPosition.right && currentPosition.top < currentPosition.bottom && currentPosition.bottom <= this.videoHeight && currentPosition.right <= this.videoWidth) {
+ this.jSPlugin.jSPlugin._JSPlayM4_SetDisplayRegion(currentPosition.left, currentPosition.right, currentPosition.top, currentPosition.bottom);
+ }
+
+ document.getElementById("".concat(this.jSPlugin.id, "-zoom-container")).innerHTML = "".concat(currentScale, ".0X");
+ document.getElementById("".concat(this.jSPlugin.id, "-zoom-container")).style.display = currentScale === 1 ? "none" : "inline-block";
+ }
+ }, {
+ key: "calCurrentPosition",
+ value: function calCurrentPosition(e) {
+ var currentPosition = this.currentPosition,
+ clientRect = this.clientRect;
+ currentPosition.x = e.clientX;
+ currentPosition.y = e.clientY;
+ currentPosition.xPercent = (e.clientX - clientRect.x) / clientRect.width;
+ currentPosition.yPercent = (e.clientY - clientRect.y) / clientRect.height;
+ this.doScale();
+ return;
+ }
+ }]);
+
+ return MobileZoom;
+}();
+
+var styleToString = function styleToString(obj) {
+ var styleString = "";
+ Object.keys(obj).map(function (item, index) {
+ styleString += "".concat(item, ":").concat(obj[item]).concat(index < Object.keys(obj).length - 1 ? ';' : "");
+ });
+ return styleString;
+};
+
+var MEDIAWIDTH = 500;
+var Theme = /*#__PURE__*/function () {
+ function Theme(jSPlugin) {
+ var _this = this;
+
+ _classCallCheck$1(this, Theme);
+
+ this.jSPlugin = jSPlugin;
+ this.isNeedRenderHeader = false;
+ this.isNeedRenderFooter = false;
+ this.autoFocus = 0, this.autoFocusTimer = null, this.recordTimer = null;
+ this.nextRate = 1;
+ this.showHD = false;
+ this.decoderState = {
+ state: {
+ isEditing: false,
+ play: false,
+ sound: false,
+ recordvideo: false,
+ recordCount: "00:00",
+ talk: false,
+ zoom: false,
+ pantile: false,
+ hd: false,
+ speed: false,
+ expend: false,
+ webExpend: false,
+ cloudRec: matchEzopenUrl(jSPlugin.url).type === 'cloud.rec',
+ rec: matchEzopenUrl(jSPlugin.url).type === 'rec',
+ type: matchEzopenUrl(jSPlugin.url).type
+ }
+ };
+ console.log(" matchEzopenUrl(jSPlugin.url)", matchEzopenUrl(jSPlugin.url), this.decoderState.state);
+ this.inited = false;
+ this.isMobile = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i);
+
+ if (typeof jSPlugin.isMobile !== 'undefined') {
+ this.isMobile = jSPlugin.isMobile;
+ } // 榛樿涓婚 - 鎸夐挳鍏ㄩ儴灞曠ず
+
+
+ this.themeData = emptyData.data; // 鑷�傚簲涓婚鏁版嵁
+
+ /*
+ 绉诲姩绔� & 鐩存挱 =銆� mobileLive
+ 绉诲姩绔� & 鍥炴斁鍦板潃 => mobileRec
+ PC绔� & 鐩存挱 =銆� pcLive
+ PC绔� & 鍥炴斁鍦板潃 => pcRec
+ */
+
+ if (this.jSPlugin.themeId) {
+ switch (this.jSPlugin.themeId) {
+ case 'pcLive':
+ case 'pcRec':
+ case 'mobileLive':
+ case 'mobileRec':
+ case 'security':
+ case 'voice':
+ case 'simple':
+ var ezuikitTemplateDetail = lodash.find(officeTemplateList, function (item) {
+ return item.themeId === _this.jSPlugin.themeId;
+ });
+
+ if (ezuikitTemplateDetail) {
+ this.themeData = ezuikitTemplateDetail;
+ }
+
+ this.initThemeData();
+ this.renderThemeData();
+ break;
+
+ case 'themeData':
+ this.themeData = this.jSPlugin.params.themeData;
+ this.initThemeData();
+ this.renderThemeData();
+ break;
+
+ default:
+ this.fetchThemeData(this.jSPlugin.themeId);
+ break;
+ }
+ }
+
+ if (!this.jSPlugin.Talk) {
+ this.jSPlugin.Talk = new Talk(this.jSPlugin);
+ }
+
+ addCss("".concat(this.jSPlugin.staticPath, "/speed/speed.css"));
+ addCss("".concat(this.jSPlugin.staticPath, "/css/theme.css"));
+ }
+
+ _createClass$1(Theme, [{
+ key: "fetchThemeData",
+ value: function fetchThemeData(themeId) {
+ var _this2 = this;
+
+ var url = "".concat(this.jSPlugin.env.domain, "/console/jssdk/ezopen/template/getDetail?accessToken=").concat(this.jSPlugin.accessToken, "&id=").concat(themeId);
+
+ if (window.location.hostname === "test11open.ys7.com" || window.location.hostname === "127.0.0.1" || window.location.hostname === "jianboyu.top") {
+ url = url.replace("test12open.ys7.com/console/jssdk", "test11open.ys7.com/console/jssdk");
+ }
+
+ fetch(url, {
+ method: 'GET'
+ }).then(function (response) {
+ return response.json();
+ }).then(function (data) {
+ console.log("get theme data", data);
+
+ if (data.meta.code === 0 && data.data) {
+ _this2.themeData = data.data;
+
+ if (data.data.header) {
+ _this2.themeData.header = data.data.header;
+ _this2.themeData.header.btnList = _this2.themeData.header.btnList.sort(function (a, b) {
+ return a.btnKey.split("-")[3] - b.btnKey.split("-")[3];
+ });
+ }
+
+ if (data.data.footer) {
+ _this2.themeData.footer = data.data.footer;
+ _this2.themeData.footer.btnList = _this2.themeData.footer.btnList.sort(function (a, b) {
+ return a.btnKey.split("-")[3] - b.btnKey.split("-")[3];
+ });
+ }
+
+ _this2.initThemeData();
+
+ _this2.renderThemeData();
+ }
+ })["catch"](function (error) {
+ _this2.renderThemeData();
+ });
+ }
+ }, {
+ key: "changeTheme",
+ value: function changeTheme(options) {
+ var _this3 = this;
+
+ if (typeof options === 'string') {
+ this.jSPlugin.themeId = options;
+
+ switch (this.jSPlugin.themeId) {
+ case 'pcLive':
+ case 'pcRec':
+ case 'mobileLive':
+ case 'mobileRec':
+ case 'security':
+ case 'voice':
+ case 'simple':
+ var ezuikitTemplateDetail = lodash.find(officeTemplateList, function (item) {
+ return item.themeId === _this3.jSPlugin.themeId;
+ });
+
+ if (ezuikitTemplateDetail) {
+ this.themeData = ezuikitTemplateDetail;
+ }
+
+ this.initThemeData();
+ this.renderThemeData();
+ break;
+
+ default:
+ this.fetchThemeData(options);
+ break;
+ }
+ } else if (_typeof(options) === 'object') {
+ this.themeData = options;
+ this.initThemeData();
+ this.renderThemeData();
+
+ if (this.decoderState.state.isEditing) {
+ this.editStart();
+ }
+ }
+
+ if (this.jSPlugin && this.jSPlugin.handleThemeChange) {
+ this.jSPlugin.handleThemeChange(options);
+ }
+ }
+ }, {
+ key: "renderThemeData",
+ value: function renderThemeData() {
+ var _this4 = this;
+
+ var _this$themeData = this.themeData,
+ header = _this$themeData.header,
+ footer = _this$themeData.footer;
+
+ if (this.isNeedRenderHeader && header) {
+ document.getElementById("".concat(this.jSPlugin.id, "-headControl")).style.background = header.backgroundColor.replace("-diy", "");
+ document.getElementById("".concat(this.jSPlugin.id, "-headControl")).style.color = header.color.replace("-diy", "");
+ header.btnList.map(function (item, index) {
+ if (item.isrender) {
+ _this4.setDecoderState(_defineProperty({}, item.iconId, _this4.decoderState.state[item.iconId]));
+ }
+ });
+ }
+
+ if (this.isNeedRenderFooter && footer) {
+ document.getElementById("".concat(this.jSPlugin.id, "-audioControls")).style.background = footer.backgroundColor.replace("-diy", "");
+ document.getElementById("".concat(this.jSPlugin.id, "-audioControls")).style.color = footer.color.replace("-diy", "");
+ footer.btnList.map(function (item, index) {
+ if (item.isrender) {
+ _this4.setDecoderState(_defineProperty({}, item.iconId, _this4.decoderState.state[item.iconId]));
+ }
+
+ if (item.iconId === "play" && item.defaultActive) {
+ var checkTimer = setInterval(function () {
+ if (window.EZUIKit[_this4.jSPlugin.id].state.EZUIKitPlayer.init) {
+ clearInterval(checkTimer);
+
+ _this4.jSPlugin.play();
+ }
+ }, 50);
+ }
+ }); // 鍒ゆ柇鏍囨竻楂樻竻
+
+ if (this.jSPlugin.url.indexOf("hd.live") !== -1) {
+ this.setDecoderState({
+ hd: true
+ });
+ } // 鍒ゆ柇鏄惁鑷姩闅愯棌鎺т欢
+
+
+ if (this.themeData.autoFocus > 0) {
+ this.autoFocus = parseInt(this.themeData.autoFocus);
+ this.startAutoFocus();
+ document.getElementById("".concat(this.jSPlugin.id, "-wrap")).addEventListener("click", function () {
+ _this4.stopAutoFocus();
+ }); // document.getElementById(`${this.jSPlugin.id}-wrap`).addEventListener("mouseout", ()=>{
+ // console.log("寮�鍚嚜鍔ㄩ殣钘�")
+ // this.startAutoFocus();
+ // })
+ }
+ } else {
+ var _checkTimer = setInterval(function () {
+ if (window.EZUIKit[_this4.jSPlugin.id].state.EZUIKitPlayer.init) {
+ clearInterval(_checkTimer);
+
+ _this4.jSPlugin.play();
+ }
+ }, 50);
+ }
+
+ var isNeedRoom = lodash.findIndex(this.themeData.footer.btnList, function (v) {
+ return v.iconId === 'zoom' && v.isrender > 0;
+ }) >= 0;
+
+ if (isNeedRoom) {
+ if (this.isMobile) {
+ this.jSPlugin.Zoom = new MobileZoom(this.jSPlugin);
+ } else {
+ this.jSPlugin.Zoom = new Zoom(this.jSPlugin);
+ }
+ }
+
+ var checkTimer = setInterval(function () {
+ if (window.EZUIKit[_this4.jSPlugin.id].state.EZUIKitPlayer.init) {
+ clearInterval(checkTimer); // 鎵ц涓�娆eSize
+
+ _this4.jSPlugin.reSize(_this4.jSPlugin.params.width, _this4.jSPlugin.params.height);
+ }
+ }, 50);
+ }
+ }, {
+ key: "setDecoderState",
+ value: function setDecoderState(options) {
+ var _this5 = this;
+
+ var _this$themeData2 = this.themeData,
+ header = _this$themeData2.header,
+ footer = _this$themeData2.footer;
+ Object.keys(options).map(function (item, index) {
+ var color = "#FFFFFF";
+ var activeColor = "#FFFFFF";
+
+ var _index = header.btnList.findIndex(function (i) {
+ return i.iconId === item;
+ });
+
+ if (_index === -1) {
+ color = footer.color.replace("-diy", "");
+ activeColor = footer.activeColor.replace("-diy", "");
+ } else {
+ color = header.color.replace("-diy", ""); // 鎸夐挳鐩稿叧鐨勬縺娲婚鑹茬粺涓�浣跨敤搴曢儴鐨�
+
+ activeColor = footer.activeColor.replace("-diy", "");
+ }
+
+ switch (item) {
+ case 'play':
+ if (options[item]) {
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-play"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-play-content")).children[0].children[0].style = "display:inline-block";
+ document.getElementById("".concat(_this5.jSPlugin.id, "-play-content")).children[0].children[1].style = "display:none";
+ document.getElementById("".concat(_this5.jSPlugin.id, "-play")).className = options[item] ? 'active' : '';
+ document.getElementById("".concat(_this5.jSPlugin.id, "-play-content")).childNodes[0].children[0].style.fill = options[item] ? activeColor : color;
+ }
+ } else {
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-play"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-play-content")).children[0].children[1].style = "display:inline-block";
+ document.getElementById("".concat(_this5.jSPlugin.id, "-play-content")).children[0].children[0].style = "display:none";
+ document.getElementById("".concat(_this5.jSPlugin.id, "-play")).className = options[item] ? 'active' : '';
+ document.getElementById("".concat(_this5.jSPlugin.id, "-play-content")).childNodes[0].children[1].style.fill = options[item] ? activeColor : color;
+ }
+ }
+
+ break;
+
+ case 'sound':
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-sound"))) {
+ if (options[item]) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-sound-content")).children[0].children[1].style = "display:inline-block";
+ document.getElementById("".concat(_this5.jSPlugin.id, "-sound-content")).children[0].children[0].style = "display:none";
+ document.getElementById("".concat(_this5.jSPlugin.id, "-sound")).className = options[item] ? 'active' : '';
+ document.getElementById("".concat(_this5.jSPlugin.id, "-sound-content")).childNodes[0].children[1].style.fill = options[item] ? activeColor : color;
+ } else {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-sound-content")).children[0].children[0].style = "display:inline-block";
+ document.getElementById("".concat(_this5.jSPlugin.id, "-sound-content")).children[0].children[1].style = "display:none";
+ document.getElementById("".concat(_this5.jSPlugin.id, "-sound")).className = options[item] ? 'active' : '';
+ document.getElementById("".concat(_this5.jSPlugin.id, "-sound-content")).childNodes[0].children[0].style.fill = options[item] ? activeColor : color;
+ }
+ }
+
+ break;
+
+ case 'recordvideo':
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-recordvideo"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-recordvideo")).className = options[item] ? 'active' : '';
+ document.getElementById("".concat(_this5.jSPlugin.id, "-recordvideo-content")).childNodes[0].style.fill = options[item] ? activeColor : color; // 瀹氭椂鍣ㄥ鐞�
+
+ if (options[item]) {
+ _this5.countTime('add', 0); // this.recordTimer = setInterval(() => {
+ // }, 1000);
+
+ } else {
+ _this5.countTime('destroy', 0); // clearInterval(this.recordTimer);
+
+ }
+ }
+
+ break;
+
+ case 'talk':
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-talk"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-talk")).className = options[item] ? 'active' : '';
+ document.getElementById("".concat(_this5.jSPlugin.id, "-talk-content")).childNodes[1].style.fill = options[item] ? activeColor : color;
+ }
+
+ break;
+
+ case 'zoom':
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-zoom"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-zoom")).className = options[item] ? 'active' : '';
+ document.getElementById("".concat(_this5.jSPlugin.id, "-zoom-content")).childNodes[1].style.fill = options[item] ? activeColor : color;
+ }
+
+ break;
+
+ case 'pantile':
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-pantile"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-pantile")).className = options[item] ? 'active' : '';
+ document.getElementById("".concat(_this5.jSPlugin.id, "-pantile-content")).childNodes[0].style.fill = options[item] ? activeColor : color;
+ }
+
+ break;
+
+ case 'webExpend':
+ if (options[item]) {
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-webExpend"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-webExpend-content")).children[0].children[1].style = "display:inline-block";
+ document.getElementById("".concat(_this5.jSPlugin.id, "-webExpend-content")).children[0].children[0].style = "display:none";
+ } // 鍏ㄥ睆缃伆
+
+
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-expend"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-expend")).className = "disabled";
+ }
+ } else {
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-webExpend"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-webExpend-content")).children[0].children[0].style = "display:inline-block";
+ document.getElementById("".concat(_this5.jSPlugin.id, "-webExpend-content")).children[0].children[1].style = "display:none";
+ } // 鍏ㄥ睆缃伆
+
+
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-expend"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-expend")).className = "";
+ }
+ }
+
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-webExpend"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-webExpend")).className = options[item] ? 'active' : '';
+ document.getElementById("".concat(_this5.jSPlugin.id, "-webExpend-content")).childNodes[0].childNodes[0].style.fill = options[item] ? activeColor : color;
+ document.getElementById("".concat(_this5.jSPlugin.id, "-webExpend-content")).childNodes[0].childNodes[1].style.fill = options[item] ? activeColor : color;
+ }
+
+ break;
+
+ case 'capturePicture':
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-capturePicture"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-capturePicture")).className = options[item] ? 'active' : '';
+ document.getElementById("".concat(_this5.jSPlugin.id, "-capturePicture-content")).childNodes[0].style.fill = options[item] ? activeColor : color;
+ }
+
+ break;
+
+ case 'expend':
+ if (options[item]) {
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-expend"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-expend-content")).children[0].children[1].style = "display:inline-block";
+ document.getElementById("".concat(_this5.jSPlugin.id, "-expend-content")).children[0].children[0].style = "display:none";
+ } // 缃戠珯鍏ㄥ睆缃伆
+
+
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-webExpend"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-webExpend")).className = "disabled";
+ }
+ } else {
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-expend"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-expend-content")).children[0].children[0].style = "display:inline-block";
+ document.getElementById("".concat(_this5.jSPlugin.id, "-expend-content")).children[0].children[1].style = "display:none";
+ } // 缃戠珯鍏ㄥ睆缃伆
+
+
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-webExpend"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-webExpend")).className = "";
+ }
+ }
+
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-expend"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-expend")).className = options[item] ? 'active' : '';
+ document.getElementById("".concat(_this5.jSPlugin.id, "-expend-content")).childNodes[0].childNodes[0].style.fill = options[item] ? activeColor : color;
+ document.getElementById("".concat(_this5.jSPlugin.id, "-expend-content")).childNodes[0].childNodes[1].style.fill = options[item] ? activeColor : color;
+ }
+
+ break;
+
+ case 'hd':
+ if (options[item]) {
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-hd"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-hd-content")).children[1].children[0].style = "display:block";
+ document.getElementById("".concat(_this5.jSPlugin.id, "-hd-content")).children[1].children[1].style = "display:none";
+ }
+ } else {
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-hd"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-hd-content")).children[1].children[1].style = "display:block";
+ document.getElementById("".concat(_this5.jSPlugin.id, "-hd-content")).children[1].children[0].style = "display:none";
+ }
+ }
+
+ break;
+
+ case 'speed':
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-speed"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-speed-content")).children[1].children[0].style.color = options[item] ? activeColor : color;
+ document.getElementById("".concat(_this5.jSPlugin.id, "-speed-content")).children[1].children[0].style.borderColor = options[item] ? activeColor : color;
+ }
+
+ if (_this5.isMobile && options[item]) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-select-mask")).style.display = "block";
+ } else {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-select-mask")).style.display = "none";
+ }
+
+ break;
+
+ case 'cloudRec':
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-cloudRec"))) {
+ console.log("document.getElementById(`${this.jSPlugin.id}-cloudRec-content`)", document.getElementById("".concat(_this5.jSPlugin.id, "-cloudRec")));
+ document.getElementById("".concat(_this5.jSPlugin.id, "-cloudRec")).className = options[item] ? 'active' : '';
+ document.getElementById("".concat(_this5.jSPlugin.id, "-cloudRec-content")).children[0].children[0].style.fill = options[item] ? activeColor : color;
+ }
+
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-rec"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-rec")).className = options[item] ? 'active' : '';
+ document.getElementById("".concat(_this5.jSPlugin.id, "-rec-content")).children[0].children[0].style.fill = options[item] ? color : activeColor;
+ }
+
+ break;
+
+ case 'rec':
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-cloudRec"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-cloudRec")).className = options[item] ? 'active' : '';
+ document.getElementById("".concat(_this5.jSPlugin.id, "-cloudRec-content")).children[0].children[0].style.fill = options[item] ? color : activeColor;
+ }
+
+ if (document.getElementById("".concat(_this5.jSPlugin.id, "-rec"))) {
+ document.getElementById("".concat(_this5.jSPlugin.id, "-rec")).className = options[item] ? 'active' : '';
+ document.getElementById("".concat(_this5.jSPlugin.id, "-rec-content")).children[0].children[0].style.fill = options[item] ? activeColor : color;
+ }
+
+ break;
+ }
+
+ _this5.decoderState.state = Object.assign(_this5.decoderState.state, options);
+ });
+ }
+ }, {
+ key: "startAutoFocus",
+ value: function startAutoFocus() {
+ var _this6 = this;
+
+ console.log("寮�濮嬭嚜鍔ㄩ殣钘�", this.autoFocus);
+ var autoFocus = this.autoFocus; // if(document.getElementById(`${this.jSPlugin.id}-audioControls`)) {
+
+ if (this.autoFocusTimer) {
+ clearTimeout(this.autoFocusTimer);
+ }
+
+ this.autoFocusTimer = setTimeout(function () {
+ if (document.getElementById("".concat(_this6.jSPlugin.id, "-audioControls"))) {
+ document.getElementById("".concat(_this6.jSPlugin.id, "-audioControls")).style.opacity = 0;
+ }
+ }, autoFocus * 1000);
+ }
+ }, {
+ key: "stopAutoFocus",
+ value: function stopAutoFocus() {
+ console.log("缁撴潫鑷姩闅愯棌");
+
+ if (document.getElementById("".concat(this.jSPlugin.id, "-audioControls"))) {
+ document.getElementById("".concat(this.jSPlugin.id, "-audioControls")).style.opacity = 1;
+ }
+
+ if (this.autoFocusTimer) {
+ clearTimeout(this.autoFocusTimer);
+ }
+
+ this.startAutoFocus();
+ }
+ }, {
+ key: "toString",
+ value: function toString() {
+ return "".concat(this.coreX, "-").concat(this.coreY);
+ }
+ }, {
+ key: "renderFooter",
+ value: function renderFooter(id, part) {
+ var _this7 = this;
+
+ // 鎾斁鍋滄
+ var objItem = this.matchBtn(id); // 绉诲姩绔笉灞曠ず鐢靛瓙鏀惧ぇ
+
+ if (this.isMobile && objItem.id === "zoom") {
+ return false;
+ }
+
+ var objDOM = document.createElement('div');
+ objDOM.className = "theme-icon-item";
+ objDOM.innerHTML = "".concat("<span id=\"".concat(this.jSPlugin.id, "-").concat(objItem.id, "\" style=\"position:relative;\">") // +`<span id="${this.jSPlugin.id}-${objItem.id}-left" class="ezuikit-theme-icon" title="宸︾Щ" style="position: absolute;top: calc(50% - 26px);left: -6px;display: none;"><svg fill="#ffffff" version="1.1" xmlns="http://www.w3.org/2000/svg" width="12" height="24" viewBox="0 0 10 15" style="background:#00000080;"><path d="M7.4,10V5.3c0-0.3-0.3-0.6-0.6-0.6c-0.1,0-0.3,0.1-0.4,0.2L3.7,7.4c-0.2,0.2-0.3,0.6,0,0.8 c0,0,0,0,0.1,0.1l2.7,2.2c0.2,0.2,0.6,0.2,0.8-0.1C7.3,10.3,7.4,10.2,7.4,10z"></path></svg></span>`
+ + "<div id=\"".concat(this.jSPlugin.id, "-").concat(objItem.id, "-content\" title=\"").concat(objItem.title, "\" style=\"height:").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "px;display: flex;align-items: center;position:relative;\">")).concat(objItem.domString, "</div>") // +`<span id="${this.jSPlugin.id}-${objItem.id}-right" class="ezuikit-theme-icon" title="鍙崇Щ" style="position: absolute;top: calc(50% - 26px);left: calc(100% - 0px);display: none;"><svg fill="#ffffff" version="1.1" xmlns="http://www.w3.org/2000/svg" width="12" height="24" viewBox="0 0 10 15" style="background:#00000080"><path d="M3.4,5.2v4.7c0,0.3,0.3,0.6,0.6,0.6c0.1,0,0.3-0.1,0.4-0.2l2.7-2.5c0.2-0.2,0.3-0.6,0-0.8 c0,0,0,0-0.1-0.1L4.4,4.8C4.1,4.6,3.8,4.6,3.6,4.9C3.5,5,3.4,5.1,3.4,5.2z"></path></svg></span>`
+ + '</span>';
+
+ objDOM.onclick = function (e) {
+ if (_this7.decoderState.state.isEditing) {
+ return false;
+ }
+
+ objItem.onclick(e);
+ };
+
+ if (objItem.onmouseenter) {
+ objDOM.onmouseenter = function (e) {
+ if (_this7.decoderState.state.isEditing) {
+ return false;
+ }
+
+ objItem.onmouseenter(e);
+ };
+ }
+
+ if (objItem.onmouseleave) {
+ objDOM.onmouseleave = function (e) {
+ if (_this7.decoderState.state.isEditing) {
+ return false;
+ }
+
+ objItem.onmouseleave(e);
+ };
+ }
+
+ var toLeft = document.createElement('span');
+ toLeft.className = "icon-move left";
+ toLeft.innerHTML = "<span id=\"".concat(this.jSPlugin.id, "-").concat(objItem.id, "-left\" title=\"\u5DE6\u79FB\" style=\"position: absolute;top: calc(50% - 10px);left: -4px;\"><svg fill=\"#ffffff\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"24\" viewBox=\"0 0 10 15\" style=\"background:#00000080;\"><path d=\"M7.4,10V5.3c0-0.3-0.3-0.6-0.6-0.6c-0.1,0-0.3,0.1-0.4,0.2L3.7,7.4c-0.2,0.2-0.3,0.6,0,0.8 c0,0,0,0,0.1,0.1l2.7,2.2c0.2,0.2,0.6,0.2,0.8-0.1C7.3,10.3,7.4,10.2,7.4,10z\"></path></svg></span>");
+
+ toLeft.onclick = function () {
+ _this7.editIcon(objItem.id, 'left', 'footer');
+ };
+
+ objDOM.appendChild(toLeft);
+ var toRight = document.createElement('span');
+ toRight.className = "icon-move right";
+ toRight.innerHTML = "<span id=\"".concat(this.jSPlugin.id, "-").concat(objItem.id, "-right\" class=\"ezuikit-theme-icon\" title=\"\u53F3\u79FB\" style=\"position: absolute;top: calc(50% - 10px);left: calc(100% - 8px);\"><svg fill=\"#ffffff\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"24\" viewBox=\"0 0 10 15\" style=\"background:#00000080\"><path d=\"M3.4,5.2v4.7c0,0.3,0.3,0.6,0.6,0.6c0.1,0,0.3-0.1,0.4-0.2l2.7-2.5c0.2-0.2,0.3-0.6,0-0.8 c0,0,0,0-0.1-0.1L4.4,4.8C4.1,4.6,3.8,4.6,3.6,4.9C3.5,5,3.4,5.1,3.4,5.2z\"></path></svg></span>");
+
+ toRight.onclick = function () {
+ _this7.editIcon(objItem.id, 'right', 'footer');
+ };
+
+ objDOM.appendChild(toRight);
+ var toClose = document.createElement('span');
+ toClose.className = "icon-move close";
+ toClose.innerHTML = "<span id=\"".concat(objItem.id, "-remove\" class=\"ezuikit-theme-icon\" title=\"\u79FB\u9664\" style=\"position: absolute;top: -10px;right: -10px;\">") + '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 15 15">' + '<circle style="fill-rule:evenodd;clip-rule:evenodd;fill-opacity:0.8011;" cx="7.5" cy="7.6" r="7" />' + '<rect x="3.9" y="3.5" class="st1" style="fill:none;" width="8.1" height="8.1" />' + '<line style="fill:none;stroke:#ffffff;stroke-width:0.5833;stroke-linecap:round;" x1="4.9" y1="5" x2="10" y2="10.1" />' + '<line style="fill:none;stroke:#ffffff;stroke-width:0.5833;stroke-linecap:round;" x1="4.9" y1="10.1" x2="10" y2="5" />' + '</svg>' + '</span>';
+
+ toClose.onclick = function () {
+ _this7.editIcon(objItem.id, 'delete', 'footer');
+ };
+
+ objDOM.appendChild(toClose);
+
+ if (part === 'left') {
+ document.getElementById("".concat(this.jSPlugin.id, "-audioControls")).childNodes[0].appendChild(objDOM);
+ } else {
+ document.getElementById("".concat(this.jSPlugin.id, "-audioControls")).childNodes[1].appendChild(objDOM);
+ } // 鎴浘
+
+ }
+ }, {
+ key: "editIcon",
+ value: function editIcon(id, type, area) {
+ console.log("缂栬緫缁勪欢", id, type, area);
+ var newThemeData = this.themeData;
+ console.log("themeData", this.themeData);
+ var btnList = this.themeData[area].btnList;
+
+ var _index = lodash.findIndex(btnList, function (item) {
+ return item.iconId === id;
+ });
+
+ var tmp = btnList[_index];
+
+ switch (type) {
+ case 'delete':
+ // btnList.splice(_index, 1);
+ // 闄愬埗鍥炴斁蹇呴』閫変腑涓�绉嶄粙璐�
+ if (id === "rec") {
+ if (lodash.findIndex(btnList, function (item) {
+ return item.iconId === "cloudRec" && item.isrender == 1;
+ }) === -1) {
+ if (this.jSPlugin.Message) {
+ this.jSPlugin.Message["default"]("蹇呴』閫変腑涓�绉嶅瓨鍌ㄤ粙璐�");
+ }
+
+ return false;
+ }
+ } else if (id === "cloudRec") {
+ if (lodash.findIndex(btnList, function (item) {
+ return item.iconId === "rec" && item.isrender == 1;
+ }) === -1) {
+ if (this.jSPlugin.Message) {
+ this.jSPlugin.Message["default"]("蹇呴』閫変腑涓�绉嶅瓨鍌ㄤ粙璐�");
+ }
+
+ return false;
+ }
+ }
+
+ btnList[_index].isrender = 0;
+ break;
+
+ case 'right':
+ var nextRightBtnIndex = -1;
+
+ for (var i = _index + 1; i < btnList.length; i++) {
+ if (btnList[i].part === btnList[_index].part && btnList[i].isrender == 1) {
+ nextRightBtnIndex = i;
+ break;
+ }
+ }
+
+ if (nextRightBtnIndex !== -1) {
+ btnList[_index] = btnList[nextRightBtnIndex];
+ btnList[nextRightBtnIndex] = tmp;
+ }
+
+ break;
+
+ case 'left':
+ var nextLeftBtnIndex = -1;
+
+ for (var _i = _index - 1; _i >= 0; _i--) {
+ if (btnList[_i].part === btnList[_index].part && btnList[_i].isrender == 1) {
+ nextLeftBtnIndex = _i;
+ break;
+ }
+ }
+
+ if (nextLeftBtnIndex !== -1) {
+ btnList[_index] = btnList[nextLeftBtnIndex];
+ btnList[nextLeftBtnIndex] = tmp;
+ }
+
+ break;
+ }
+
+ console.log("new btnList", btnList);
+ newThemeData[area].btnList = btnList; //this.renderThemeData();
+
+ this.changeTheme(newThemeData);
+ }
+ }, {
+ key: "renderHeader",
+ value: function renderHeader(id, part) {
+ var _this8 = this;
+
+ // 鎾斁鍋滄
+ var objItem = this.matchBtn(id);
+ var objDOM = document.createElement('div');
+ objDOM.className = "theme-icon-item";
+ objDOM.innerHTML = "".concat("<span id=\"".concat(this.jSPlugin.id, "-").concat(objItem.id, "\" style=\"position:relative\";>") // +`<span id="${this.jSPlugin.id}-${objItem.id}-left" title="宸︾Щ" style="position: absolute;top: calc(50% - 10px);left: -6px;display: none;"><svg fill="#ffffff" version="1.1" xmlns="http://www.w3.org/2000/svg" width="12" height="24" viewBox="0 0 10 15" style="background:#00000080;"><path d="M7.4,10V5.3c0-0.3-0.3-0.6-0.6-0.6c-0.1,0-0.3,0.1-0.4,0.2L3.7,7.4c-0.2,0.2-0.3,0.6,0,0.8 c0,0,0,0,0.1,0.1l2.7,2.2c0.2,0.2,0.6,0.2,0.8-0.1C7.3,10.3,7.4,10.2,7.4,10z"></path></svg></span>`
+ + "<span id=\"".concat(this.jSPlugin.id, "-").concat(objItem.id, "-content\" title=\"").concat(objItem.title, "\" style=\"display:inline-block;height:").concat(this.width > MEDIAWIDTH ? 48 : 32, "px;\">")).concat(objItem.domString, "</span>") //+`<span id="${this.jSPlugin.id}-${objItem.id}-right" title="鍙崇Щ" style="position: absolute;top: calc(50% - 10px);left: calc(100% - 6px);display: none;"><svg fill="#ffffff" version="1.1" xmlns="http://www.w3.org/2000/svg" width="12" height="24" viewBox="0 0 10 15" style="background:#00000080"><path d="M3.4,5.2v4.7c0,0.3,0.3,0.6,0.6,0.6c0.1,0,0.3-0.1,0.4-0.2l2.7-2.5c0.2-0.2,0.3-0.6,0-0.8 c0,0,0,0-0.1-0.1L4.4,4.8C4.1,4.6,3.8,4.6,3.6,4.9C3.5,5,3.4,5.1,3.4,5.2z"></path></svg></span>`
+ + "<span id=\"".concat(this.jSPlugin.id, "-").concat(objItem.id, "-remove\" title=\"\u79FB\u9664\" style=\"position: absolute;top: -6px;left: 38px;display: none;\">") + '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 15 15">' + '<circle style="fill-rule:evenodd;clip-rule:evenodd;fill-opacity:0.8011;" cx="7.5" cy="7.6" r="7" />' + '<rect x="3.9" y="3.5" class="st1" style="fill:none;" width="8.1" height="8.1" />' + '<line style="fill:none;stroke:#ffffff;stroke-width:0.5833;stroke-linecap:round;" x1="4.9" y1="5" x2="10" y2="10.1" />' + '<line style="fill:none;stroke:#ffffff;stroke-width:0.5833;stroke-linecap:round;" x1="4.9" y1="10.1" x2="10" y2="5" />' + '</svg>' + '</span>' + '</span>'; // var toLeft = document.createElement('span');
+ // toLeft.innerHTML = +`<span id="${this.jSPlugin.id}-${objItem.id}-left" title="宸︾Щ" style="position: absolute;top: calc(50% - 10px);left: -6px;display: none;"><svg fill="#ffffff" version="1.1" xmlns="http://www.w3.org/2000/svg" width="12" height="24" viewBox="0 0 10 15" style="background:#00000080;"><path d="M7.4,10V5.3c0-0.3-0.3-0.6-0.6-0.6c-0.1,0-0.3,0.1-0.4,0.2L3.7,7.4c-0.2,0.2-0.3,0.6,0,0.8 c0,0,0,0,0.1,0.1l2.7,2.2c0.2,0.2,0.6,0.2,0.8-0.1C7.3,10.3,7.4,10.2,7.4,10z"></path></svg></span>`;
+ // toLeft.onclick = () => {console.log("宸︾Щ鍔�")};
+
+ objDOM.onclick = function (e) {
+ if (_this8.decoderState.state.isEditing) {
+ return false;
+ }
+
+ objItem.onclick(e);
+ }; // var toLeft = document.createElement('span');
+ // toLeft.className = "icon-move left";
+ // toLeft.innerHTML = `<span id="${this.jSPlugin.id}-${objItem.id}-left" title="宸︾Щ" style="position: absolute;top: calc(50% - 10px);left: -4px;"><svg fill="#ffffff" version="1.1" xmlns="http://www.w3.org/2000/svg" width="12" height="24" viewBox="0 0 10 15" style="background:#00000080;"><path d="M7.4,10V5.3c0-0.3-0.3-0.6-0.6-0.6c-0.1,0-0.3,0.1-0.4,0.2L3.7,7.4c-0.2,0.2-0.3,0.6,0,0.8 c0,0,0,0,0.1,0.1l2.7,2.2c0.2,0.2,0.6,0.2,0.8-0.1C7.3,10.3,7.4,10.2,7.4,10z"></path></svg></span>`;
+ // toLeft.onclick = () => {this.editIcon(objItem.id,'left','header')};
+ // objDOM.appendChild(toLeft);
+ // var toRight = document.createElement('span');
+ // toRight.className = "icon-move right";
+ // toRight.innerHTML = `<span id="${this.jSPlugin.id}-${objItem.id}-right" class="ezuikit-theme-icon" title="鍙崇Щ" style="position: absolute;top: calc(50% - 10px);left: calc(100% - 8px);"><svg fill="#ffffff" version="1.1" xmlns="http://www.w3.org/2000/svg" width="12" height="24" viewBox="0 0 10 15" style="background:#00000080"><path d="M3.4,5.2v4.7c0,0.3,0.3,0.6,0.6,0.6c0.1,0,0.3-0.1,0.4-0.2l2.7-2.5c0.2-0.2,0.3-0.6,0-0.8 c0,0,0,0-0.1-0.1L4.4,4.8C4.1,4.6,3.8,4.6,3.6,4.9C3.5,5,3.4,5.1,3.4,5.2z"></path></svg></span>`;
+ // toRight.onclick = () => {this.editIcon(objItem.id,'right','header')};
+ // objDOM.appendChild(toRight);
+
+
+ var toClose = document.createElement('span');
+ toClose.className = "icon-move close";
+ toClose.innerHTML = "<span id=\"".concat(objItem.id, "-remove\" class=\"ezuikit-theme-icon\" title=\"\u79FB\u9664\" style=\"position: absolute;top: -6px;right: -6px;\">") + '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 15 15">' + '<circle style="fill-rule:evenodd;clip-rule:evenodd;fill-opacity:0.8011;" cx="7.5" cy="7.6" r="7" />' + '<rect x="3.9" y="3.5" class="st1" style="fill:none;" width="8.1" height="8.1" />' + '<line style="fill:none;stroke:#ffffff;stroke-width:0.5833;stroke-linecap:round;" x1="4.9" y1="5" x2="10" y2="10.1" />' + '<line style="fill:none;stroke:#ffffff;stroke-width:0.5833;stroke-linecap:round;" x1="4.9" y1="10.1" x2="10" y2="5" />' + '</svg>' + '</span>';
+
+ toClose.onclick = function () {
+ _this8.editIcon(objItem.id, 'delete', 'header');
+ };
+
+ objDOM.appendChild(toClose); // objDOM.appendChild(toLeft);
+
+ if (part === 'left') {
+ document.getElementById("".concat(this.jSPlugin.id, "-headControl")).childNodes[0].appendChild(objDOM);
+ } else {
+ document.getElementById("".concat(this.jSPlugin.id, "-headControl")).childNodes[1].appendChild(objDOM);
+ }
+ }
+ }, {
+ key: "countTime",
+ value: function countTime(type) {
+ var start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
+ var that = this;
+
+ if (!document.getElementById(this.jSPlugin.id + "time-area")) {
+ var recordDOM = document.createElement("div");
+ recordDOM.id = this.jSPlugin.id + "time-area";
+ recordDOM.className = "time-area";
+ recordDOM.innerHTML = "<span class=\"dot\"></span><span class=\"value\">00:00</span>";
+
+ if (document.getElementById("".concat(this.jSPlugin.id, "-ez-iframe-footer-container"))) {
+ document.getElementById("".concat(this.jSPlugin.id, "-ez-iframe-footer-container")).appendChild(recordDOM);
+ }
+ }
+
+ if (this.countTimer) {
+ clearInterval(this.countTimer);
+ }
+
+ if (type === 'add') {
+ var i = start;
+ document.getElementById(that.jSPlugin.id + "time-area").style.display = 'flex';
+ this.countTimer = setInterval(function () {
+ ++i;
+ document.getElementById(that.jSPlugin.id + "time-area").children[1].innerHTML = formatSeconds(i);
+ }, 1000);
+ } else if (type === 'destroy') {
+ if (this.countTimer) {
+ clearInterval(this.countTimer);
+ }
+ this.countTimer = undefined;
+
+ if (document.getElementById(that.jSPlugin.id + "time-area")) {
+ document.getElementById(that.jSPlugin.id + "time-area").children[1].innerHTML = '00:00';
+ document.getElementById(that.jSPlugin.id + "time-area").style.display = 'none';
+ }
+ } //灏嗙鏁拌浆鎹负鏃跺垎绉掓牸寮�
+
+
+ function formatSeconds(value) {
+ var theTime = parseInt(value); // 绉�
+
+ var middle = 0; // 鍒�
+
+ var hour = 0; // 灏忔椂
+
+ var secondV = '00';
+ var minV = '00';
+ var hourV = '00';
+
+ if (theTime > 59) {
+ middle = parseInt(theTime / 60);
+ theTime = parseInt(theTime % 60);
+
+ if (middle > 59) {
+ hour = parseInt(middle / 60);
+ middle = parseInt(middle % 60);
+ }
+ }
+
+ secondV = parseInt(theTime) > 9 ? parseInt(theTime) : '0' + parseInt(theTime);
+ minV = parseInt(middle) > 9 ? parseInt(middle) : '0' + parseInt(middle);
+ hourV = parseInt(hour) > 9 ? parseInt(hour) : '0' + parseInt(hour);
+
+ if (hour > 0) {
+ return hourV + ':' + minV + ':' + secondV;
+ } else if (middle > 0) {
+ return minV + ':' + secondV;
+ } else {
+ return '00:' + secondV;
+ }
+ }
+ }
+ }, {
+ key: "matchBtn",
+ value: function matchBtn(btnId) {
+ var _this9 = this;
+
+ var _this$themeData3 = this.themeData,
+ header = _this$themeData3.header,
+ footer = _this$themeData3.footer;
+ var btnItem = {
+ title: "",
+ id: "",
+ domString: "",
+ color: "#FFFFFF",
+ activeColor: "#FFFFFF",
+ onclick: function onclick() {},
+ onmoveleft: function onmoveleft() {},
+ onmoveright: function onmoveright() {},
+ onremove: function onremove() {}
+ };
+
+ var _index = header.btnList.findIndex(function (item) {
+ return item.iconId === btnId;
+ });
+
+ if (_index === -1) {
+ btnItem.color = footer.color;
+ btnItem.backgroundColor = footer.backgroundColor;
+ btnItem.activeColor = footer.activeColor;
+ } else {
+ btnItem.color = header.color;
+ btnItem.backgroundColor = header.backgroundColor;
+ btnItem.activeColor = header.activeColor;
+ }
+
+ switch (btnId) {
+ case 'play':
+ btnItem.title = "鎾斁/缁撴潫鎾斁";
+ btnItem.id = btnId;
+ btnItem.domString = '<div style="height: 100%">' + "<svg style=\"display:none\" width=\"".concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" height=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" fill=\"").concat(btnItem.color, "\" viewBox=\"-6 -6 32 32\">\n <path id=\"Stroke-1\" class=\"st1\" d=\"M10.5,1.7c-4.9,0-8.8,4-8.8,8.8s4,8.8,8.8,8.8s8.8-4,8.8-8.8S15.4,1.7,10.5,1.7z M10.5,2.7\n c4.3,0,7.8,3.5,7.8,7.8s-3.5,7.8-7.8,7.8s-7.8-3.5-7.8-7.8S6.2,2.7,10.5,2.7z\"/>\n <path class=\"st2\" d=\"M8.7,8C9,8,9.3,8.3,9.3,8.6v3.8C9.3,12.7,9,13,8.7,13C8.3,13,8,12.7,8,12.4V8.6C8,8.3,8.3,8,8.7,8z\"/>\n <path id=\"Rectangle-Copy-10\" class=\"st2\" d=\"M12.8,8c0.3,0,0.6,0.3,0.6,0.6v3.8c0,0.3-0.3,0.6-0.6,0.6c-0.3,0-0.6-0.3-0.6-0.6V8.6\n C12.2,8.3,12.5,8,12.8,8z\"/>\n </svg>") + "<svg fill=\"".concat(btnItem.color, "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" height=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" viewBox=\"-6 -6 32 32\">") + '<path d="M13,9.8L10.1,8C9.9,7.9,9.7,7.9,9.5,7.9c-0.6,0-1,0.4-1,1v3.7c0,0.2,0.1,0.4,0.2,0.5c0.3,0.5,0.9,0.6,1.4,0.3 l2.9-1.8c0.1-0.1,0.2-0.2,0.3-0.3C13.6,10.7,13.4,10.1,13,9.8z" />' + '<path d="M10.5,1.9c-4.9,0-8.8,4-8.8,8.8c0,4.9,4,8.8,8.8,8.8s8.8-4,8.8-8.8C19.4,5.8,15.4,1.9,10.5,1.9z M10.5,18.5 c-4.3,0-7.8-3.5-7.8-7.8s3.5-7.8,7.8-7.8c4.3,0,7.8,3.5,7.8,7.8S14.9,18.5,10.5,18.5z" />' + '</svg>' + '</div>';
+
+ btnItem.onclick = function () {
+ var _this9$decoderState$s = _this9.decoderState.state,
+ play = _this9$decoderState$s.play,
+ isEditing = _this9$decoderState$s.isEditing;
+
+ if (isEditing) {
+ return false;
+ }
+
+ if (play) {
+ _this9.jSPlugin.stop();
+ } else {
+ _this9.jSPlugin.play();
+ }
+
+ _this9.setDecoderState({
+ play: !play
+ });
+ };
+
+ return btnItem;
+
+ case 'sound':
+ btnItem.title = "澹伴煶";
+ btnItem.id = btnId;
+ btnItem.domString = '<span style="height: 100%">' + "<svg style=\"display:none\" fill=\"".concat(btnItem.color, "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" height=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" viewBox=\"-6 -6 32 32\">\n <path d=\"M8.5,4.2c0.8-0.7,2.1-0.2,2.2,0.9l0,0.1v10c0,1.1-1.2,1.7-2.1,1.1l-0.1-0.1l-3.3-2.8C5,13.2,5,12.9,5.1,12.7 c0.2-0.2,0.4-0.2,0.6-0.1l0.1,0.1l3.3,2.8c0.2,0.2,0.5,0.1,0.5-0.2l0-0.1v-10c0-0.3-0.3-0.4-0.5-0.3L9.2,5L5.9,7.8 C5.6,7.9,5.3,7.9,5.1,7.7C5,7.5,5,7.3,5.1,7.1L5.2,7L8.5,4.2z\"/>\n <path d=\"M5.5,6.9C5.8,6.9,6,7.1,6,7.4c0,0.2-0.2,0.4-0.4,0.5l-0.1,0h-2C3.4,7.9,3.3,8,3.2,8.2l0,0.1v4 c0,0.2,0.1,0.3,0.3,0.3l0.1,0h2C5.8,12.5,6,12.7,6,13c0,0.2-0.2,0.4-0.4,0.5l-0.1,0h-2c-0.7,0-1.3-0.5-1.3-1.2l0-0.1v-4 c0-0.7,0.5-1.3,1.2-1.3l0.1,0H5.5z\"/>\n <path d=\"M17.4,7.9c0.2-0.2,0.5-0.2,0.7,0c0.2,0.2,0.2,0.4,0.1,0.6l-0.1,0.1l-3.8,3.8c-0.2,0.2-0.5,0.2-0.7,0 c-0.2-0.2-0.2-0.4-0.1-0.6l0.1-0.1L17.4,7.9z\"/>\n <path d=\"M13.7,7.9c0.2-0.2,0.4-0.2,0.6-0.1l0.1,0.1l3.8,3.8c0.2,0.2,0.2,0.5,0,0.7c-0.2,0.2-0.4,0.2-0.6,0.1l-0.1-0.1 l-3.7-3.8C13.5,8.4,13.5,8.1,13.7,7.9z\"/>\n </svg>") + "<svg style=\"display:inline-block\" width=\"".concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" height=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" fill=\"").concat(btnItem.color, "\" viewBox=\"-6 -6 32 32\">\n <path d=\"M13.2,7.1c0.1-0.2,0.5-0.3,0.7-0.2c1.1,0.7,1.9,2.2,1.9,3.7c0,1.6-0.7,3-1.9,3.7\n c-0.2,0.1-0.5,0.1-0.7-0.2c-0.1-0.2-0.1-0.5,0.2-0.7c0.8-0.5,1.4-1.6,1.4-2.9c0-1.3-0.6-2.4-1.4-2.9C13.1,7.6,13,7.3,13.2,7.1z\"/>\n <path d=\"M15.7,4.5c0.2-0.2,0.5-0.2,0.7-0.1C18,5.8,19,8.2,19,10.7c0,2.5-1,4.8-2.7,6.3\n c-0.2,0.2-0.5,0.2-0.7-0.1c-0.2-0.2-0.2-0.5,0.1-0.7c1.4-1.2,2.3-3.3,2.3-5.5c0-2.2-0.9-4.3-2.3-5.5C15.5,5,15.5,4.7,15.7,4.5z\"/>\n <path id=\"Stroke-5\" class=\"st1\" d=\"M8.5,4.7c0.8-0.7,2.1-0.2,2.2,0.9l0,0.1v10c0,1.1-1.2,1.7-2.1,1.1l-0.1-0.1l-3.3-2.8\n C5,13.7,5,13.4,5.1,13.2c0.2-0.2,0.4-0.2,0.6-0.1l0.1,0.1l3.3,2.8c0.2,0.2,0.5,0.1,0.5-0.2l0-0.1v-10c0-0.3-0.3-0.4-0.5-0.3l-0.1,0\n L5.9,8.3C5.6,8.4,5.3,8.4,5.1,8.2C5,8,5,7.7,5.1,7.6l0.1-0.1L8.5,4.7z\"/>\n <path d=\"M5.5,7.4C5.8,7.4,6,7.6,6,7.9c0,0.2-0.2,0.4-0.4,0.5l-0.1,0h-2c-0.2,0-0.3,0.1-0.3,0.3l0,0.1v4\n c0,0.2,0.1,0.3,0.3,0.3l0.1,0h2C5.8,13,6,13.2,6,13.5c0,0.2-0.2,0.4-0.4,0.5l-0.1,0h-2c-0.7,0-1.3-0.5-1.3-1.2l0-0.1v-4\n c0-0.7,0.5-1.3,1.2-1.3l0.1,0H5.5z\"/>\n </svg>") + '</span>';
+
+ btnItem.onclick = function () {
+ var _this9$decoderState$s2 = _this9.decoderState.state,
+ play = _this9$decoderState$s2.play,
+ sound = _this9$decoderState$s2.sound;
+
+ if (play) {
+ if (sound) {
+ _this9.jSPlugin.closeSound();
+
+ _this9.setDecoderState({
+ sound: false
+ });
+ } else {
+ _this9.jSPlugin.openSound();
+
+ _this9.setDecoderState({
+ sound: true
+ });
+ }
+ }
+ };
+
+ return btnItem;
+
+ case 'recordvideo':
+ btnItem.title = "褰曞睆";
+ btnItem.id = btnId;
+ btnItem.domString = "<svg fill=\"".concat(btnItem.color, "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" height=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" viewBox=\"-6 -6 32 32\">") + '<path d="M11.6,5.3H4.7c-1.4,0-2.5,1.1-2.5,2.5v5.9c0,1.4,1.1,2.5,2.5,2.5h6.9c1.4,0,2.5-1.1,2.5-2.5V7.7 C14.1,6.4,13,5.3,11.6,5.3z M4.7,6.3h6.9c0.8,0,1.5,0.7,1.5,1.5v5.9c0,0.8-0.7,1.5-1.5,1.5H4.7c-0.8,0-1.5-0.7-1.5-1.5V7.7 C3.3,6.9,3.9,6.3,4.7,6.3z" />' + '<path d="M16.6,6.7c0.9-0.8,2.3-0.1,2.4,1l0,0.1v5.7c0,1.2-1.3,1.9-2.3,1.2l-0.1-0.1L13.3,12 c-0.2-0.2-0.2-0.5-0.1-0.7c0.2-0.2,0.4-0.2,0.6-0.1l0.1,0.1l3.3,2.7c0.3,0.2,0.7,0.1,0.8-0.3l0-0.1V7.8c0-0.4-0.4-0.6-0.7-0.4 l-0.1,0l-3.3,2.7c-0.2,0.2-0.5,0.1-0.7-0.1c-0.2-0.2-0.1-0.5,0-0.6l0.1-0.1L16.6,6.7z" />' + '</svg>';
+
+ btnItem.onclick = function () {
+ var _this9$decoderState$s3 = _this9.decoderState.state,
+ play = _this9$decoderState$s3.play,
+ recordvideo = _this9$decoderState$s3.recordvideo;
+
+ if (play) {
+ if (recordvideo) {
+ _this9.jSPlugin.stopSave();
+
+ _this9.setDecoderState({
+ recordvideo: false
+ });
+ } else {
+ _this9.jSPlugin.startSave("".concat(new Date().getTime()));
+
+ _this9.setDecoderState({
+ recordvideo: true
+ });
+ }
+ }
+ };
+
+ return btnItem;
+
+ case 'capturePicture':
+ btnItem.title = "鎴浘";
+ btnItem.id = btnId;
+ btnItem.domString = "<svg fill=\"".concat(btnItem.color, "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" height=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" viewBox=\"-6 -6 32 32\">") + '<path d="M10.8,7.7c-2,0-3.7,1.6-3.7,3.7S8.7,15,10.8,15c2,0,3.7-1.6,3.7-3.7S12.8,7.7,10.8,7.7z M10.8,8.7c1.5,0,2.7,1.2,2.7,2.7S12.2,14,10.8,14c-1.5,0-2.7-1.2-2.7-2.7S9.3,8.7,10.8,8.7z" />' + '<path d="M8.6,3.7l-0.1,0C8,3.7,7.7,4,7.5,4.3l-1,1.7l-1.3,0C4,6.1,3.1,7,3.1,8.2v7.1 c0,1.2,0.9,2.1,2.1,2.1h11.1c1.2,0,2.1-0.9,2.1-2.1V8.2l0-0.1c-0.1-1.1-1-1.9-2.1-1.9l-1.3,0l-1.1-1.8c-0.2-0.4-0.7-0.6-1.1-0.6H8.6 z M8.6,4.7h4.2c0.1,0,0.2,0.1,0.3,0.1l1.2,2c0.1,0.2,0.3,0.2,0.4,0.2h1.6c0.6,0,1.1,0.5,1.1,1.1v7.1c0,0.6-0.5,1.1-1.1,1.1H5.1 c-0.6,0-1.1-0.5-1.1-1.1V8.2c0-0.6,0.5-1.1,1.1-1.1h1.6c0.2,0,0.3-0.1,0.4-0.2l1.2-2C8.4,4.7,8.5,4.7,8.6,4.7z" />' + '</svg>';
+
+ btnItem.onclick = function () {
+ var play = _this9.decoderState.state.play;
+
+ if (play) {
+ _this9.jSPlugin.capturePicture("".concat(new Date().getTime()));
+ } else {
+ console.log("瑙嗛鏈挱鏀撅紝鏃犳硶鎴浘");
+ }
+ };
+
+ return btnItem;
+
+ case 'talk':
+ btnItem.title = "瀵硅";
+ btnItem.id = btnId;
+ btnItem.domString = '<div></div>' + "<svg fill=\"".concat(btnItem.color, "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" height=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" viewBox=\"-6 -6 32 32\">") + '<path d="M10.1,2.7C8.5,2.7,7.2,4,7.2,5.6v5.2c0,1.6,1.3,2.9,2.9,2.9l0.2,0c1.5-0.1,2.7-1.4,2.7-2.9V5.6 C13,4,11.7,2.7,10.1,2.7z M10.1,3.7c1.1,0,1.9,0.9,1.9,1.9v5.2c0,1-0.8,1.8-1.8,1.9l-0.1,0c-1,0-1.9-0.9-1.9-1.9V5.6 C8.2,4.5,9,3.7,10.1,3.7z" />' + '<path d="M15.1,8.5c0.2,0,0.4,0.2,0.5,0.4l0,0.1v1.7c0,3-2.5,5.5-5.5,5.5c-3,0-5.4-2.3-5.5-5.3l0-0.2V9 c0-0.3,0.2-0.5,0.5-0.5c0.2,0,0.4,0.2,0.5,0.4l0,0.1v1.7c0,2.5,2,4.5,4.5,4.5c2.4,0,4.4-1.9,4.5-4.3l0-0.2V9 C14.6,8.7,14.8,8.5,15.1,8.5z" />' + '<path d="M13.5,17.7c0.3,0,0.5,0.2,0.5,0.5c0,0.2-0.2,0.4-0.4,0.5l-0.1,0h-7c-0.3,0-0.5-0.2-0.5-0.5 c0-0.2,0.2-0.4,0.4-0.5l0.1,0H13.5z" />' + '<path d="M10.1,15.2c0.2,0,0.4,0.2,0.5,0.4l0,0.1v2.5c0,0.3-0.2,0.5-0.5,0.5c-0.2,0-0.4-0.2-0.5-0.4l0-0.1 v-2.5C9.6,15.4,9.8,15.2,10.1,15.2z" />' + '</svg>';
+
+ btnItem.onclick = function () {
+ var _this9$decoderState$s4 = _this9.decoderState.state,
+ talk = _this9$decoderState$s4.talk,
+ sound = _this9$decoderState$s4.sound;
+
+ if (talk) {
+ console.log('缁撴潫瀵硅');
+
+ _this9.setDecoderState({
+ talk: false
+ });
+
+ _this9.jSPlugin.Talk.stopTalk();
+
+ var isReOpenSound = lodash.findIndex(_this9.themeData.footer.btnList, function (v) {
+ return v.iconId === 'sound' && v.isrender === 1 && v.defaultActive === 1;
+ }) > -1;
+
+ if (_this9.themeData && isReOpenSound) {
+ _this9.jSPlugin.openSound();
+
+ _this9.setDecoderState({
+ sound: true
+ });
+ }
+ } else {
+ console.log('寮�濮嬪璁�');
+
+ _this9.setDecoderState({
+ talk: true
+ });
+
+ if (sound) {
+ _this9.jSPlugin.closeSound();
+
+ _this9.setDecoderState({
+ sound: false
+ });
+ }
+
+ _this9.jSPlugin.Talk.startTalk();
+ }
+ };
+
+ return btnItem;
+
+ case 'zoom':
+ btnItem.title = "鐢靛瓙鏀惧ぇ";
+ btnItem.id = btnId;
+ btnItem.domString = '<div></div>' + "<svg fill=\"".concat(btnItem.color, "\" version=\"1.1\" id=\"\u56FE\u5C42_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n width=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" height=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" viewBox=\"5 -6 5 32\" style=\"enable-background:new 0 0 20 20.1;\" xml:space=\"preserve\">\n <path class=\"st1\" d=\"M8.8,2.6c3.5,0,6.2,2.8,6.2,6.2s-2.8,6.2-6.2,6.2s-6.2-2.8-6.2-6.2S5.3,2.6,8.8,2.6z M8.8,3.9\n c-2.8,0-5,2.2-5,5s2.2,5,5,5s5-2.2,5-5S11.5,3.9,8.8,3.9z M12.7,12.7l3.9,3.9\"/>\n <path class=\"st2\" d=\"M11.2,9.5h-5c-0.3,0-0.6-0.3-0.6-0.6s0.3-0.6,0.6-0.6h5c0.3,0,0.6,0.3,0.6,0.6S11.6,9.5,11.2,9.5z\"/>\n <path class=\"st2\" d=\"M8.7,12c-0.3,0-0.6-0.3-0.6-0.6v-5c0-0.3,0.3-0.6,0.6-0.6s0.6,0.3,0.6,0.6v5C9.3,11.8,9.1,12,8.7,12z\"/>\n <path class=\"st2\" d=\"M16.9,17.6c-0.1,0-0.3-0.1-0.4-0.2l-3.9-3.9c-0.2-0.2-0.2-0.6,0-0.8s0.6-0.2,0.8,0l3.9,3.9\n c0.2,0.2,0.2,0.6,0,0.8C17.2,17.5,17,17.6,16.9,17.6z\"/>\n </svg>");
+
+ btnItem.onclick = function () {
+ var zoom = _this9.decoderState.state.zoom;
+
+ if (zoom) {
+ console.log('缁撴潫鐢靛瓙鏀惧ぇ');
+
+ _this9.setDecoderState({
+ zoom: false
+ });
+
+ _this9.jSPlugin.Zoom.stopZoom();
+ } else {
+ console.log('寮�濮嬬數瀛愭斁澶�');
+
+ _this9.jSPlugin.Zoom.startZoom();
+
+ _this9.setDecoderState({
+ zoom: true
+ });
+ }
+ };
+
+ return btnItem;
+
+ case 'pantile':
+ btnItem.title = "浜戝彴鎺у埗";
+ btnItem.id = btnId;
+ btnItem.domString = "<svg fill=\"".concat(btnItem.color, "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" height=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" viewBox=\"-6 -6 32 32\">") + '<path d="M10.2,7.8c1.6,0,2.9,1.3,2.9,2.9s-1.3,2.9-2.9,2.9s-2.9-1.3-2.9-2.9S8.5,7.8,10.2,7.8z M10.2,8.8c-1.1,0-1.9,0.9-1.9,1.9s0.9,1.9,1.9,1.9s1.9-0.9,1.9-1.9S11.2,8.8,10.2,8.8z" />' + '<path d="M8.8,3.5c0.7-0.6,1.8-0.6,2.5-0.1l0.1,0.1l1.4,1.1c0.2,0.2,0.3,0.5,0.1,0.7 c-0.2,0.2-0.4,0.2-0.6,0.1l-0.1,0l-1.4-1.1C10.5,3.9,10,3.9,9.6,4.2L9.4,4.3L8,5.4C7.8,5.5,7.5,5.5,7.3,5.3c-0.2-0.2-0.1-0.5,0-0.6 l0.1-0.1L8.8,3.5z" />' + '<path d="M2.5,12.3c-0.6-0.7-0.6-1.8-0.1-2.5l0.1-0.1l1.1-1.4c0.2-0.2,0.5-0.3,0.7-0.1 c0.2,0.2,0.2,0.4,0.1,0.6l0,0.1l-1.1,1.4C3,10.6,3,11.1,3.2,11.5l0.1,0.1L4.4,13c0.2,0.2,0.1,0.5-0.1,0.7c-0.2,0.2-0.5,0.1-0.6,0 l-0.1-0.1L2.5,12.3z" />' + '<path d="M17.7,12.3c0.6-0.7,0.6-1.8,0.1-2.5l-0.1-0.1l-1.1-1.4c-0.2-0.2-0.5-0.3-0.7-0.1 c-0.2,0.2-0.2,0.4-0.1,0.6l0,0.1l1.1,1.4c0.3,0.4,0.3,0.9,0.1,1.3l-0.1,0.1L15.8,13c-0.2,0.2-0.1,0.5,0.1,0.7c0.2,0.2,0.5,0.1,0.6,0 l0.1-0.1L17.7,12.3z" />' + '<path d="M8.8,18.2c0.7,0.6,1.8,0.6,2.5,0.1l0.1-0.1l1.4-1.1c0.2-0.2,0.3-0.5,0.1-0.7 c-0.2-0.2-0.4-0.2-0.6-0.1l-0.1,0l-1.4,1.1c-0.4,0.3-0.9,0.3-1.3,0.1l-0.1-0.1L8,16.3c-0.2-0.2-0.5-0.1-0.7,0.1 c-0.2,0.2-0.1,0.5,0,0.6l0.1,0.1L8.8,18.2z" />' + '</svg>';
+
+ btnItem.onclick = function () {
+ var _this9$decoderState$s5 = _this9.decoderState.state,
+ pantile = _this9$decoderState$s5.pantile,
+ expend = _this9$decoderState$s5.expend;
+
+ if (!pantile) {
+ console.log('鏄剧ず浜戝彴');
+
+ if (_this9.isMobile && !expend) {
+ console.log("绉诲姩绔紝闈炲叏灞忕姸鎬佷笉灞曠ず浜戝彴"); // 绉诲姩绔紝闈炲叏灞忕姸鎬佷笉灞曠ず浜戝彴
+
+ return false;
+ }
+
+ _this9.Ptz.show();
+
+ _this9.setDecoderState({
+ pantile: true
+ });
+ } else {
+ console.log('闅愯棌浜戝彴');
+
+ _this9.Ptz.hide();
+
+ _this9.setDecoderState({
+ pantile: false
+ });
+ }
+ };
+
+ return btnItem;
+
+ case 'expend':
+ btnItem.title = "鍏ㄥ眬鍏ㄥ睆";
+ btnItem.id = btnId;
+ btnItem.domString = "<span><svg fill=\"".concat(btnItem.color, "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" height=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" viewBox=\"-6 -6 32 32\">") + '<path d="M3.4,7.6c-0.3,0-0.5-0.2-0.5-0.5V5.3c0-1.2,1-2.3,2.2-2.3h1.8c0.3,0,0.5,0.2,0.5,0.5S7.2,4.1,6.9,4.1H5.2 c-0.7,0-1.2,0.6-1.2,1.3v1.8C3.9,7.4,3.7,7.6,3.4,7.6z" />' + '<path d="M6.9,18.1H5.2c-1.2,0-2.2-1-2.2-2.2v-1.8c0-0.3,0.2-0.5,0.5-0.5s0.5,0.2,0.5,0.5v1.8c0,0.7,0.6,1.2,1.2,1.2 h1.8c0.3,0,0.5,0.2,0.5,0.5S7.2,18.1,6.9,18.1z" />' + '<path d="M15.7,18.1h-1.8c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h1.8c0.7,0,1.2-0.6,1.2-1.2v-1.8 c0-0.3,0.2-0.5,0.5-0.5s0.5,0.2,0.5,0.5v1.8C17.9,17.1,16.9,18.1,15.7,18.1z" />' + '<path d="M17.4,7.6c-0.3,0-0.5-0.2-0.5-0.5V5.3c0-0.7-0.6-1.3-1.2-1.3h-1.8c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h1.8 c1.2,0,2.2,1,2.2,2.3v1.8C17.9,7.4,17.7,7.6,17.4,7.6z" />' + '</svg>' + "<svg style=\"display:none\" width=\"".concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" height=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" fill=\"").concat(btnItem.color, "\" viewBox=\"-6 -6 32 32\">\n <path class=\"st1\" d=\"M5.7,8.1H3.9c-0.3,0-0.6-0.2-0.6-0.6S3.6,7,3.9,7h1.9c0.7,0,1.3-0.6,1.3-1.3V3.8c0-0.3,0.2-0.6,0.6-0.6\n s0.6,0.2,0.6,0.6v1.9C8.2,7,7.1,8.1,5.7,8.1z\"/>\n <path class=\"st1\" d=\"M7.6,17.7c-0.3,0-0.6-0.2-0.6-0.6v-1.9c0-0.7-0.6-1.3-1.3-1.3H3.9c-0.3,0-0.6-0.2-0.6-0.6s0.2-0.6,0.6-0.6h1.9\n c1.3,0,2.4,1.1,2.4,2.4v1.9C8.2,17.5,7.9,17.7,7.6,17.7z\"/>\n <path class=\"st1\" d=\"M13.4,17.7c-0.3,0-0.6-0.2-0.6-0.6v-1.9c0-1.3,1.1-2.4,2.4-2.4h1.9c0.3,0,0.6,0.2,0.6,0.6S17.5,14,17.2,14\n h-1.9c-0.7,0-1.3,0.6-1.3,1.3v1.9C14,17.5,13.8,17.7,13.4,17.7z\"/>\n <path class=\"st1\" d=\"M17.2,8.1h-1.9c-1.3,0-2.4-1.1-2.4-2.4V3.8c0-0.3,0.2-0.6,0.6-0.6S14,3.5,14,3.8v1.9C14,6.4,14.6,7,15.3,7h1.9\n c0.3,0,0.6,0.2,0.6,0.6S17.5,8.1,17.2,8.1z\"/>\n </svg>\n </span>");
+
+ btnItem.onclick = function () {
+ var _this9$decoderState$s6 = _this9.decoderState.state,
+ webExpend = _this9$decoderState$s6.webExpend,
+ expend = _this9$decoderState$s6.expend,
+ play = _this9$decoderState$s6.play,
+ pantile = _this9$decoderState$s6.pantile;
+
+ if (!play) {
+ return false;
+ }
+
+ if (webExpend) {
+ console.log("姝e湪缃戠珯鍏ㄥ睆");
+ return false;
+ }
+
+ if (!expend) {
+ console.log("鎵ц鍏ㄥ眬鍏ㄥ睆");
+
+ if (_this9.isMobile) {
+ var heightIntercept = parseInt(getComputedStyle(document.getElementById("".concat(_this9.jSPlugin.id, "-wrap"))).height, 10) - parseInt(getComputedStyle(document.getElementById(_this9.jSPlugin.id)).height, 10);
+ requestMobileFullScreen(document.getElementById("".concat(_this9.jSPlugin.id, "-wrap")));
+ setTimeout(function () {
+ var width = document.documentElement.clientWidth;
+ var height = document.documentElement.clientHeight; // 鍏煎寰俊娴忚鍣╢ooter琚殣钘�
+ // document.getElementById(`${this.jSPlugin.id}-ez-iframe-footer-container`).style.marginTop = "0px";
+ // document.getElementById(`${this.jSPlugin.id}-headControl`).style.position = "absolute";
+
+ document.getElementById("".concat(_this9.jSPlugin.id)).style["backface-visibility"] = "hidden";
+
+ _this9.jSPlugin.jSPlugin.JS_Resize(height, width - heightIntercept);
+ }, 100);
+ } else {
+ var promise = requestFullScreenPromise(document.getElementById("".concat(_this9.jSPlugin.id)));
+ promise.then(function (data) {
+ _this9.jSPlugin.jSPlugin.JS_Resize(window.screen.availWidth, window.screen.availHeight);
+ })["catch"](function (err) {
+ console.log(err);
+ });
+ }
+ } else {
+ if (_this9.isMobile) {
+ var heightIntercept = parseInt(getComputedStyle(document.getElementById("".concat(_this9.jSPlugin.id, "-wrap"))).height, 10) - parseInt(getComputedStyle(document.getElementById(_this9.jSPlugin.id)).height, 10);
+
+ if (document.getElementById("".concat(_this9.jSPlugin.id, "-ez-iframe-footer-container"))) {
+ document.getElementById("".concat(_this9.jSPlugin.id, "-ez-iframe-footer-container")).style.marginTop = "-32px";
+ }
+
+ if (document.getElementById("".concat(_this9.jSPlugin.id, "-headControl"))) {
+ document.getElementById("".concat(_this9.jSPlugin.id, "-headControl")).style.position = "relative";
+ }
+
+ cancelMobileFullScreen(document.getElementById("".concat(_this9.jSPlugin.id, "-wrap")), _this9.jSPlugin.width, _this9.jSPlugin.height + heightIntercept);
+
+ _this9.jSPlugin.jSPlugin.JS_Resize(_this9.jSPlugin.width, _this9.jSPlugin.height); // 绉诲姩绔彇娑堝叏灞忥紝濡傛灉寮�鍚簡浜戝彴锛屽彇娑堜簯鍙�
+
+
+ if (pantile) {
+ _this9.Ptz.hide();
+
+ _this9.setDecoderState({
+ pantile: false
+ });
+ }
+ } else {
+ console.log("鍙栨秷鍏ㄥ眬鍏ㄥ睆");
+ var cancelPromise = cancelFullScreenPromise();
+ cancelPromise.then(function (data) {
+ console.log("鍙栨秷鍏ㄥ睆", data, _this9.jSPlugin);
+
+ _this9.jSPlugin.jSPlugin.JS_Resize(_this9.jSPlugin.width, _this9.jSPlugin.height);
+ });
+ }
+ }
+
+ _this9.setDecoderState({
+ expend: !expend
+ });
+ };
+
+ return btnItem;
+
+ case 'webExpend':
+ btnItem.title = "缃戦〉鍏ㄥ睆";
+ btnItem.id = btnId;
+ btnItem.domString = "<span><svg fill=\"".concat(btnItem.color, "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" height=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" viewBox=\"-6 -6 32 32\">") + '<path d="M3.1,7.6c-0.3,0-0.5-0.2-0.5-0.5V5.3c0-1.2,1-2.3,2.2-2.3h1.8c0.3,0,0.5,0.2,0.5,0.5S6.8,4.1,6.6,4.1H4.8 c-0.7,0-1.2,0.6-1.2,1.3v1.8C3.6,7.4,3.3,7.6,3.1,7.6z" />' + '<path d="M15.3,18.1h-1.8c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h1.8c0.7,0,1.2-0.6,1.2-1.2v-1.8 c0-0.3,0.2-0.5,0.5-0.5s0.5,0.2,0.5,0.5v1.8C17.6,17.1,16.6,18.1,15.3,18.1z" />' + '<circle class="st2" cx="10.2" cy="10.4" r="1.1"/>' + '</svg>' + "<svg fill=\"".concat(btnItem.color, "\" style=\"display:none;\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" height=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" viewBox=\"-6 -6 32 32\">\n <path class=\"st1\" d=\"M5.4,8.1H3.5C3.2,8.1,3,7.9,3,7.6s0.2-0.5,0.5-0.5h1.9c0.8,0,1.4-0.6,1.4-1.4V3.8c0-0.3,0.2-0.5,0.5-0.5\n s0.5,0.2,0.5,0.5v1.9C7.7,7,6.7,8.1,5.4,8.1z\"/>\n <path class=\"st1\" d=\"M13.1,17.7c-0.3,0-0.5-0.2-0.5-0.5v-1.9c0-1.3,1.1-2.4,2.4-2.4h1.9c0.3,0,0.5,0.2,0.5,0.5s-0.2,0.5-0.5,0.5H15\n c-0.8,0-1.4,0.6-1.4,1.4v1.9C13.6,17.4,13.4,17.7,13.1,17.7z\"/>\n <circle class=\"st2\" cx=\"10.2\" cy=\"10.4\" r=\"1.1\"/>\n ") + '</svg></span>';
+
+ btnItem.onclick = function () {
+ var _this9$decoderState$s7 = _this9.decoderState.state,
+ webExpend = _this9$decoderState$s7.webExpend,
+ expend = _this9$decoderState$s7.expend,
+ play = _this9$decoderState$s7.play;
+
+ if (!play) {
+ return false;
+ }
+
+ if (expend) {
+ console.log("姝e湪鍏ㄥ眬鍏ㄥ睆");
+ return false;
+ }
+
+ if (!webExpend) {
+ console.log("鎵ц缃戦〉鍏ㄥ睆");
+ var footerDOMHeight = 0;
+ var headerDOMHeight = 0; // ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange'].forEach((item) => {
+ // window.addEventListener(item, (data) => fullscreenchange("fullscreenchange", data));
+ // });
+ // // 鐩戝惉鍏ㄥ睆浜嬩欢瑙﹀彂
+ // function fullscreenchange() {
+ // let isFullScreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
+ // return isFullScreen;
+ // }
+
+ var promise = requestFullScreenPromise(document.getElementById("".concat(_this9.jSPlugin.id, "-wrap")));
+ promise.then(function (data) {
+ console.log("鍏ㄥ睆promise", window.screen.availWidth);
+
+ if (document.getElementById("".concat(_this9.jSPlugin.id, "-canvas-container"))) {
+ footerDOMHeight = parseInt(window.getComputedStyle(document.getElementById("".concat(_this9.jSPlugin.id, "-canvas-container"))).height, 10);
+ }
+
+ if (document.getElementById("".concat(_this9.jSPlugin.id, "-headControl"))) {
+ headerDOMHeight = parseInt(window.getComputedStyle(document.getElementById("".concat(_this9.jSPlugin.id, "-headControl"))).height, 10);
+ }
+
+ console.log("this.jSPlugin.JS_Resiz", footerDOMHeight, headerDOMHeight, document.body.clientWidth);
+
+ _this9.jSPlugin.jSPlugin.JS_Resize(window.screen.availWidth, window.screen.availHeight - footerDOMHeight - headerDOMHeight);
+ })["catch"](function (err) {
+ console.log(err);
+ });
+ } else {
+ console.log("鍙栨秷缃戦〉鍏ㄥ睆");
+ var cancelPromise = cancelFullScreenPromise();
+ cancelPromise.then(function (data) {
+ _this9.jSPlugin.jSPlugin.JS_Resize(_this9.jSPlugin.width, _this9.jSPlugin.height);
+ });
+ }
+
+ _this9.setDecoderState({
+ webExpend: !webExpend
+ });
+ };
+
+ return btnItem;
+
+ case 'hd':
+ btnItem.title = "鐢婚潰娓呮櫚搴�";
+ btnItem.id = btnId;
+ btnItem.domString = "<ul id=\"".concat(this.jSPlugin.id, "-hdSelect\" class=\"hd speed-select ").concat(this.isMobile ? "mobile" : "", "\" style=\"display:none;\">") // + `<li class="selectOption" style="width: 60px;height: 32px;text-align: center;line-height: 32px;list-style: none;cursor: pointer;font-size: 13px;color: rgba(0, 0, 0, .85);" name="option" id="${this.jSPlugin.id}-select-hd">楂樻竻</li>`
+ // + `<li class="selectOption" style="width: 60px;height: 32px;text-align: center;line-height: 32px;list-style: none;cursor: pointer;font-size: 13px;color: rgba(0, 0, 0, .85);" name="option" id="${this.jSPlugin.id}-select-sd">鏍囨竻</li>`
+ + "<li class=\"selectOption default\" style=\"height: 45px;text-align: center;line-height: 45px;list-style: none;cursor: pointer;\" name=\"option\" id=\"".concat(this.jSPlugin.id, "-select-hd\">\u9AD8\u6E05</li>") + "<li class=\"selectOption default\" style=\"height: 45px;text-align: center;line-height: 45px;list-style: none;cursor: pointer;\" name=\"option\" id=\"".concat(this.jSPlugin.id, "-select-sd\">\u6807\u6E05</li>") + "<li class=\"selectOption cancel\" style=\"".concat(this.isMobile ? "" : "display:none;", "\" name=\"option\" id=\"").concat(this.jSPlugin.id, "-select-speed\">\u53D6\u6D88</li>") + '</ul>' + "<span><svg fill=\"".concat(btnItem.color, "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" height=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" viewBox=\"-6 -6 32 32\">") + '<path d="M17.4,16.5H3.1c-0.8,0-1.4-0.6-1.4-1.4V5.4c0-0.9,0.7-1.6,1.6-1.6h14.1c0.8,0,1.4,0.6,1.4,1.4v9.8 C18.8,15.9,18.2,16.5,17.4,16.5z M3.3,5C3.1,5,2.9,5.2,2.9,5.4v9.7c0,0.2,0.1,0.3,0.3,0.3h14.3c0.2,0,0.3-0.1,0.3-0.3V5.3 c0-0.2-0.1-0.3-0.3-0.3H3.3z" />' + '<path d="M13.3,13.6h-1.6c-0.4,0-0.7-0.3-0.7-0.7V7.4c0-0.4,0.3-0.7,0.7-0.7h1.6c1.2,0,2.2,1,2.2,2.2v2.4 C15.6,12.6,14.6,13.6,13.3,13.6z M12.2,12.5h1.1c0.6,0,1.1-0.5,1.1-1.1V9c0-0.6-0.5-1.1-1.1-1.1h-1.1V12.5z" />' + '<path d="M5.5,13.6c-0.3,0-0.6-0.2-0.6-0.6V7.3C5,7,5.2,6.8,5.5,6.8S6.1,7,6.1,7.3v5.7C6.1,13.4,5.8,13.6,5.5,13.6z" />' + '<path d="M9.2,13.6c-0.3,0-0.6-0.2-0.6-0.6V7.3c0-0.3,0.2-0.6,0.6-0.6S9.8,7,9.8,7.3v5.7C9.8,13.4,9.5,13.6,9.2,13.6z" />' + '<rect x="5.6" y="9.6" width="3.6" height="1.1" />' + '</svg>' + "<svg style=\"display:none\" fill=\"".concat(btnItem.color, "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" height=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" viewBox=\"-6 -8 40 44\">\n <path d=\"M24.1,23.8h-20c-1.1,0-1.9-0.9-1.9-1.9V8.4c0-1.2,1-2.2,2.1-2.2h19.7c1.1,0,1.9,0.9,1.9,1.9v13.8\n C26,23,25.1,23.8,24.1,23.8z M4.3,7.7C4,7.7,3.7,8,3.7,8.4v13.5c0,0.2,0.2,0.4,0.4,0.4h20c0.2,0,0.4-0.2,0.4-0.4V8.2\n c0-0.2-0.2-0.4-0.4-0.4H4.3z\"/>\n <path d=\"M18.4,19.8h-2.2c-0.5,0-0.9-0.4-0.9-0.9v-7.8c0-0.5,0.4-0.9,0.9-0.9h2.2c1.7,0,3.1,1.4,3.1,3.1v3.3\n C21.5,18.4,20.1,19.8,18.4,19.8z M16.7,18.3h1.6c0.9,0,1.6-0.7,1.6-1.6v-3.3c0-0.9-0.7-1.6-1.6-1.6h-1.6V18.3z\"/>\n <path d=\"M10.5,19.8c1.2,0,2.1-0.3,2.7-0.9c0.6-0.6,0.9-1.3,0.9-2.1c0-0.8-0.3-1.4-0.9-1.8c-0.4-0.2-1.1-0.5-2.2-0.8\n l0,0l-1-0.2c-0.4-0.1-0.8-0.2-1-0.4c-0.4-0.2-0.6-0.5-0.6-0.9c0-0.4,0.1-0.6,0.4-0.9s0.7-0.3,1.3-0.3c0.8,0,1.4,0.2,1.8,0.6\n c0.2,0.3,0.3,0.6,0.4,0.9l0,0h1.4c0-0.6-0.2-1.1-0.5-1.6c-0.6-0.8-1.6-1.2-2.9-1.2c-1,0-1.8,0.3-2.4,0.8c-0.6,0.5-0.9,1.2-0.9,2\n c0,0.7,0.3,1.3,1,1.7c0.4,0.2,0.9,0.4,1.7,0.6l0,0l1.2,0.3c0.6,0.2,1.1,0.3,1.3,0.4c0.3,0.2,0.5,0.5,0.5,0.9c0,0.5-0.2,0.9-0.6,1.1\n s-0.9,0.4-1.5,0.4c-0.9,0-1.6-0.2-2-0.7c-0.2-0.3-0.3-0.6-0.4-1.1l0,0H6.8c0,0.9,0.3,1.6,0.9,2.2C8.2,19.5,9.2,19.8,10.5,19.8z\"/>\n <defs>\n <filter id=\"Adobe_OpacityMaskFilter\" filterUnits=\"userSpaceOnUse\" x=\"15.2\" y=\"10.3\" width=\"6.2\" height=\"9.5\">\n <feColorMatrix type=\"matrix\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0\"/>\n </filter>\n </defs>\n <mask maskUnits=\"userSpaceOnUse\" x=\"15.2\" y=\"10.3\" width=\"6.2\" height=\"9.5\" id=\"mask-2_2_\">\n <g class=\"st2\">\n <path id=\"path-1_2_\" class=\"st3\" d=\"M24.1,23.1h-20c-0.6,0-1.2-0.5-1.2-1.2V8.2C2.9,7.5,3.5,7,4.1,7h19.7c0.8,0,1.4,0.6,1.4,1.4\n v13.5C25.2,22.6,24.7,23.1,24.1,23.1z\"/>\n </g>\n </mask>\n <defs>\n <filter id=\"Adobe_OpacityMaskFilter_1_\" filterUnits=\"userSpaceOnUse\" x=\"6.8\" y=\"10.3\" width=\"7.3\" height=\"9.5\">\n <feColorMatrix type=\"matrix\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0\"/>\n </filter>\n </defs>\n <mask maskUnits=\"userSpaceOnUse\" x=\"6.8\" y=\"10.3\" width=\"7.3\" height=\"9.5\" id=\"mask-2_3_\">\n <g class=\"st5\">\n <path id=\"path-1_3_\" class=\"st3\" d=\"M24.1,23.1h-20c-0.6,0-1.2-0.5-1.2-1.2V8.2C2.9,7.5,3.5,7,4.1,7h19.7c0.8,0,1.4,0.6,1.4,1.4\n v13.5C25.2,22.6,24.7,23.1,24.1,23.1z\"/>\n </g>\n </mask>\n </svg>\n ") + "<span class='speed-select-mask' style=\"display:none\" id=\"".concat(this.jSPlugin.id, "-select-hd-mask\"></span>") + '</span>';
+
+ btnItem.onclick = function (e) {
+ var _this9$decoderState$s8 = _this9.decoderState.state,
+ hd = _this9$decoderState$s8.hd,
+ expend = _this9$decoderState$s8.expend; // 閫夋嫨娓呮櫚搴﹂�夐」鏃舵墠瑙﹀彂浜嬩欢
+
+ if (hd && e.target.id === "".concat(_this9.jSPlugin.id, "-select-sd")) {
+ //decoder.changePlayUrl({ hd: false });
+ console.log("鍒囨崲鍒版爣娓�");
+
+ _this9.jSPlugin.changeVideoLevel(0);
+
+ _this9.setDecoderState({
+ hd: false
+ });
+ } else if (!hd && e.target.id === "".concat(_this9.jSPlugin.id, "-select-hd")) {
+ _this9.jSPlugin.changeVideoLevel(1);
+
+ _this9.setDecoderState({
+ hd: true
+ });
+ }
+
+ _this9.showHD = !_this9.showHD;
+
+ if (document.getElementById("".concat(_this9.jSPlugin.id, "-hdSelect"))) {
+ document.getElementById("".concat(_this9.jSPlugin.id, "-hdSelect")).style.display = document.getElementById("".concat(_this9.jSPlugin.id, "-hdSelect")).style.display === 'none' ? 'block' : 'none';
+
+ if (_this9.isMobile) {
+ document.getElementById("".concat(_this9.jSPlugin.id, "-select-hd-mask")).style.display = document.getElementById("".concat(_this9.jSPlugin.id, "-select-hd-mask")).style.display === 'none' ? 'block' : 'none';
+ }
+ }
+
+ if (_this9.isMobile && expend && _this9.showHD) {
+ document.getElementById("".concat(_this9.jSPlugin.id, "-hdSelect")).className = "hd speed-select mobile expend";
+ } else {
+ document.getElementById("".concat(_this9.jSPlugin.id, "-hdSelect")).className = _this9.isMobile ? "hd speed-select mobile" : "speed-select";
+ }
+ };
+
+ return btnItem;
+
+ case 'speed':
+ btnItem.title = "鍥炴斁鍊嶉��";
+ btnItem.id = btnId;
+ btnItem.domString = "<ul id=\"".concat(this.jSPlugin.id, "-speedSelect\" class=\"speed speed-select ").concat(this.isMobile ? "mobile" : "", "\" style=\"display:none;\">") + "<li class=\"selectOption default\" style=\"height: 45px;text-align: center;line-height: 45px;list-style: none;cursor: pointer;font-size: 13px;\" name=\"option\" id=\"".concat(this.jSPlugin.id, "-select-speed4\">4\u500D</li>") + "<li class=\"selectOption default\" style=\"height: 45px;text-align: center;line-height: 45px;list-style: none;cursor: pointer;font-size: 13px;\" name=\"option\" id=\"".concat(this.jSPlugin.id, "-select-speed2\">2\u500D</li>") + "<li class=\"selectOption active\" style=\"height: 45px;text-align: center;line-height: 45px;list-style: none;cursor: pointer;font-size: 13px;\" name=\"option\" id=\"".concat(this.jSPlugin.id, "-select-speed1\">1\u500D\uFF08\u6B63\u5E38\u64AD\u653E\uFF09</li>") + "<li class=\"selectOption default\" style=\"height: 45px;text-align: center;line-height: 45px;list-style: none;cursor: pointer;font-size: 13px;\" name=\"option\" id=\"".concat(this.jSPlugin.id, "-select-speed05\">0.5\u500D</li>") + "<li class=\"selectOption cancel\" style=\"".concat(this.isMobile ? "" : "display:none;", "\" name=\"option\" id=\"").concat(this.jSPlugin.id, "-select-speed\">\u53D6\u6D88</li>") + '</ul>' + "<span>\n <div style=\"font-size: 12px;\n vertical-align: bottom;\n display: inline-flex;\n padding: 0px 7px;\n width: 48px;\n line-height: 24px;\n justify-content: center;\n border: 1px solid ".concat(btnItem.color, ";\n text-align: center;border-radius: 12.5px;\"\n id=\"").concat(this.jSPlugin.id, "-speed-text\"\n >").concat(this.nextRate === 1 ? "鍊嶉��" : "".concat(this.nextRate, "\u500D").replace("3", "0.5"), "</div>\n ") + "<span class='speed-select-mask' style=\"display:none\" id=\"".concat(this.jSPlugin.id, "-select-mask\"></span>") + '</span>';
+
+ var setLiActive = function setLiActive(index) {
+ console.log("setLiActive", index);
+ document.getElementById("".concat(_this9.jSPlugin.id, "-speedSelect")).childNodes[0].className = document.getElementById("".concat(_this9.jSPlugin.id, "-speedSelect")).childNodes[0].className.replace("active", "default");
+ document.getElementById("".concat(_this9.jSPlugin.id, "-speedSelect")).childNodes[1].className = document.getElementById("".concat(_this9.jSPlugin.id, "-speedSelect")).childNodes[1].className.replace("active", "default");
+ document.getElementById("".concat(_this9.jSPlugin.id, "-speedSelect")).childNodes[2].className = document.getElementById("".concat(_this9.jSPlugin.id, "-speedSelect")).childNodes[2].className.replace("active", "default");
+ document.getElementById("".concat(_this9.jSPlugin.id, "-speedSelect")).childNodes[3].className = document.getElementById("".concat(_this9.jSPlugin.id, "-speedSelect")).childNodes[3].className.replace("active", "default");
+ document.getElementById("".concat(_this9.jSPlugin.id, "-speedSelect")).childNodes[index].className = document.getElementById("".concat(_this9.jSPlugin.id, "-speedSelect")).childNodes[index].className.replace("default", "active");
+ };
+
+ if (!this.isMobile) {
+ btnItem.onmouseenter = function (e) {
+ console.log("榧犳爣绉诲叆", e);
+
+ _this9.setDecoderState({
+ speed: true
+ });
+
+ if (document.getElementById("".concat(_this9.jSPlugin.id, "-speedSelect"))) {
+ document.getElementById("".concat(_this9.jSPlugin.id, "-speedSelect")).style.display = 'block';
+ }
+ };
+
+ btnItem.onmouseleave = function (e) {
+ console.log("榧犳爣绉诲嚭", e);
+
+ _this9.setDecoderState({
+ speed: false
+ });
+
+ if (document.getElementById("".concat(_this9.jSPlugin.id, "-speedSelect"))) {
+ document.getElementById("".concat(_this9.jSPlugin.id, "-speedSelect")).style.display = 'none';
+ }
+ };
+ }
+
+ btnItem.onclick = function (e) {
+ var _this9$decoderState$s9 = _this9.decoderState.state,
+ speed = _this9$decoderState$s9.speed,
+ expend = _this9$decoderState$s9.expend;
+
+ if (!speed && _this9.isMobile) {
+ document.getElementById("".concat(_this9.jSPlugin.id, "-speedSelect")).className = expend ? "speed speed-select mobile expend" : "speed speed-select mobile";
+ }
+
+ _this9.nextRate = 1; // 閫夋嫨娓呮櫚搴﹂�夐」鏃舵墠瑙﹀彂浜嬩欢
+ // if(this.isMobile) {
+ // console.log("璇锋墽琛岀Щ鍔ㄧ鍊嶉��");
+ // return false;
+ // }
+
+ if (e.target.id) {
+ switch (e.target.id) {
+ case "".concat(_this9.jSPlugin.id, "-select-speed1"):
+ // case `${this.jSPlugin.id}-select-speed`:
+ console.log("鍊嶉��1");
+ _this9.nextRate = 1;
+
+ _this9.jSPlugin.jSPlugin.JS_Speed(_this9.nextRate);
+
+ if (document.getElementById("".concat(_this9.jSPlugin.id, "-speed-text"))) {
+ document.getElementById("".concat(_this9.jSPlugin.id, "-speed-text")).innerHTML = "鍊嶉��";
+ setLiActive(2);
+ }
+
+ _this9.setDecoderState({
+ speed: !speed
+ });
+
+ break;
+
+ case "".concat(_this9.jSPlugin.id, "-select-speed2"):
+ console.log("鍊嶉��2");
+ _this9.nextRate = 2;
+
+ _this9.jSPlugin.jSPlugin.JS_Speed(_this9.nextRate);
+
+ if (document.getElementById("".concat(_this9.jSPlugin.id, "-speed-text"))) {
+ document.getElementById("".concat(_this9.jSPlugin.id, "-speed-text")).innerHTML = "2鍊�"; // 璁剧疆2鍊嶉�熼�変腑鏁堟灉
+
+ setLiActive(1);
+ }
+
+ _this9.setDecoderState({
+ speed: !speed
+ });
+
+ break;
+
+ case "".concat(_this9.jSPlugin.id, "-select-speed4"):
+ console.log("鍊嶉��4");
+ _this9.nextRate = 4;
+
+ _this9.jSPlugin.jSPlugin.JS_Speed(_this9.nextRate);
+
+ if (document.getElementById("".concat(_this9.jSPlugin.id, "-speed-text"))) {
+ document.getElementById("".concat(_this9.jSPlugin.id, "-speed-text")).innerHTML = "4鍊�";
+ setLiActive(0);
+ }
+
+ _this9.setDecoderState({
+ speed: !speed
+ });
+
+ break;
+
+ case "".concat(_this9.jSPlugin.id, "-select-speed05"):
+ console.log("鍊嶉��05");
+ _this9.nextRate = 3;
+
+ _this9.jSPlugin.jSPlugin.JS_Speed(_this9.nextRate);
+
+ if (document.getElementById("".concat(_this9.jSPlugin.id, "-speed-text"))) {
+ document.getElementById("".concat(_this9.jSPlugin.id, "-speed-text")).innerHTML = "0.5鍊�";
+ setLiActive(3);
+ }
+
+ _this9.setDecoderState({
+ speed: !speed
+ });
+
+ break;
+
+ default:
+ // if(document.getElementById(`${this.jSPlugin.id}-speed-text`)){
+ // document.getElementById(`${this.jSPlugin.id}-speed-text`).innerHTML = this.nextRate +"鍊�";
+ // }
+ // pc 绔偣鍑讳笉鍐嶉殣钘忥紝鍙�氳繃绉诲嚭闅愯棌
+ if (!_this9.isMobile) {
+ _this9.setDecoderState({
+ speed: true
+ });
+ } else {
+ _this9.setDecoderState({
+ speed: !speed
+ });
+ }
+
+ break;
+ }
+ } // pc 绔偣鍑讳笉鍐嶉殣钘忥紝鍙�氳繃绉诲嚭闅愯棌
+
+
+ if (!_this9.isMobile && e.target.id === "".concat(_this9.jSPlugin.id, "-speed-text")) {
+ document.getElementById("".concat(_this9.jSPlugin.id, "-speedSelect")).style.display = 'block';
+ } else {
+ if (document.getElementById("".concat(_this9.jSPlugin.id, "-speedSelect"))) {
+ document.getElementById("".concat(_this9.jSPlugin.id, "-speedSelect")).style.display = document.getElementById("".concat(_this9.jSPlugin.id, "-speedSelect")).style.display === 'none' ? 'block' : 'none';
+ }
+ }
+ };
+
+ return btnItem;
+
+ case 'deviceName':
+ btnItem.title = "璁惧鍚嶇О";
+ btnItem.id = btnId;
+ btnItem.domString = '<span>璁惧鍚嶇О</span>';
+
+ btnItem.onclick = function () {};
+
+ return btnItem;
+
+ case 'deviceID':
+ btnItem.title = "璁惧搴忓垪鍙�";
+ btnItem.id = btnId;
+ btnItem.domString = '<span>璁惧搴忓垪鍙�</span>';
+
+ btnItem.onclick = function () {};
+
+ return btnItem;
+
+ case 'cloudRec':
+ btnItem.title = "浜戝瓨鍌ㄥ洖鏀�";
+ btnItem.id = btnId;
+ btnItem.domString = "\n <span>\n <svg fill=\"".concat(btnItem.color, "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" height=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" viewBox=\"-10 0 40 15\">\n\t<path d=\"M9.5,13.1c-0.3,0-0.5-0.2-0.5-0.5V8.8c0-0.3,0.2-0.5,0.5-0.5S10,8.5,10,8.8v3.8C10,12.8,9.8,13.1,9.5,13.1z\"/>\n\t<path d=\"M7.6,10.6c-0.1,0-0.3-0.1-0.4-0.2C7,10.2,7,9.9,7.3,9.7l1.9-1.7c0.2-0.2,0.5-0.2,0.7,0l1.8,1.7\n\t\tc0.2,0.2,0.2,0.5,0,0.7c-0.2,0.2-0.5,0.2-0.7,0L9.5,9.1l-1.6,1.4C7.8,10.6,7.7,10.6,7.6,10.6z\"/>\n\t<path d=\"M13.2,15.7H5.6c-2.1-0.1-3.8-1.8-3.8-3.9c0-1.8,1.3-3.4,3-3.8c0.4-2.2,2.3-3.9,4.6-3.9c2.3,0,4.2,1.7,4.6,3.8\n\t\tc1.8,0.4,3.1,1.9,3.1,3.8C17.1,13.9,15.4,15.7,13.2,15.7z M5.6,14.7h7.6c1.6,0,2.9-1.3,2.9-2.9c0-1.5-1.1-2.7-2.6-2.9l-0.4,0l0-0.4\n\t\tc-0.2-1.9-1.7-3.3-3.6-3.3C7.5,5.1,6,6.6,5.8,8.5l0,0.4l-0.4,0c-1.4,0.2-2.5,1.4-2.5,2.9C2.8,13.3,4.1,14.6,5.6,14.7z\"/>\n </svg>\n </span>\n ");
+
+ btnItem.onclick = function () {
+ console.log("鐐瑰嚮浜戝洖鏀�");
+
+ _this9.setDecoderState({
+ type: 'cloud.rec',
+ cloudRec: true,
+ rec: false
+ });
+
+ _this9.jSPlugin.changePlayUrl({
+ type: 'cloud.rec'
+ });
+
+ console.log(_this9.jSPlugin);
+ var initDate = getQueryString("begin", _this9.jSPlugin.url) || new Date().Format('yyyyMMdd');
+
+ _this9.Rec.renderRec("".concat(initDate.slice(0, 4), "-").concat(initDate.slice(4, 6), "-").concat(initDate.slice(6, 8)));
+ };
+
+ return btnItem;
+
+ case 'rec':
+ btnItem.title = "鏈湴瀛樺偍";
+ btnItem.id = btnId;
+ btnItem.domString = "\n <span>\n <svg fill=".concat(btnItem.color, " version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" height=\"").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "\" viewBox=\"0 0 40 15\">\n <path d=\"M13,16.3H5.5c-1.1,0-2-0.9-2-2V3.8c0-1.1,0.9-2,2-2h5.4c0.5,0,1,0.2,1.4,0.6l2.1,2.1C14.8,4.8,15,5.3,15,5.9\n v8.4C15,15.4,14.1,16.3,13,16.3z M5.5,2.8c-0.6,0-1,0.4-1,1v10.5c0,0.6,0.4,1,1,1H13c0.6,0,1-0.4,1-1V5.9c0-0.3-0.1-0.5-0.3-0.7\n L11.6,3c-0.2-0.2-0.4-0.3-0.7-0.3H5.5z\"/>\n<path d=\"M6.3,7.3C6,7.3,5.8,7,5.8,6.8V4.5C5.8,4.2,6,4,6.3,4s0.5,0.2,0.5,0.5v2.2C6.8,7,6.6,7.3,6.3,7.3z\"/>\n<path d=\"M8.5,7.3C8.3,7.3,8,7,8,6.8V4.5C8,4.2,8.3,4,8.5,4S9,4.2,9,4.5v2.2C9,7,8.8,7.3,8.5,7.3z\"/>\n<path d=\"M10.8,7.3c-0.3,0-0.5-0.2-0.5-0.5V4.5c0-0.3,0.2-0.5,0.5-0.5s0.5,0.2,0.5,0.5v2.2C11.3,7,11.1,7.3,10.8,7.3z\"\n />\n </svg>\n </span>\n ");
+
+ btnItem.onclick = function () {
+ console.log("鐐瑰嚮鏈湴鍥炴斁");
+
+ _this9.setDecoderState({
+ type: 'rec',
+ cloudRec: false,
+ rec: true
+ });
+
+ _this9.jSPlugin.changePlayUrl({
+ type: 'rec'
+ });
+
+ console.log(_this9.jSPlugin);
+ var initDate = getQueryString("begin", _this9.jSPlugin.url) || new Date().Format('yyyyMMdd');
+
+ _this9.Rec.renderRec("".concat(initDate.slice(0, 4), "-").concat(initDate.slice(4, 6), "-").concat(initDate.slice(6, 8)));
+ };
+
+ return btnItem;
+
+ default:
+ return btnItem;
+ }
+ }
+ }, {
+ key: "initThemeData",
+ value: function initThemeData() {
+ var _this10 = this;
+
+ var _this$themeData4 = this.themeData,
+ header = _this$themeData4.header,
+ footer = _this$themeData4.footer;
+ var videoId = this.jSPlugin.id;
+ this.header = defaultTheme.header;
+ this.footer = defaultTheme.footer;
+ this.isNeedRenderHeader = lodash.findIndex(header.btnList, function (v) {
+ return v.isrender > 0;
+ }) >= 0;
+
+ if (this.isMobile) {
+ // 绉诲姩绔洖鏀撅紝闇�瑕佸垽鏂澶囧簭鍒楀彿锛岃澶囧悕绉�
+ this.isNeedRenderHeader = lodash.findIndex(header.btnList, function (v) {
+ return v.isrender > 0 && v.iconId === "deviceID" || v.isrender > 0 && v.iconId === "deviceName";
+ }) >= 0;
+ }
+
+ this.isNeedRenderFooter = lodash.findIndex(footer.btnList, function (v) {
+ return v.isrender > 0;
+ }) >= 0;
+ this.isNeedRenderTimeLine = lodash.findIndex(header.btnList, function (v) {
+ return v.iconId === 'cloudRec' && v.isrender === 1 || v.iconId === 'rec' && v.isrender === 1;
+ }) >= 0 && !this.jSPlugin.disabledTimeLine;
+ ["date-switch-container-wrap", "rec-type-container-wrap", "mobile-rec-wrap", "mobile-ez-ptz-container"].forEach(function (item, index) {
+ if (document.getElementById(item)) {
+ document.getElementById(item).parentElement.removeChild(document.getElementById(item));
+ }
+ });
+
+ if (this.isNeedRenderHeader) {
+ if (!document.getElementById("".concat(this.jSPlugin.id, "-headControl"))) {
+ var headerContainer = document.createElement('div');
+ headerContainer.setAttribute('id', "".concat(this.jSPlugin.id, "-headControl"));
+ headerContainer.setAttribute('class', 'header-controls');
+ headerContainer.innerHTML = "<div id='".concat(this.jSPlugin.id, "-headControl-left' class=\"header-controls-left\" style='display:flex'></div><div id='").concat(this.jSPlugin.id, "-headControl-right' class=\"header-controls-right\" style='display:flex'></div>");
+ var headerStyle = {
+ height: this.jSPlugin.width > MEDIAWIDTH ? "48px" : "32px",
+ "line-height": this.jSPlugin.width > MEDIAWIDTH ? "48px" : "32px",
+ display: "flex",
+ "justify-content": "space-between",
+ top: 0,
+ "z-index": 1,
+ background: "#000000",
+ color: "#FFFFFF",
+ width: "100%"
+ };
+ headerContainer.style = styleToString(headerStyle);
+ document.getElementById("".concat(videoId, "-wrap")).insertBefore(headerContainer, document.getElementById(videoId)); // 澶撮儴棰勭暀x鍍忕礌绌洪棿
+
+ var _checkTimer2 = setInterval(function () {
+ if (window.EZUIKit[_this10.jSPlugin.id].state.EZUIKitPlayer.init) {
+ clearInterval(_checkTimer2); // 妫�娴嬪埌娓叉煋澶撮儴锛屾墽琛屼竴娆eSize
+ // this.jSPlugin.reSize(this.jSPlugin.params.width,this.jSPlugin.params.height);
+ }
+ }, 50);
+ } else {
+ document.getElementById("".concat(this.jSPlugin.id, "-headControl")).innerHTML = "<div id='".concat(this.jSPlugin.id, "-headControl-left' style='display:flex'></div><div id='").concat(this.jSPlugin.id, "-headControl-right' style='display:flex'></div>");
+ }
+ } else {
+ if (document.getElementById("".concat(this.jSPlugin.id, "-headControl"))) {
+ document.getElementById("".concat(this.jSPlugin.id, "-headControl")).parentElement.removeChild(document.getElementById("".concat(this.jSPlugin.id, "-headControl")));
+ } // this.jSPlugin.reSize(this.jSPlugin.params.width,this.jSPlugin.params.height);
+
+ }
+
+ if (this.isNeedRenderFooter) {
+ if (!document.getElementById("".concat(this.jSPlugin.id, "-ez-iframe-footer-container"))) {
+ var footerContainer = document.createElement('div');
+ footerContainer.setAttribute('id', "".concat(this.jSPlugin.id, "-ez-iframe-footer-container"));
+ footerContainer.setAttribute('class', 'ez-iframe-footer-container');
+ var footerStyle = {
+ "min-height": this.jSPlugin.width > MEDIAWIDTH ? "48px" : "32px",
+ "max-height": this.jSPlugin.width > MEDIAWIDTH ? "96px" : "80px",
+ "position": "relative",
+ "margin-top": this.jSPlugin.width > MEDIAWIDTH ? "-48px" : "-32px",
+ display: "flex",
+ "flex-wrap": "wrap",
+ "justify-content": "space-between",
+ "z-index": 999,
+ top: 0,
+ color: "#FFFFFF",
+ width: "100%"
+ };
+ footerContainer.style = styleToString(footerStyle);
+ footerContainer.innerHTML = "<div id=\"".concat(this.jSPlugin.id, "-audioControls\" class=\"footer-controls\" style='display:flex;height:").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "px;justify-content: space-between;width:100%;z-index:999;position: relative;'><div id='").concat(this.jSPlugin.id, "-audioControls-left' class=\"footer-controls-left\" style='display:flex;margin-lefacti'></div><div id='").concat(this.jSPlugin.id, "-audioControls-right' class=\"footer-controls-right\" style='display:flex'></div></div>");
+ insertAfter$1(footerContainer, document.getElementById(videoId));
+ } else {
+ if (document.getElementById("".concat(this.jSPlugin.id, "-ez-iframe-footer-container"))) {
+ document.getElementById("".concat(this.jSPlugin.id, "-ez-iframe-footer-container")).innerHTML = "<div id=\"".concat(this.jSPlugin.id, "-audioControls\" class=\"footer-controls\" style='display:flex;justify-content: space-between;height: ").concat(this.jSPlugin.width > MEDIAWIDTH ? 48 : 32, "px;width:100%;'><div id='").concat(this.jSPlugin.id, "-audioControls-left' class=\"footer-controls-left\" style='display:flex'></div><div id='").concat(this.jSPlugin.id, "-audioControls-right' class=\"footer-controls-right\" style='display:flex'></div></div>");
+ }
+ }
+ } else {
+ if (document.getElementById("".concat(this.jSPlugin.id, "-ez-iframe-footer-container"))) {
+ document.getElementById("".concat(this.jSPlugin.id, "-ez-iframe-footer-container")).parentElement.removeChild(document.getElementById("".concat(this.jSPlugin.id, "-ez-iframe-footer-container")));
+ }
+ }
+
+ if (this.isNeedRenderHeader && document.getElementById("".concat(this.jSPlugin.id, "-headControl"))) {
+ document.getElementById("".concat(this.jSPlugin.id, "-headControl")).style.background = header.backgroundColor;
+ document.getElementById("".concat(this.jSPlugin.id, "-headControl")).style.color = header.color;
+ header.btnList.map(function (item, index) {
+ if (item.isrender) {
+ _this10.renderHeader(item.iconId, item.part);
+ }
+ });
+ }
+
+ if (this.isNeedRenderFooter && document.getElementById("".concat(this.jSPlugin.id, "-audioControls"))) {
+ document.getElementById("".concat(this.jSPlugin.id, "-audioControls")).style.background = footer.backgroundColor;
+ document.getElementById("".concat(this.jSPlugin.id, "-audioControls")).style.color = footer.color;
+ footer.btnList.map(function (item, index) {
+ if (item.isrender) {
+ _this10.renderFooter(item.iconId, item.part);
+ }
+ });
+ }
+
+ if (this.isNeedRenderTimeLine) {
+ if (this.isMobile) {
+ if (document.getElementById("".concat(this.jSPlugin.id, "-headControl-right"))) {
+ document.getElementById("".concat(this.jSPlugin.id, "-headControl-right")).style.display = "none";
+ }
+
+ this.Rec = new MobileRec(this.jSPlugin);
+ } else {
+ this.Rec = new Rec(this.jSPlugin); // 鍥炴斁鏃堕棿杞撮鐣�48鍍忕礌绌洪棿
+
+ var _checkTimer3 = setInterval(function () {
+ if (window.EZUIKit[_this10.jSPlugin.id].state.EZUIKitPlayer.init) {
+ clearInterval(_checkTimer3); // 妫�娴嬪埌娓叉煋鍥炴斁鏃堕棿杞达紝鎵ц涓�娆eSize
+ // this.jSPlugin.reSize(this.jSPlugin.params.width, this.jSPlugin.params.height);
+ }
+ }, 50);
+ }
+ }
+
+ var isNeedRenderPTZ = lodash.findIndex(this.themeData.footer.btnList, function (v) {
+ return v.iconId === 'pantile' && v.isrender === 1;
+ }) >= 0 && !this.jSPlugin.disabledPTZ;
+
+ if (isNeedRenderPTZ) {
+ if (this.isMobile) {
+ this.MobilePtz = new MobilePtz(this.jSPlugin);
+ }
+
+ this.Ptz = new Ptz(this.jSPlugin);
+ } // 鐩戝惉鍏ㄥ睆浜嬩欢瑙﹀彂
+
+
+ var fullscreenchange = function fullscreenchange() {
+ var _this10$decoderState$ = _this10.decoderState.state,
+ expend = _this10$decoderState$.expend,
+ webExpend = _this10$decoderState$.webExpend;
+ var isFullScreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
+
+ if (!isFullScreen) {
+ _this10.jSPlugin.reSize(_this10.jSPlugin.params.width, _this10.jSPlugin.params.height);
+
+ if (expend) {
+ _this10.setDecoderState({
+ expend: false
+ });
+ }
+
+ if (webExpend) {
+ _this10.setDecoderState({
+ webExpend: false
+ });
+ }
+ }
+ };
+
+ ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange'].forEach(function (item) {
+ window.addEventListener(item, function (data) {
+ return fullscreenchange();
+ });
+ }); // // 鍒ゆ柇鏄惁閰嶇疆灏侀潰
+
+ if (this.themeData.poster) {
+ this.jSPlugin.poster = this.themeData.poster;
+ var checkTimer = setInterval(function () {
+ if (window.EZUIKit[_this10.jSPlugin.id].state.EZUIKitPlayer.init) {
+ clearInterval(checkTimer);
+
+ _this10.jSPlugin.setPoster(_this10.themeData.poster);
+ }
+ }, 50);
+ }
+
+ this.inited = true; //璁惧淇℃伅
+
+ this.getDeviceInfo();
+ }
+ }, {
+ key: "getDeviceInfo",
+ value: function getDeviceInfo() {
+ var _this11 = this;
+
+ var deviceAPISuccess = function deviceAPISuccess(data) {
+ if (data.code == 200 && data.data) {
+ // 璁惧搴忓垪鍙�
+ if (document.getElementById("".concat(_this11.jSPlugin.id, "-deviceName-content"))) {
+ document.getElementById("".concat(_this11.jSPlugin.id, "-deviceName-content")).style.maxWidth = "160px";
+ document.getElementById("".concat(_this11.jSPlugin.id, "-deviceName-content")).style.overflow = "hidden";
+ document.getElementById("".concat(_this11.jSPlugin.id, "-deviceName-content")).style.textOverflow = "ellipsis";
+ document.getElementById("".concat(_this11.jSPlugin.id, "-deviceName-content")).innerHTML = data.data.deviceName;
+ } // 璁惧搴忓垪鍙�
+
+
+ if (document.getElementById("".concat(_this11.jSPlugin.id, "-deviceID-content"))) {
+ document.getElementById("".concat(_this11.jSPlugin.id, "-deviceID-content")).style.maxWidth = "160px";
+ document.getElementById("".concat(_this11.jSPlugin.id, "-deviceID-content")).style.overflow = "hidden";
+ document.getElementById("".concat(_this11.jSPlugin.id, "-deviceID-content")).style.textOverflow = "ellipsis";
+ document.getElementById("".concat(_this11.jSPlugin.id, "-deviceID-content")).innerHTML = matchEzopenUrl(_this11.jSPlugin.url).deviceSerial;
+ }
+ }
+ };
+
+ request(this.jSPlugin.env.domain + '/api/lapp/device/info', 'POST', {
+ accessToken: this.jSPlugin.accessToken,
+ deviceSerial: matchEzopenUrl(this.jSPlugin.url).deviceSerial
+ }, '', deviceAPISuccess);
+ }
+ }, {
+ key: "editStart",
+ value: function editStart(callback) {
+ var audioControlsDOM = document.getElementById("".concat(this.jSPlugin.id, "-audioControls"));
+ var headerMessageDOM = document.getElementById("".concat(this.jSPlugin.id, "-headControl"));
+
+ if (headerMessageDOM) {
+ headerMessageDOM.setAttribute('class', 'header-controls themeEditing');
+ }
+
+ if (audioControlsDOM) {
+ audioControlsDOM.setAttribute('class', 'footer-controls themeEditing');
+ }
+
+ this.setDecoderState({
+ isEditing: true
+ });
+ }
+ }, {
+ key: "editEnd",
+ value: function editEnd(callback) {
+ var audioControlsDOM = document.getElementById("".concat(this.jSPlugin.id, "-audioControls"));
+ var headerMessageDOM = document.getElementById("".concat(this.jSPlugin.id, "-headControl"));
+
+ if (headerMessageDOM) {
+ headerMessageDOM.setAttribute('class', 'header-controls');
+ }
+
+ if (audioControlsDOM) {
+ audioControlsDOM.setAttribute('class', 'footer-controls');
+ }
+
+ this.setDecoderState({
+ isEditing: false
+ });
+ }
+ }, {
+ key: "webExpend",
+ value: function webExpend() {
+ var _this12 = this;
+
+ var _this$decoderState$st = this.decoderState.state;
+ _this$decoderState$st.webExpend;
+ var expend = _this$decoderState$st.expend,
+ play = _this$decoderState$st.play;
+
+ if (!play) {
+ return false;
+ }
+
+ if (expend) {
+ console.log("姝e湪鍏ㄥ眬鍏ㄥ睆");
+ return false;
+ }
+
+ console.log("鎵ц缃戦〉鍏ㄥ睆");
+ var footerDOMHeight = 0;
+ var headerDOMHeight = 0; // ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange'].forEach((item) => {
+ // window.addEventListener(item, (data) => fullscreenchange("fullscreenchange", data));
+ // });
+ // // 鐩戝惉鍏ㄥ睆浜嬩欢瑙﹀彂
+ // function fullscreenchange() {
+ // let isFullScreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
+ // return isFullScreen;
+ // }
+
+ var promise = requestFullScreenPromise(document.getElementById("".concat(this.jSPlugin.id, "-wrap")));
+ promise.then(function (data) {
+ console.log("鍏ㄥ睆promise", window.screen.availWidth);
+
+ if (document.getElementById("".concat(_this12.jSPlugin.id, "-canvas-container"))) {
+ footerDOMHeight = parseInt(window.getComputedStyle(document.getElementById("".concat(_this12.jSPlugin.id, "-canvas-container"))).height, 10);
+ }
+
+ if (document.getElementById("".concat(_this12.jSPlugin.id, "-headControl"))) {
+ headerDOMHeight = parseInt(window.getComputedStyle(document.getElementById("".concat(_this12.jSPlugin.id, "-headControl"))).height, 10);
+ }
+
+ console.log("this.jSPlugin.JS_Resiz", footerDOMHeight, headerDOMHeight, document.body.clientWidth);
+
+ _this12.jSPlugin.jSPlugin.JS_Resize(window.screen.availWidth, window.screen.availHeight - footerDOMHeight - headerDOMHeight);
+ })["catch"](function (err) {
+ console.log(err);
+ });
+ }
+ }, {
+ key: "expend",
+ value: function expend() {
+ var _this13 = this;
+
+ var _this$decoderState$st2 = this.decoderState.state,
+ webExpend = _this$decoderState$st2.webExpend;
+ _this$decoderState$st2.expend;
+ var play = _this$decoderState$st2.play;
+ _this$decoderState$st2.pantile;
+
+ if (!play) {
+ return false;
+ }
+
+ if (webExpend) {
+ console.log("姝e湪缃戠珯鍏ㄥ睆");
+ return false;
+ }
+
+ console.log("鎵ц鍏ㄥ眬鍏ㄥ睆");
+
+ if (this.isMobile) {
+ var heightIntercept = parseInt(getComputedStyle(document.getElementById("".concat(this.jSPlugin.id, "-wrap"))).height, 10) - parseInt(getComputedStyle(document.getElementById(this.jSPlugin.id)).height, 10);
+ requestMobileFullScreen(document.getElementById("".concat(this.jSPlugin.id, "-wrap")));
+ setTimeout(function () {
+ var width = document.documentElement.clientWidth;
+ var height = document.documentElement.clientHeight; // 鍏煎寰俊娴忚鍣╢ooter琚殣钘�
+ // document.getElementById(`${this.jSPlugin.id}-ez-iframe-footer-container`).style.marginTop = "0px";
+ // document.getElementById(`${this.jSPlugin.id}-headControl`).style.position = "absolute";
+
+ document.getElementById("".concat(_this13.jSPlugin.id)).style["backface-visibility"] = "hidden";
+
+ _this13.jSPlugin.jSPlugin.JS_Resize(height, width - heightIntercept);
+ }, 100);
+ } else {
+ var promise = requestFullScreenPromise(document.getElementById("".concat(this.jSPlugin.id)));
+ promise.then(function (data) {
+ _this13.jSPlugin.jSPlugin.JS_Resize(window.screen.availWidth, window.screen.availHeight);
+ })["catch"](function (err) {
+ console.log(err);
+ });
+ }
+ }
+ }]);
+
+ return Theme;
+}();
+
+Date.prototype.Format = function (fmt) {
+ //author: meizz
+ var o = {
+ "M+": this.getMonth() + 1,
+ //鏈堜唤
+ "d+": this.getDate(),
+ //鏃�
+ "h+": this.getHours(),
+ //灏忔椂
+ "m+": this.getMinutes(),
+ //鍒�
+ "s+": this.getSeconds(),
+ //绉�
+ "q+": Math.floor((this.getMonth() + 3) / 3),
+ //瀛e害
+ "S": this.getMilliseconds() //姣
+
+ };
+ if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
+
+ for (var k in o) {
+ if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
+ }
+
+ return fmt;
+};
+
+var Monitor = /*#__PURE__*/function () {
+ function Monitor(params, jsPlugin) {
+ _classCallCheck$1(this, Monitor);
+
+ this.params = params;
+ this.state = {};
+ this.jsPlugin = jsPlugin;
+ this.url = "https://log.ys7.com/statistics.do?";
+
+ if (params.env) {
+ switch (params.env) {
+ case 'test12':
+ this.url = "https://test12dclog.ys7.com/statistics.do?";
+ break;
+
+ case 'online':
+ break;
+
+ default:
+ this.url = params.env;
+ break;
+ }
+ }
+ }
+ /** 鐢熸垚uuid */
+
+
+ _createClass$1(Monitor, [{
+ key: "uuid",
+ value: function uuid() {
+ var s = [];
+ var hexDigits = "0123456789abcdef";
+
+ for (var i = 0; i < 36; i++) {
+ s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
+ }
+ s[14] = "4";
+ s[19] = hexDigits.substr(s[19] & 0x3 | 0x8, 1);
+ s[8] = s[13] = s[18] = s[23] = "-";
+ var uuid = s.join("");
+ return uuid;
+ }
+ }, {
+ key: "dclog",
+ value: function dclog(dclogObj) {
+ var imgUrl = this.url;
+ var obj = Object.assign({}, {
+ systemName: "open_website_monitor"
+ }, {
+ bn: "ezuikit-js"
+ }, dclogObj, {
+ un: dclogObj.url
+ }, {
+ st: new Date().getTime(),
+ h: window.location.pathname
+ }); // usr_name 鏇存敼涓簎n锛屽吋瀹规棫
+
+ Object.keys(obj).forEach(function (item, index) {
+ var value = obj[item];
+
+ if (typeof obj[item] === 'string') {
+ value = obj[item].replace('%', '%25'); // decodeURIComponent 鏃犳硶瑙f瀽%
+ }
+
+ if (typeof obj[item] === 'undefined') {
+ return;
+ }
+
+ imgUrl += "".concat(index === 0 ? '' : '&').concat(item, "=").concat(encodeURIComponent(value));
+ });
+ var img = new Image();
+ img.src = imgUrl;
+ }
+ }, {
+ key: "localInfoLog",
+ value: function localInfoLog(dclogObj) {
+ var imgUrl = this.url; // var obj = Object.assign({}, { systemName: "open_netstream_localinfo" }, dclogObj, {un:dclogObj.url}, { st: new Date().getTime(), h: window.location.pathname }); // usr_name 鏇存敼涓簎n锛屽吋瀹规棫
+
+ var domain = window.location.protocol + '//' + window.location.host;
+ var obj = {
+ systemName: "open_netstream_localinfo",
+ Ver: 'v6.0.0',
+ PlatAddr: domain,
+ ExterVer: 'v6.0.0',
+ OpId: this.uuid(),
+ CltType: 102,
+ AppId: "",
+ playurl: encodeURIComponent(this.jsPlugin.url),
+ StartTime: new Date().Format('yyyy-MM-dd hh:mm:ss.S'),
+ // 姣忎釜鏃ュ織鍖呭惈褰撳墠鐨勬椂闂�
+ OS: navigator.platform
+ };
+ obj = Object.assign(obj, dclogObj);
+ Object.keys(obj).forEach(function (item, index) {
+ var value = obj[item];
+
+ if (typeof obj[item] === 'string') {
+ value = obj[item].replace('%', '%25'); // decodeURIComponent 鏃犳硶瑙f瀽%
+ }
+
+ if (typeof obj[item] === 'undefined') {
+ return;
+ }
+
+ imgUrl += "".concat(index === 0 ? '' : '&').concat(item, "=").concat(encodeURIComponent(value));
+ });
+ var img = new Image();
+ img.src = imgUrl;
+ }
+ }, {
+ key: "playLog",
+ value: function playLog(dclogObj) {
+ var url = this.url;
+ var imgUrl = url;
+ var obj = {
+ systemName: "open_netstream_play_main",
+ playurl: encodeURIComponent(this.jsPlugin.url),
+ Time: new Date().Format('yyyy-MM-dd hh:mm:ss.S'),
+ //Enc: 0, // 0 涓嶅姞瀵� 1 鍔犲瘑
+ //PlTp: PlTp, // 1 鐩存挱 2 鍥炴斁
+ Via: 2,
+ // 2 鏈嶅姟绔彇娴�
+ //ErrCd: 0,
+ OpId: this.uuid() //Cost: (new Date()).getTime() - _this.initTime, // 姣鏁�
+ //Serial: getQueryString('dev', item),
+ //Channel: getQueryString('chn', item),
+
+ };
+ obj = Object.assign(obj, dclogObj);
+ Object.keys(obj).forEach(function (item, index) {
+ var value = obj[item];
+
+ if (typeof obj[item] === 'string') {
+ value = obj[item].replace('%', '%25'); // decodeURIComponent 鏃犳硶瑙f瀽%
+ }
+
+ if (typeof obj[item] === 'undefined') {
+ return;
+ }
+
+ imgUrl += "".concat(index === 0 ? '' : '&').concat(item, "=").concat(encodeURIComponent(value));
+ });
+ var img = new Image();
+ img.src = imgUrl;
+ }
+ }]);
+
+ return Monitor;
+}();
+
+(function (global, factory) {
+
+ if ((typeof module === "undefined" ? "undefined" : _typeof(module)) === "object" && _typeof(module.exports) === "object") {
+ module.exports = global.document ? factory(global, true) : function (w) {
+ if (!w.document) {
+ throw new Error("EZUIPlayer requires a window with a document");
+ }
+
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ } // Pass this if window is not defined yet
+
+})(typeof window !== "undefined" ? window : void 0, function (window, noGlobal) {
+ var _state;
+
+ // 鍔犺浇js
+ function addJs(filepath, callback) {
+ var headerScript = document.getElementsByTagName('head')[0].getElementsByTagName("script");
+ var isReady = false;
+
+ for (var i = 0; i < headerScript.length; i++) {
+ if (headerScript[i].getAttribute("src") == filepath) {
+ isReady = true;
+ callback();
+ }
+ }
+
+ if (!isReady) {
+ var oJs = document.createElement("script");
+ oJs.setAttribute("src", filepath);
+ oJs.onload = callback;
+ document.getElementsByTagName("head")[0].appendChild(oJs);
+ }
+ } // 鍔犺浇css
+
+
+ function addCss(filepath, callback) {
+ var headerLink = document.getElementsByTagName('head')[0].getElementsByTagName("link");
+ var isReady = false;
+
+ for (var i = 0; i < headerLink.length; i++) {
+ if (headerLink[i].getAttribute("href") == filepath) {
+ isReady = true;
+ callback();
+ }
+ }
+
+ if (!isReady) {
+ var oJs = document.createElement('link');
+ oJs.rel = 'stylesheet';
+ oJs.type = 'text/css';
+ oJs.href = filepath;
+ oJs.onload = callback;
+ document.getElementsByTagName("head")[0].appendChild(oJs);
+ }
+ } // 閫氱敤璇锋眰鏂规硶
+
+
+ function request(url, method, params, header, success, error) {
+ var _url = url;
+ var http_request = new XMLHttpRequest();
+
+ http_request.onreadystatechange = function () {
+ if (http_request.readyState == 4) {
+ if (http_request.status == 200) {
+ var _data = JSON.parse(http_request.responseText);
+
+ success(_data);
+ }
+ }
+ };
+
+ http_request.open(method, _url, true); // http_request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
+
+ var data = new FormData();
+
+ for (var i in params) {
+ data.append(i, params[i]);
+ }
+
+ http_request.send(data);
+ }
+
+
+ var EZUIKit = {
+ EZUIKitPlayer: undefined,
+ EZUIKitTalk: undefined,
+ opt: {
+ apiDomain: 'https://open.ys7.com/api/lapp/live/talk/url',
+ filePath: 'https://open.ys7.com/assets/ezuikit_v2.6.4',
+ accessToken: '',
+ url: '',
+ deviceSerial: '',
+ channelNo: '',
+ id: '',
+ talkLink: '',
+ rtcUrl: '',
+ ttsUrl: '',
+ stream: '',
+ // 瀵硅鎻掍欢渚濊禆
+ isReliesReady: false,
+ template: 'simple',
+ plugin: [],
+ // 鍔犺浇鎻掍欢锛宼alk-瀵硅
+ audio: 1,
+ // 澹伴煶id 0-涓嶅紑鍚� 1-寮�鍚�
+ autoplay: 1,
+ videoLoading: false
+ },
+ state: (_state = {
+ countTimer: undefined,
+ // countTime 璁℃椂鍣�
+ recodeTime: 0,
+ // 褰曢煶鏃堕棿
+ recodeTimer: undefined
+ }, _defineProperty(_state, "recodeTime", 0), _defineProperty(_state, "fetchDefaultList", false), _defineProperty(_state, "page", 0), _defineProperty(_state, "pageSize", 5), _state),
+ handleTalkSuccess: function handleTalkSuccess() {},
+ handleTalkError: function handleTalkError() {}
+ };
+ /**
+ * 瑙嗛鎾斁鍣�-寮�濮�
+ */
+
+ var domain = "https://open.ys7.com";
+ var filePathDomain = domain;
+
+ var EZUIKitPlayer = function EZUIKitPlayer(params) {
+ var _this = this;
+
+ this.opt = {
+ id: params.id,
+ apiDomain: domain + '/api/lapp/live/talk/url',
+ filePath: filePathDomain + '/assets/ezuikit_v2.6.4',
+ decoderVersion: '',
+ accessToken: '',
+ url: '',
+ deviceSerial: '',
+ channelNo: '',
+ talkLink: '',
+ rtcUrl: '',
+ ttsUrl: '',
+ stream: '',
+ // 瀵硅鎻掍欢渚濊禆
+ isReliesReady: false,
+ template: 'simple',
+ plugin: [],
+ // 鍔犺浇鎻掍欢锛宼alk-瀵硅
+ audio: 1,
+ // 澹伴煶id 0-涓嶅紑鍚� 1-寮�鍚�
+ autoplay: 1,
+ fullScreenStatus: 0,
+ bSupporDoubleClickFull: true,
+ videoLoading: false
+ };
+ this.params = params;
+
+ if (params.id) {
+ this.opt.id = params.id;
+ }
+
+ if (params.accessToken) {
+ this.opt.accessToken = params.accessToken;
+ }
+
+ if (typeof params.audio !== 'undefined') {
+ this.opt.audio = params.audio;
+ }
+
+ if (typeof params.decoderVersion !== 'undefined') {
+ this.opt.decoderVersion = params.decoderVersion;
+ }
+
+ if (typeof params.env !== 'undefined') {
+ if (typeof params.env.domain !== 'undefined') {
+ domain = params.env.domain;
+ this.opt.apiDomain = domain + '/api/lapp/live/talk/url';
+ }
+
+ if (typeof params.env.filePathDomain !== 'undefined') {
+ filePathDomain = params.env.filePathDomain;
+ this.opt.filePathDomain = params.env.filePathDomain;
+ }
+ } // if(typeof params.domain !== 'undefined'){
+ // this.opt.apiDomain = params.domain + '/api/lapp/live/talk/url';
+ // }
+
+
+ if (params.url) {
+ this.opt.url = params.url;
+ this.opt.deviceSerial = params.url.split("/")[3];
+ this.opt.channelNo = params.url.split("/")[4].split(".")[0];
+ }
+
+ if (typeof params.template !== 'undefined') {
+ this.opt.template = params.template;
+ }
+
+ if (params.plugin) {
+ this.opt.plugin = params.plugin;
+ }
+
+ if (typeof params.autoplay !== 'undefined') {
+ this.opt.autoplay = params.autoplay ? 1 : 0;
+ }
+
+ if (typeof params.bSupporDoubleClickFull !== 'undefined') {
+ this.opt.bSupporDoubleClickFull = params.bSupporDoubleClickFull;
+ }
+
+ if (typeof params.handleTalkSuccess !== 'undefined') {
+ window.EZUIKit.handleTalkSuccess = params.handleTalkSuccess;
+ }
+
+ if (typeof params.handleTalkError !== 'undefined') {
+ window.EZUIKit.handleTalkError = params.handleTalkError;
+ }
+
+ var id = this.opt.id;
+ var domElement = document.getElementById(id); // 闂撮殭
+
+ domElement.style.fontSize = 0;
+ domElement.style.overflowY = 'auto';
+ domElement.style.position = 'relative';
+ /**
+ * 娓叉煋iframe瑙嗛妗�
+ */
+
+ var iframe = document.createElement('iframe');
+
+ function matchIframeUrl() {
+ switch (_this.opt.template) {
+ case 'simple':
+ var iframeUrl = domain + "/ezopen/h5/iframe?bSupporDoubleClickFull=0&url=" + _this.opt.url.replace("?", "&") + "&autoplay=" + _this.opt.autoplay + "&audio=" + _this.opt.audio + "&accessToken=" + params.accessToken + "&templete=0" + "&id=" + id + "&decoderVersion=" + _this.opt.decoderVersion;
+
+ var controlsValue = "";
+
+ if (typeof params.controls !== 'undefined' && params.controls) {
+ console.log("typeof", _typeof(params.controls));
+ controlsValue = "play,voice,hd,fullScreen";
+
+ if (params.controls.length > 0) {
+ controlsValue = params.controls.join(",");
+ iframeUrl += '&controls=' + controlsValue;
+ }
+ }
+
+ if (params.websocketParams) {
+ iframeUrl += '&websocketParams=' + JSON.stringify(params.websocketParams);
+ }
+
+ return iframeUrl;
+
+ case 'standard':
+ return domain + "/ezopen/h5/iframe?bSupporDoubleClickFull=0&url=" + _this.opt.url.replace("?", "&") + "&autoplay=" + _this.opt.autoplay + "&audio=" + _this.opt.audio + "&accessToken=" + params.accessToken + "&templete=1" + "&id=" + id + "&decoderVersion=" + _this.opt.decoderVersion;
+
+ case 'security':
+ return domain + "/ezopen/h5/iframe_se?bSupporDoubleClickFull=0&url=" + _this.opt.url.replace("?", "&") + "&autoplay=" + _this.opt.autoplay + "&audio=" + _this.opt.audio + "&accessToken=" + params.accessToken + "&templete=0" + "&id=" + id + "&decoderVersion=" + _this.opt.decoderVersion;
+
+ case 'theme':
+ iframeUrl = domain + "/jssdk/theme.html?url=".concat(params.url, "&accessToken=").concat(params.accessToken, "&id=").concat(id, "&isMobile=").concat(params.isMobile);
+
+ if (typeof params.isMobile !== 'undefined') {
+ iframeUrl += '&isMobile=' + params.isMobile;
+ }
+
+ if (typeof params.autoplay !== 'undefined') {
+ iframeUrl += '&autoplay=' + params.autoplay;
+ }
+
+ if (typeof params.domain !== 'undefined') {
+ if (params.domain == 'https://test12open.ys7.com') iframeUrl += '&env=' + 'test12';
+ }
+
+ if (typeof params.env !== 'undefined') {
+ if (typeof params.env.domain !== 'undefined') {
+ if (params.env.domain == 'https://test12open.ys7.com') {
+ iframeUrl += '&env=' + 'test12';
+ }
+ }
+ }
+
+ if (typeof params.header !== 'undefined') {
+ iframeUrl += '&header=' + params.header;
+ }
+
+ return iframeUrl;
+
+ default:
+ return domain + "/ezopen/h5/iframe?bSupporDoubleClickFull=0&url=" + _this.opt.url.replace("?", "&") + "&autoplay=" + _this.opt.autoplay + "&audio=" + _this.opt.audio + "&accessToken=" + params.accessToken + "&templete=0" + "&id=" + id + "&decoderVersion=" + _this.opt.decoderVersion;
+ }
+ }
+
+ iframe.src = matchIframeUrl(); // 榛樿鍙栧鍣ㄥ楂�
+
+ var iframeHeight = document.getElementById(id).offsetHeight;
+ var iframeWidth = document.getElementById(id).offsetWidth;
+
+ if (params.height) {
+ iframeHeight = parseInt(params.height);
+
+ if (/\%$/.test(params.height)) {
+ iframeWidth = document.getElementById(id).offsetWidth * (parseInt(params.height) / 100);
+ }
+ }
+
+ if (params.width) {
+ iframeWidth = parseInt(params.width);
+
+ if (/\%$/.test(params.width)) {
+ iframeWidth = document.getElementById(id).offsetWidth * (parseInt(params.width) / 100);
+ }
+ }
+
+ iframe.width = iframeWidth;
+ iframe.height = iframeHeight;
+ iframe.id = 'EZUIKitPlayer-' + id; // 閮ㄥ垎iframe灞炴��
+
+ iframe.setAttribute("allowfullscreen", true);
+ iframe.setAttribute("allow", "autoplay");
+ iframe.setAttribute("frameborder", 0);
+ domElement.appendChild(iframe);
+ var jqueryJS = _this.opt.filePath + '/js/jquery.js';
+ var layerJs = 'https://open.ys7.com/assets/layer/layer.js';
+ addJs(jqueryJS, function () {
+ addJs(layerJs, function () {
+ // });
+ // });
+
+ /**
+ * 娓叉煋header
+ */
+ if (matchHeaderOpt().headerContainer) {
+ // if (params.header && params.header instanceof Array) {
+ var headerContainer = document.createElement('div');
+ headerContainer.setAttribute('class', 'panel-top');
+ var controsDOM = document.createElement('div');
+ controsDOM.setAttribute('class', 'contros');
+ headerContainer.appendChild(controsDOM);
+ domElement.insertBefore(headerContainer, iframe);
+
+ if (matchHeaderOpt().capturePictureModule) {
+ // 鎴浘
+ var capturePictureDOM = document.createElement('span');
+ capturePictureDOM.innerHTML = '<span title="鎴浘">' + '<svg id="capturePicture" title="鎴浘" t="1578882764585" class="icon" viewBox="0 0 1024 1024" version="1.1"' + ' xmlns="http://www.w3.org/2000/svg" p-id="5958" width="24" height="24">' + ' <path' + ' d="M887.296 315.904h-153.6c-51.2 0-68.096-102.4-119.296-102.4H392.704c-34.304 0-51.2 102.4-102.4 102.4h-153.6c-29.696 0-51.2 21.504-51.2 51.2v439.296c0 25.6 21.504 47.104 51.2 47.104h751.104c29.696 0 51.2-21.504 51.2-51.2v-435.2c-0.512-30.208-21.504-51.2-51.712-51.2zM512 768c-115.2 0-204.8-89.6-204.8-200.704s89.6-200.704 204.8-200.704 204.8 89.6 204.8 200.704-93.696 200.704-204.8 200.704z m247.296-354.304c-12.8 0-25.6-12.8-25.6-25.6s12.8-25.6 25.6-25.6 25.6 12.8 25.6 25.6c0 17.408-12.8 25.6-25.6 25.6zM256 264.704c0-8.704-8.704-16.896-16.896-16.896h-51.2c-8.704 0-16.896 8.704-16.896 16.896V281.6H256v-16.896z m256 148.992c-85.504 0-153.6 68.096-153.6 153.6s68.096 153.6 153.6 153.6 153.6-68.096 153.6-153.6-68.096-153.6-153.6-153.6z"' + ' fill="#ffffff" p-id="5959"></path>' + '</svg>' + '</span>';
+
+ capturePictureDOM.onclick = function () {
+ _this.capturePicture();
+ };
+
+ controsDOM.appendChild(capturePictureDOM);
+ }
+
+ console.log("matchHeaderOpt().saveModule", matchHeaderOpt().saveModule);
+
+ if (matchHeaderOpt().saveModule) {
+ var startSaveDOM = document.createElement('span');
+ startSaveDOM.innerHTML = '<span title="寮�濮嬪綍鍍�">' + ' <svg id="startSave" t="1578882716693" class="icon" viewBox="0 0 1024 1024" version="1.1"' + ' xmlns="http://www.w3.org/2000/svg" p-id="3782" width="24" height="24">' + ' <path' + ' d="M915.2 729.6l-128-76.8c-25.6-12.8-44.8-32-44.8-51.2V435.2c0-25.6 19.2-38.4 44.8-51.2l128-76.8c25.6-12.8 44.8 0 44.8 19.2V704c0 32-19.2 38.4-44.8 25.6z m-332.8 89.6H96c-51.2 0-89.6-38.4-89.6-89.6V332.8c0-51.2 38.4-89.6 89.6-89.6h486.4c51.2 0 89.6 38.4 89.6 89.6v396.8c0 51.2-38.4 89.6-89.6 89.6zM192 364.8c-32 6.4-57.6 32-64 64-12.8 57.6 38.4 115.2 96 102.4 32-6.4 57.6-32 64-70.4 12.8-57.6-38.4-108.8-96-96z m0 0"' + ' p-id="3783" fill="#ffffff"></path>' + ' </svg>' + '</span>';
+
+ startSaveDOM.onclick = function () {
+ _this.startSave();
+
+ document.getElementById('startSave').setAttribute('class', 'icon hide');
+ document.getElementById('stopSave').setAttribute('class', 'icon');
+ };
+
+ controsDOM.appendChild(startSaveDOM);
+ var stopSaveDOM = document.createElement('span');
+ stopSaveDOM.innerHTML = '<span title="缁撴潫褰曞儚">' + ' <svg id="stopSave" t="1578882716693" class="icon hide" viewBox="0 0 1024 1024" version="1.1"' + ' xmlns="http://www.w3.org/2000/svg" p-id="3782" width="24" height="24">' + ' <path' + ' d="M915.2 729.6l-128-76.8c-25.6-12.8-44.8-32-44.8-51.2V435.2c0-25.6 19.2-38.4 44.8-51.2l128-76.8c25.6-12.8 44.8 0 44.8 19.2V704c0 32-19.2 38.4-44.8 25.6z m-332.8 89.6H96c-51.2 0-89.6-38.4-89.6-89.6V332.8c0-51.2 38.4-89.6 89.6-89.6h486.4c51.2 0 89.6 38.4 89.6 89.6v396.8c0 51.2-38.4 89.6-89.6 89.6zM192 364.8c-32 6.4-57.6 32-64 64-12.8 57.6 38.4 115.2 96 102.4 32-6.4 57.6-32 64-70.4 12.8-57.6-38.4-108.8-96-96z m0 0"' + ' p-id="3783" fill="red"></path>' + ' </svg>' + ' </span>';
+
+ stopSaveDOM.onclick = function () {
+ _this.stopSave();
+
+ document.getElementById('stopSave').setAttribute('class', 'icon hide');
+ document.getElementById('startSave').setAttribute('class', 'icon');
+ };
+
+ controsDOM.appendChild(stopSaveDOM);
+ }
+
+ if (matchHeaderOpt().zoomModule) {
+ var enableZoomDOM = document.createElement('span');
+ enableZoomDOM.innerHTML = '<span title="寮�鍚數瀛愭斁澶�">' + ' <svg id="enableZoom" t="1578882639834" class="icon" viewBox="0 0 1000 1000" version="1.1"' + ' xmlns="http://www.w3.org/2000/svg" p-id="2227" width="24" height="24">' + ' <path' + ' d="M830.6119 441.1089c0-193.7756-157.0939-350.8641-350.8775-350.8641S128.8559 247.3333 128.8559 441.1089 285.9508 791.972 479.7344 791.972 830.6119 634.8845 830.6119 441.1089zM483.2821 710.4863c-146.7975 0-265.8187-118.9953-265.8187-265.8088S336.4847 178.8697 483.2821 178.8697s265.8197 118.9953 265.8197 265.8078S630.0796 710.4863 483.2821 710.4863zM770.6031 653.5739l-72.6417 75.9485 141.6917 160.1814 82.0737-90.0739L770.6031 653.5739zM527.5849 267.4727h-88.60655762279428v132.90489048425167H306.0690340253259v88.60292721534799h132.90933675248866v132.9038911617923h88.60655762279428V488.9794719180395h132.90933675248866v-88.60292721534799H527.5849284006089V267.4726535408993z"' + ' p-id="2228" fill="#ffffff"></path>' + ' </svg>' + '</span>';
+
+ enableZoomDOM.onclick = function () {
+ _this.enableZoom();
+
+ document.getElementById('enableZoom').setAttribute('class', 'icon hide');
+ document.getElementById('closeZoom').setAttribute('class', 'icon');
+ };
+
+ controsDOM.appendChild(enableZoomDOM);
+ var closeZoomDOM = document.createElement('span');
+ closeZoomDOM.innerHTML = '<span title="鍏抽棴鐢靛瓙鏀惧ぇ">' + ' <svg id="closeZoom" t="1578882639834" class="icon hide" viewBox="0 0 1000 1000" version="1.1"' + ' xmlns="http://www.w3.org/2000/svg" p-id="2227" width="24" height="24">' + ' <path' + ' d="M830.6119 441.1089c0-193.7756-157.0939-350.8641-350.8775-350.8641S128.8559 247.3333 128.8559 441.1089 285.9508 791.972 479.7344 791.972 830.6119 634.8845 830.6119 441.1089zM483.2821 710.4863c-146.7975 0-265.8187-118.9953-265.8187-265.8088S336.4847 178.8697 483.2821 178.8697s265.8197 118.9953 265.8197 265.8078S630.0796 710.4863 483.2821 710.4863zM770.6031 653.5739l-72.6417 75.9485 141.6917 160.1814 82.0737-90.0739L770.6031 653.5739zM527.5849 267.4727h-88.60655762279428v132.90489048425167H306.0690340253259v88.60292721534799h132.90933675248866v132.9038911617923h88.60655762279428V488.9794719180395h132.90933675248866v-88.60292721534799H527.5849284006089V267.4726535408993z"' + ' p-id="2228" fill="red"></path>' + ' </svg>' + '</span>';
+
+ closeZoomDOM.onclick = function () {
+ _this.closeZoom();
+
+ document.getElementById('closeZoom').setAttribute('class', 'icon hide');
+ document.getElementById('enableZoom').setAttribute('class', 'icon');
+ };
+
+ controsDOM.appendChild(closeZoomDOM);
+ }
+ }
+ /**
+ * 娓叉煋footer
+ */
+
+ /** 鏍规嵁閰嶇疆鍖归厤搴曢儴娓叉煋 */
+
+
+ function matchFooterOpt() {
+ var result = {
+ footerContainer: false,
+ talkModule: false,
+ broadcastModule: false,
+ hdModule: false,
+ fullScreenModule: false
+ };
+ var template = _this.opt.template;
+
+ switch (template) {
+ case 'simple':
+ if (params.footer && params.footer instanceof Array) {
+ var footer = params.footer;
+ result = {
+ footerContainer: true,
+ talkModule: footer.indexOf('talk') !== -1,
+ broadcastModule: footer.indexOf('broadcast') !== -1,
+ hdModule: footer.indexOf('hd') !== -1,
+ fullScreenModule: footer.indexOf('fullScreen') !== -1
+ };
+ }
+
+ break;
+
+ case 'standard':
+ if (params.footer && params.footer instanceof Array) {
+ var footer = params.footer;
+ result = {
+ footerContainer: true,
+ talkModule: footer.indexOf('talk') !== -1,
+ broadcastModule: footer.indexOf('broadcast') !== -1,
+ hdModule: footer.indexOf('hd') !== -1,
+ fullScreenModule: footer.indexOf('fullScreen') !== -1
+ };
+ }
+
+ break;
+
+ case 'security':
+ break;
+
+ case 'voice':
+ result = {
+ footerContainer: true,
+ talkModule: true,
+ broadcastModule: true,
+ hdModule: true,
+ fullScreenModule: true
+ };
+ break;
+ }
+
+ return result;
+ }
+ /** 鏍规嵁閰嶇疆鍖归厤搴曢儴娓叉煋 */
+
+
+ function matchHeaderOpt() {
+ var result = {
+ headerContainer: false,
+ capturePictureModule: false,
+ saveModule: false,
+ zoomModule: false
+ };
+ var template = _this.opt.template;
+
+ switch (template) {
+ case 'simple':
+ if (params.header && params.header instanceof Array) {
+ var header = params.header;
+ result = {
+ headerContainer: true,
+ capturePictureModule: header.indexOf('capturePicture') !== -1,
+ saveModule: header.indexOf('save') !== -1,
+ zoomModule: header.indexOf('zoom') !== -1
+ };
+ }
+
+ break;
+
+ case 'standard':
+ break;
+
+ case 'security':
+ break;
+
+ case 'voice':
+ result = {
+ headerContainer: true,
+ capturePictureModule: true,
+ saveModule: true,
+ zoomModule: true
+ };
+ break;
+ }
+
+ return result;
+ }
+
+ if (matchFooterOpt().footerContainer || _this.opt.plugin.indexOf('talk') !== -1) {
+ var recoderCSS = _this.opt.filePath + '/npm/css/recoder.css';
+ var recoderJs = _this.opt.filePath + '/npm/js/recoder.js';
+ var recorderJs = _this.opt.filePath + '/recorder.js'; // addCss()
+
+ addCss(recoderCSS, function () {});
+ addJs(recoderJs, function () {
+ addJs(recorderJs, function () {});
+ }); // 瀵硅妯″潡
+
+ if (_this.opt.plugin.indexOf('talk') !== -1 || matchFooterOpt().talkModule) {
+ var apiSuccess = function apiSuccess(data) {
+ console.log("data", data);
+
+ if (data.code == 200) {
+ var apiResult = data.data;
+
+ if (apiResult) {
+ // 涓存椂灏唄ttps杞崲涓簑ebsocket
+ var rtcTrunk = apiResult.rtcUrl;
+
+ if (rtcTrunk.indexOf("ws") === -1) {
+ rtcTrunk = rtcTrunk.replace("https", "wss").replace("rtcgw", "rtcgw-ws");
+ }
+
+ _this.opt.rtcUrl = rtcTrunk;
+ _this.opt.ttsUrl = "tts://" + apiResult.ttsUrl;
+ var talk = "talk://" + _this.opt.deviceSerial + ":0:" + _this.opt.channelNo + ":cas.ys7.com:6500";
+ _this.opt.talkLink = _this.opt.ttsUrl + "/" + talk;
+ _this.opt.stream = apiResult.stream;
+ console.log("_this.opt", _this.opt); // 鍔犺浇渚濊禆
+
+ if (!_this.opt.isReliesReady) {
+ var adapeterJS = _this.opt.filePath + '/npm/js/adapeter.js';
+ var janusJS = _this.opt.filePath + '/npm/js/janus.js';
+ var ttsJS = _this.opt.filePath + '/npm/js/tts.js';
+ console.log("鍔犺浇jquery.js");
+ addJs(adapeterJS, function () {
+ console.log("鍔犺浇adapeter.js");
+ addJs(janusJS, function () {
+ console.log("鍔犺浇janus.js");
+ addJs(ttsJS, function () {
+ console.log("鍔犺浇tts.js"); // 鏂囦欢鍔犺浇瀹屾瘯;
+
+ _this.opt.isReliesReady = true;
+ });
+ });
+ }, function () {
+ return !!window.adapter;
+ });
+ } // 鍒涘缓DOM
+
+
+ if (!document.getElementById("audioleft")) {
+ var audioleft = document.createElement('div');
+ audioleft.style.display = 'none';
+ audioleft.id = 'audioleft';
+ document.body.appendChild(audioleft);
+ }
+
+ if (!document.getElementById("audioright")) {
+ var audioright = document.createElement('div');
+ audioright.style.display = 'none';
+ audioright.id = 'audioright';
+ document.body.appendChild(audioright);
+ }
+ }
+ }
+
+ EZUIKit.opt = _this.opt;
+
+ if (window.EZUIKit) {
+ window.EZUIKit.opt = _this.opt;
+ }
+ };
+
+ request(_this.opt.apiDomain, 'POST', {
+ accessToken: _this.opt.accessToken,
+ deviceSerial: _this.opt.deviceSerial,
+ channelNo: _this.opt.channelNo
+ }, '', apiSuccess);
+ }
+
+ if (matchFooterOpt().footerContainer) {
+ /* 鏃堕棿璁℃暟 */
+ var countTime = function countTime(type, start) {
+ clearInterval(EZUIKit.state.countTimer);
+
+ if (type === 'add') {
+ var i = start;
+ EZUIKit.state.countTimer = setInterval(function () {
+ ++i;
+ document.getElementById("time-area").innerHTML = formatSeconds(i);
+ }, 1000);
+ } else if (type === 'sub') {
+ var i = start;
+ EZUIKit.state.countTimer = setInterval(function () {
+ if (i > 0) {
+ i--;
+ document.getElementById("time-area").innerHTML = formatSeconds(i);
+ } else {
+ clearInterval(EZUIKit.state.countTimer);
+ EZUIKit.state.countTimer = undefined;
+ console.log("鍊掕鏃剁粨鏉燂紝寮�鍚0闊�"); // decoder.openSound(0);
+ }
+ }, 1000);
+ } else if (type === 'destory') {
+ clearInterval(EZUIKit.state.countTimer);
+ EZUIKit.state.countTimer = undefined;
+ document.getElementById("time-area").innerHTML = '00:00';
+ } //灏嗙鏁拌浆鎹负鏃跺垎绉掓牸寮�
+
+
+ function formatSeconds(value) {
+ var theTime = parseInt(value); // 绉�
+
+ var middle = 0; // 鍒�
+
+ var hour = 0; // 灏忔椂
+
+ var secondV = '00';
+ var minV = '00';
+ var hourV = '00';
+
+ if (theTime > 59) {
+ middle = parseInt(theTime / 60);
+ theTime = parseInt(theTime % 60);
+
+ if (middle > 59) {
+ hour = parseInt(middle / 60);
+ middle = parseInt(middle % 60);
+ }
+ }
+
+ secondV = parseInt(theTime) > 9 ? parseInt(theTime) : '0' + parseInt(theTime);
+ minV = parseInt(middle) > 9 ? parseInt(middle) : '0' + parseInt(middle);
+ hourV = parseInt(hour) > 9 ? parseInt(hour) : '0' + parseInt(hour);
+
+ if (hour > 0) {
+ return hourV + ':' + minV + ':' + secondV;
+ } else if (middle > 0) {
+ return minV + ':' + secondV;
+ } else {
+ return '00:' + secondV;
+ }
+ }
+ };
+
+ // 搴曢儴瀹瑰櫒
+ var footerContainer = document.createElement('div');
+ footerContainer.setAttribute("class", 'audio-controls');
+ domElement.appendChild(footerContainer);
+
+ if (matchFooterOpt().hdModule || matchFooterOpt().fullScreenModule) {
+ // 搴曢儴鍙充晶鍏冪礌
+ var rightContros = document.createElement('div');
+ rightContros.setAttribute('class', 'contros');
+ footerContainer.appendChild(rightContros);
+
+ if (matchFooterOpt().hdModule) {
+ // 楂樻竻-鏍囨竻鍒囨崲
+ var hdDom = document.createElement('span');
+ hdDom.setAttribute('id', 'video-hd');
+ hdDom.innerHTML = _this.opt.url.indexOf('.hd') === -1 ? '鏍囨竻' : '楂樻竻';
+
+ hdDom.onclick = function () {
+ // 鍋滄
+ if (_this.opt.videoLoading) {
+ layer.msg("瑙嗛鍔犺浇涓紝璇风◢鍚�");
+ return false;
+ } else {
+ var stopPromise = _this.stop();
+
+ _this.opt.videoLoading = true;
+ stopPromise.then(function (data) {
+ _this.opt.videoLoading = false;
+
+ if (_this.opt.url.indexOf('.hd') === -1) {
+ _this.opt.url = _this.opt.url.replace('.live', '.hd.live');
+ hdDom.innerHTML = _this.opt.url.indexOf('.hd') === -1 ? '鏍囨竻' : '楂樻竻';
+ } else {
+ _this.opt.url = _this.opt.url.replace('.hd.live', '.live');
+ hdDom.innerHTML = _this.opt.url.indexOf('.hd') === -1 ? '鏍囨竻' : '楂樻竻';
+ }
+
+ _this.play(_this.opt.url);
+ })["catch"](function (error) {
+ console.log("error", error);
+ });
+ } //iframe.src = domain +"/ezopen/h5/iframe?url=" + _this.opt.url.replace('.hd.live', '.live') + "&autoplay=1&audio=" + _this.opt.audio + "&accessToken=" + _this.opt.accessToken + "&templete=" + 0;
+
+ };
+
+ rightContros.appendChild(hdDom);
+ }
+
+ if (matchFooterOpt().fullScreenModule) {
+ // 澹伴煶鎺у埗
+ var openSoundDOM = document.createElement('span');
+ openSoundDOM.setAttribute('class', 'hide');
+ openSoundDOM.setAttribute('id', 'ezuikit-open-sound');
+ openSoundDOM.setAttribute('title', '鎵撳紑澹伴煶');
+ openSoundDOM.setAttribute('style', 'vertical-align: top;');
+ openSoundDOM.innerHTML = '<svg t="1590476263239" class="icon" viewBox="0 0 1178 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2273" width="16" height="16"><path d="M665.6 51.2 665.6 51.2c-10.24-30.72-40.96-51.2-71.68-51.2-5.12 0-15.36 0-20.48 5.12l0 0L358.4 153.6 51.2 209.92l0 0C20.48 220.16 0 250.88 0 281.6 0 286.72 0 291.84 0 307.2l0 0 0 409.6 0 0c0 15.36 0 20.48 0 25.6 0 30.72 20.48 61.44 51.2 71.68l0 0L358.4 870.4l97.28 71.68 107.52 76.8 0 0c5.12 5.12 15.36 5.12 25.6 5.12 40.96 0 76.8-35.84 76.8-76.8 0-10.24 0-10.24 0-25.6l0 0L665.6 51.2zM563.2 870.4l-153.6-102.4-307.2-51.2L102.4 307.2l307.2-51.2 153.6-102.4L563.2 870.4z" p-id="2274" fill="#FF0000"></path><path d="M1049.6 537.6l112.64-112.64c20.48-20.48 20.48-56.32 0-76.8-20.48-20.48-56.32-20.48-76.8 0L972.8 460.8l-112.64-112.64c0 0 0 0 0 0-20.48-20.48-56.32-20.48-76.8 0 0 0 0 0 0 0-20.48 20.48-20.48 56.32 0 76.8l112.64 112.64-112.64 112.64c-20.48 20.48-20.48 56.32 0 76.8 20.48 20.48 56.32 20.48 76.8 0L972.8 614.4l112.64 112.64c20.48 20.48 56.32 20.48 76.8 0s20.48-56.32 0-76.8L1049.6 537.6z" p-id="2275" fill="#FF0000"></path></svg>';
+
+ openSoundDOM.onclick = function () {
+ _this.openSound(0);
+
+ openSoundDOM.setAttribute('class', 'hide');
+ closeSoundDOM.setAttribute('class', '');
+ }; // 澹伴煶鎺у埗
+
+
+ var closeSoundDOM = document.createElement('span');
+ openSoundDOM.setAttribute('id', 'ezuikit-close-sound');
+ closeSoundDOM.setAttribute('class', 'hide');
+ closeSoundDOM.setAttribute('title', '鍏抽棴澹伴煶');
+ closeSoundDOM.setAttribute('style', 'vertical-align: top;');
+ closeSoundDOM.innerHTML = '<svg t="1590414410633" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="20545" width="16" height="16"><path d="M840.533333 98.133333c-17.066667-17.066667-42.666667-17.066667-59.733333 0-17.066667 17.066667-17.066667 42.666667 0 59.733334C883.2 256 938.666667 392.533333 938.666667 533.333333c0 140.8-55.466667 277.333333-157.866667 375.466667-17.066667 17.066667-17.066667 42.666667 0 59.733333 8.533333 8.533333 21.333333 12.8 29.866667 12.8 8.533333 0 21.333333-4.266667 29.866666-12.8 115.2-110.933333 183.466667-268.8 183.466667-435.2 0-166.4-68.266667-324.266667-183.466667-435.2zM571.733333 12.8c-17.066667-8.533333-34.133333-4.266667-46.933333 8.533333L281.6 256H42.666667c-25.6 0-42.666667 17.066667-42.666667 42.666667v426.666666c0 25.6 17.066667 42.666667 42.666667 42.666667h238.933333l243.2 234.666667c8.533333 8.533333 17.066667 12.8 29.866667 12.8 4.266667 0 12.8 0 17.066666-4.266667 17.066667-8.533333 25.6-21.333333 25.6-38.4V51.2c0-17.066667-8.533333-34.133333-25.6-38.4zM512 870.4l-183.466667-179.2c-8.533333-4.266667-17.066667-8.533333-29.866666-8.533333H85.333333V341.333333h213.333334c12.8 0 21.333333-4.266667 29.866666-12.8L512 153.6v716.8z" p-id="20546" fill="#ffffff"></path><path d="M759.466667 349.866667c-12.8-21.333333-38.4-25.6-59.733334-8.533334-21.333333 12.8-25.6 38.4-8.533333 59.733334 21.333333 29.866667 34.133333 76.8 34.133333 123.733333 0 46.933333-12.8 93.866667-34.133333 123.733333-12.8 21.333333-8.533333 46.933333 8.533333 59.733334 8.533333 4.266667 17.066667 8.533333 25.6 8.533333 12.8 0 25.6-4.266667 34.133334-17.066667 34.133333-46.933333 51.2-106.666667 51.2-174.933333 0-68.266667-17.066667-128-51.2-174.933333z" p-id="20547" fill="#ffffff"></path></svg>';
+
+ closeSoundDOM.onclick = function () {
+ _this.closeSound(0);
+
+ openSoundDOM.setAttribute('class', '');
+ closeSoundDOM.setAttribute('class', 'hide');
+ };
+
+ rightContros.appendChild(openSoundDOM);
+ rightContros.appendChild(closeSoundDOM);
+ } // 鏍规嵁褰撳墠闊抽閰嶇疆灞曠ず
+
+
+ if (_this.opt.audio == 1) {
+ closeSoundDOM.setAttribute('class', '');
+ } else {
+ openSoundDOM.setAttribute('class', '');
+
+ _this.closeSound(0);
+ }
+
+ if (matchFooterOpt().fullScreenModule) {
+ // 鍏ㄥ睆鎺у埗
+ var fullScreenDOM = document.createElement('span');
+ fullScreenDOM.setAttribute('title', '鍏ㄥ睆');
+ fullScreenDOM.setAttribute('style', 'vertical-align: top;');
+ fullScreenDOM.innerHTML = '<svg id="fullScreen" t="1578020167938" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5035" width="16" height="16"> <path d="M348.373333 625.706667l-128 128-64 64v-128a33.28 33.28 0 0 0-35.413333-35.413334A33.493333 33.493333 0 0 0 85.333333 689.706667v213.333333A33.706667 33.706667 0 0 0 120.96 938.666667h213.333333a35.626667 35.626667 0 0 0 0-71.04h-128l64-64 128-128a35.2 35.2 0 0 0-49.92-49.92zM206.293333 156.373333h128a33.28 33.28 0 0 0 35.413334-35.413333A33.493333 33.493333 0 0 0 334.293333 85.333333H113.706667c-7.04 0-14.08 7.04-21.333334 14.293334a26.026667 26.026667 0 0 0-7.04 21.333333v213.333333a33.493333 33.493333 0 0 0 35.626667 35.413334 33.28 33.28 0 0 0 35.413333-35.413334v-128l192 192a35.2 35.2 0 0 0 49.92-49.92zM903.04 85.333333h-213.333333a33.493333 33.493333 0 0 0-35.413334 35.626667 33.28 33.28 0 0 0 35.413334 35.413333h128l-64 64-128 128a35.2 35.2 0 0 0 49.92 49.92l128-128 64-64v128a35.626667 35.626667 0 0 0 71.04 0v-213.333333A33.706667 33.706667 0 0 0 903.04 85.333333zM903.04 654.293333a33.28 33.28 0 0 0-35.413333 35.413334v128l-64-64-128-128a35.2 35.2 0 0 0-49.92 49.92l128 128 64 64h-128a35.626667 35.626667 0 0 0 0 71.04h213.333333A33.706667 33.706667 0 0 0 938.666667 903.04v-213.333333a33.493333 33.493333 0 0 0-35.626667-35.413334z" p-id="5036" fill="#ffffff"></path></svg>';
+
+ fullScreenDOM.onclick = function () {
+ _this.fullScreen();
+ };
+
+ rightContros.appendChild(fullScreenDOM);
+ }
+ }
+
+ if (matchFooterOpt().talkModule) {
+ // 瀵硅
+ var startTalkDOM = document.createElement('div');
+ var stopTalkDOM = document.createElement('div');
+ startTalkDOM.setAttribute("class", "ptp-talk off");
+ startTalkDOM.innerHTML = '<span title="瀵硅">' + '<svg t="1581930496966" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"' + ' p-id="1641" width="16" height="16">' + ' <path' + ' d="M715.648 647.872c-30.208-22.336-61.568 39.36-100.992 77.44-39.36 38.08-34.112 31.488-123.392-17.088S311.488 540.224 280 491.648C248.448 443.072 265.472 424.704 265.472 424.704s78.72-62.976 97.152-81.344c18.368-18.368 13.12-30.208 13.12-30.208l-128.64-190.144c-23.616-5.184-64.32 5.12-128.576 57.6C54.208 233.088 30.592 353.856 151.296 575.68c120.768 221.824 347.84 330.752 485.568 374.08 137.856 43.328 228.416-61.696 249.408-103.68 21.056-41.984 13.12-85.312 13.12-85.312S745.856 670.208 715.648 647.872z"' + ' p-id="1642" fill="#ffffff"></path>' + ' <path' + ' d="M715.328 64C580.992 64 472.192 172.864 472.192 307.2s108.8 243.2 243.136 243.2 243.2-108.864 243.2-243.2S849.6 64 715.328 64zM715.328 461.056c-84.992 0-153.856-68.864-153.856-153.856s68.864-153.856 153.856-153.856 153.856 68.928 153.856 153.856S800.32 461.056 715.328 461.056z"' + ' p-id="1643" fill="#ffffff"></path>' + ' <path' + ' d="M777.472 277.376c-18.176 0-32.96-14.784-32.96-33.024 0-8.448 3.136-16.064 8.32-21.888-11.52-5.12-24.128-8-37.568-8-51.2 0-92.672 41.472-92.672 92.736s41.472 92.736 92.672 92.736S808.064 358.4 808.064 307.2c0-13.696-3.072-26.688-8.384-38.4C793.728 274.112 786.048 277.376 777.472 277.376zM715.328 340.928c-18.624 0-33.664-15.104-33.664-33.728 0-18.624 15.04-33.728 33.664-33.728 18.688 0 33.728 15.104 33.728 33.728C749.056 325.824 734.016 340.928 715.328 340.928z"' + ' p-id="1644" fill="#ffffff"></path>' + ' </svg>' + ' </span>' + ' <span>寮�鍚璁�</span>';
+
+ startTalkDOM.onclick = function () {
+ console.log("EZUIKit.state.countTimer", EZUIKit.state.countTimer);
+
+ if (EZUIKit.state.countTimer) {
+ window.layer.msg("璇煶璁惧姝e繖锛岃绋嶅悗閲嶈瘯");
+ return false;
+ }
+
+ countTime('add', 0);
+ console.log("寮�濮嬪璁诧紝鍏抽棴澹伴煶");
+
+ _this.closeSound(0);
+
+ console.log(_this.opt);
+
+ _this.startTalk();
+
+ this.setAttribute("class", "ptp-talk off hide");
+ stopTalkDOM.setAttribute("class", "ptp-talk on");
+ };
+
+ stopTalkDOM.setAttribute("class", "ptp-talk on hide");
+ stopTalkDOM.innerHTML = '<span title="瀵硅">' + ' <svg t="1581930496966" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"' + ' p-id="1641" width="16" height="16">' + ' <path' + ' d="M715.648 647.872c-30.208-22.336-61.568 39.36-100.992 77.44-39.36 38.08-34.112 31.488-123.392-17.088S311.488 540.224 280 491.648C248.448 443.072 265.472 424.704 265.472 424.704s78.72-62.976 97.152-81.344c18.368-18.368 13.12-30.208 13.12-30.208l-128.64-190.144c-23.616-5.184-64.32 5.12-128.576 57.6C54.208 233.088 30.592 353.856 151.296 575.68c120.768 221.824 347.84 330.752 485.568 374.08 137.856 43.328 228.416-61.696 249.408-103.68 21.056-41.984 13.12-85.312 13.12-85.312S745.856 670.208 715.648 647.872z"' + ' p-id="1642" fill="#ff0000"></path>' + ' <path' + ' d="M715.328 64C580.992 64 472.192 172.864 472.192 307.2s108.8 243.2 243.136 243.2 243.2-108.864 243.2-243.2S849.6 64 715.328 64zM715.328 461.056c-84.992 0-153.856-68.864-153.856-153.856s68.864-153.856 153.856-153.856 153.856 68.928 153.856 153.856S800.32 461.056 715.328 461.056z"' + ' p-id="1643" fill="#ff0000"></path>' + ' <path' + ' d="M777.472 277.376c-18.176 0-32.96-14.784-32.96-33.024 0-8.448 3.136-16.064 8.32-21.888-11.52-5.12-24.128-8-37.568-8-51.2 0-92.672 41.472-92.672 92.736s41.472 92.736 92.672 92.736S808.064 358.4 808.064 307.2c0-13.696-3.072-26.688-8.384-38.4C793.728 274.112 786.048 277.376 777.472 277.376zM715.328 340.928c-18.624 0-33.664-15.104-33.664-33.728 0-18.624 15.04-33.728 33.664-33.728 18.688 0 33.728 15.104 33.728 33.728C749.056 325.824 734.016 340.928 715.328 340.928z"' + ' p-id="1644" fill="#ff0000"></path>' + ' </svg>' + ' </span>' + '<span>鍏抽棴瀵硅</span>';
+
+ stopTalkDOM.onclick = function () {
+ console.log(_this.opt);
+
+ _this.stopTalk();
+
+ countTime('destory', 0);
+
+ _this.openSound(0);
+
+ this.setAttribute("class", "ptp-talk on hide");
+ startTalkDOM.setAttribute("class", "ptp-talk off");
+ };
+
+ footerContainer.appendChild(startTalkDOM);
+ footerContainer.appendChild(stopTalkDOM);
+ }
+
+ if (matchFooterOpt().broadcastModule) {
+ var fetchVoiceList = function fetchVoiceList(page) {
+ function apiSuccess(data) {
+ console.log("data", data);
+
+ if (data.code == 200) {
+ randerVoliceList(data.data, 5);
+ EZUIKit.state.page = data.page.page; // 濡傛灉鐢ㄦ埛璇煶鍒楄〃涓虹┖
+
+ if (page == 0 && data.data.length == 0 && !EZUIKit.state.fetchDefaultList) {
+ // 鑾峰彇鐢ㄦ埛璇煶涓虹┖
+ EZUIKit.state.fetchDefaultList = true;
+ fetchVoiceList(0);
+ }
+ }
+ }
+
+ request(domain + '/api/lapp/voice/query', 'POST', {
+ accessToken: _this.opt.accessToken,
+ pageStart: page,
+ pageSize: EZUIKit.state.pageSize,
+ "default": EZUIKit.state.fetchDefaultList ? 'true' : 'false'
+ }, '', apiSuccess);
+ };
+
+ var randerVoliceList = function randerVoliceList(data) {
+ console.log("renderVoliceList", data);
+
+ if (data && data.length > 0) {
+ for (var i = 0; i < data.length; i++) {
+ var voiceItem = document.createElement('li');
+ voiceItem.innerHTML = "<li class='voice-item' id='voice-item-" + i + "' data-time=" + (data[i]["duration"] || 20) + " data-url=" + data[i]["fileUrl"] + ">" + (data[i]["voiceName"].length > 10 ? data[i]["voiceName"].substr(0, 10) + "..." : data[i]["voiceName"]) + "</li>";
+ document.getElementsByClassName('voice-list-ul')[0].append(voiceItem); // "<li class='voice-item' id='voice-item-" + i + "' data-time=" + (data[i]["duration"] || 20) + " data-url=" + data[i]["fileUrl"] + ">" + (data[i]["voiceName"].length > 10 ? (data[i]["voiceName"].substr(0, 10) + "...") : data[i]["voiceName"]) + "</li>";
+ // $("#voice-list ul").append("<li class='voice-item' id='voice-item-" + i + "' data-time=" + (data[i]["duration"] || 20) + " data-url=" + data[i]["fileUrl"] + ">" + (data[i]["voiceName"].length > 10 ? (data[i]["voiceName"].substr(0, 10) + "...") : data[i]["voiceName"]) + "</li>");
+
+ voiceItem.onclick = function (e) {
+ console.log("鐐瑰嚮鍏冪礌", e.target, e.target.dataset.url);
+ var voiceUrl = e.target.dataset.url;
+ var time = e.target.dataset.time;
+ playListOfVoice(voiceUrl, time);
+ };
+ }
+
+ if (data.length === EZUIKit.state.pageSize) {
+ document.getElementById('voice-list-end').innerHTML = "鍚戜笅婊氬姩鍔犺浇鏇村";
+ } else {
+ document.getElementById('voice-list-end').innerHTML = "娌℃湁鏇村鏁版嵁浜�";
+ }
+ }
+ };
+
+ var playListOfVoice = function playListOfVoice(voiceUrl, time) {
+ console.log("鎾斁璇煶", voiceUrl, time); // decoder && decoder.closeSound(0);
+
+ function apiSuccess(data) {
+ console.log("data.data", data.data);
+
+ if (data.code == 200) {
+ // $("#startBroadcast").show();
+ // $("#stopBroadcast").hide();
+ countTime('sub', parseInt(time));
+ } else if (data.code == "10001") {
+ window.layer.msg("鏈壘鍒板綋鍓嶈闊�");
+ } else {
+ window.layer.msg(data.msg || '鍙戦�佸け璐ワ紝璇风◢鍚庡啀璇�');
+ } // padding = false;
+
+ }
+
+ request(domain + '/api/lapp/voice/send', 'POST', {
+ accessToken: _this.opt.accessToken,
+ deviceSerial: _this.opt.deviceSerial,
+ channelNo: _this.opt.channelNo,
+ fileUrl: voiceUrl
+ }, '', apiSuccess);
+ }; // 鑷畾涔夎闊�
+ // 瀵硅
+
+
+ var startBroadcastDOM = document.createElement('div');
+ var stopBroadcastDOM = document.createElement('div');
+ startBroadcastDOM.setAttribute("class", 'broadcast off');
+ stopBroadcastDOM.setAttribute("class", "broadcast on hide");
+ startBroadcastDOM.innerHTML = ' <span title="璇煶鎾姤">' + ' <svg t="1583561695846" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"' + ' p-id="1126" width="16" height="16">' + ' <path' + ' d="M513.82044445 964.38044445c-8.192 0-15.47377778-2.73066667-21.84533334-8.192 0 0-46.42133333-41.87022222-99.21422222-86.47111112-89.20177778-73.728-117.41866667-88.29155555-123.79022222-90.112H35.04355555c-14.56355555 0-26.39644445-11.83288889-26.39644444-27.30666666V271.70133333c0-14.56355555 11.83288889-27.30666667 26.39644444-27.30666666H246.21511111c7.28177778-2.73066667 37.31911111-15.47377778 137.44355556-91.02222222 58.25422222-43.69066667 111.04711111-86.47111111 111.04711111-86.47111112 5.46133333-4.55111111 12.74311111-7.28177778 20.02488889-7.28177778 4.55111111 0 10.01244445 0.91022222 14.56355555 3.6408889 10.92266667 5.46133333 18.20444445 17.29422222 18.20444445 30.03733333v837.40444444c0 12.74311111-7.28177778 25.48622222-19.11466667 30.94755556-5.46133333 1.82044445-10.01244445 2.73066667-14.56355555 2.73066667zM270.79111111 724.992c19.11466667 0 48.24177778 8.192 167.48088889 106.496 16.384 13.65333333 33.67822222 28.21688889 51.88266667 43.69066667l5.46133333 4.55111111V139.71911111l-5.46133333 3.64088889c-22.75555555 17.29422222-44.60088889 34.58844445-65.536 50.06222222C293.54666667 291.72622222 264.41955555 299.008 245.30488889 299.008H82.37511111c-20.02488889 0-21.84533333 12.74311111-21.84533333 26.39644445V694.04444445c0 23.66577778 6.37155555 30.03733333 28.21688889 30.03733333h180.224l1.82044444 0.91022222z m520.64711111 162.01955555c-14.56355555 0-26.39644445-11.83288889-26.39644444-27.30666666 0-11.83288889 8.192-20.02488889 16.384-24.576 112.86755555-67.35644445 182.04444445-191.14666667 182.04444444-324.03911111 0-132.89244445-70.08711111-256.68266667-182.04444444-324.03911111-10.01244445-5.46133333-15.47377778-14.56355555-15.47377778-24.576 0-14.56355555 11.83288889-27.30666667 26.39644445-27.30666667 5.46133333 0 10.01244445 1.82044445 16.384 5.46133333 128.34133333 76.45866667 207.53066667 218.45333333 207.53066666 369.55022222 0 152.00711111-80.09955555 293.09155555-208.44088889 369.55022223-6.37155555 5.46133333-10.92266667 7.28177778-16.384 7.28177777z m-90.112-152.91733333c-14.56355555 0-26.39644445-11.83288889-26.39644444-27.30666667 0-10.01244445 4.55111111-18.20444445 12.74311111-23.66577777 61.89511111-34.58844445 100.12444445-100.12444445 100.12444444-171.12177778 0-70.08711111-37.31911111-134.71288889-96.48355555-170.21155555-8.192-4.55111111-12.74311111-13.65333333-12.74311111-23.66577778 0-14.56355555 11.83288889-27.30666667 26.39644444-27.30666667 4.55111111 0 11.83288889 2.73066667 15.47377778 4.55111111 74.63822222 44.60088889 121.96977778 127.43111111 121.96977778 215.72266667 0 90.112-48.24177778 173.85244445-125.61066667 218.45333333-1.82044445 0-9.10222222 4.55111111-15.47377778 4.55111111z"' + ' fill="#ffffff" p-id="1127"></path>' + ' </svg>' + '</span>' + '<span>璇煶鎾姤</span>';
+
+ startBroadcastDOM.onclick = function () {
+ this.setAttribute("class", "broadcast off hide");
+ stopBroadcastDOM.setAttribute("class", "broadcast on");
+ };
+
+ stopBroadcastDOM.innerHTML = '<div class="pop-hover">' + ' <div class="pop-hover-content">' + ' <div class="vioce-list" id="voice-list">' + ' <ul class="voice-list-ul">' + ' </ul>' + ' <div id="voice-list-end"></div>' + ' </div>' + ' <div id="voice-custom" style="text-align: center;">鑷畾涔夎闊�</div>' + ' </div>' + '</div>' + '<span title="璇煶鎾姤">' + ' <svg t="1583561695846" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"' + ' p-id="1126" width="16" height="16">' + ' <path' + ' d="M513.82044445 964.38044445c-8.192 0-15.47377778-2.73066667-21.84533334-8.192 0 0-46.42133333-41.87022222-99.21422222-86.47111112-89.20177778-73.728-117.41866667-88.29155555-123.79022222-90.112H35.04355555c-14.56355555 0-26.39644445-11.83288889-26.39644444-27.30666666V271.70133333c0-14.56355555 11.83288889-27.30666667 26.39644444-27.30666666H246.21511111c7.28177778-2.73066667 37.31911111-15.47377778 137.44355556-91.02222222 58.25422222-43.69066667 111.04711111-86.47111111 111.04711111-86.47111112 5.46133333-4.55111111 12.74311111-7.28177778 20.02488889-7.28177778 4.55111111 0 10.01244445 0.91022222 14.56355555 3.6408889 10.92266667 5.46133333 18.20444445 17.29422222 18.20444445 30.03733333v837.40444444c0 12.74311111-7.28177778 25.48622222-19.11466667 30.94755556-5.46133333 1.82044445-10.01244445 2.73066667-14.56355555 2.73066667zM270.79111111 724.992c19.11466667 0 48.24177778 8.192 167.48088889 106.496 16.384 13.65333333 33.67822222 28.21688889 51.88266667 43.69066667l5.46133333 4.55111111V139.71911111l-5.46133333 3.64088889c-22.75555555 17.29422222-44.60088889 34.58844445-65.536 50.06222222C293.54666667 291.72622222 264.41955555 299.008 245.30488889 299.008H82.37511111c-20.02488889 0-21.84533333 12.74311111-21.84533333 26.39644445V694.04444445c0 23.66577778 6.37155555 30.03733333 28.21688889 30.03733333h180.224l1.82044444 0.91022222z m520.64711111 162.01955555c-14.56355555 0-26.39644445-11.83288889-26.39644444-27.30666666 0-11.83288889 8.192-20.02488889 16.384-24.576 112.86755555-67.35644445 182.04444445-191.14666667 182.04444444-324.03911111 0-132.89244445-70.08711111-256.68266667-182.04444444-324.03911111-10.01244445-5.46133333-15.47377778-14.56355555-15.47377778-24.576 0-14.56355555 11.83288889-27.30666667 26.39644445-27.30666667 5.46133333 0 10.01244445 1.82044445 16.384 5.46133333 128.34133333 76.45866667 207.53066667 218.45333333 207.53066666 369.55022222 0 152.00711111-80.09955555 293.09155555-208.44088889 369.55022223-6.37155555 5.46133333-10.92266667 7.28177778-16.384 7.28177777z m-90.112-152.91733333c-14.56355555 0-26.39644445-11.83288889-26.39644444-27.30666667 0-10.01244445 4.55111111-18.20444445 12.74311111-23.66577777 61.89511111-34.58844445 100.12444445-100.12444445 100.12444444-171.12177778 0-70.08711111-37.31911111-134.71288889-96.48355555-170.21155555-8.192-4.55111111-12.74311111-13.65333333-12.74311111-23.66577778 0-14.56355555 11.83288889-27.30666667 26.39644444-27.30666667 4.55111111 0 11.83288889 2.73066667 15.47377778 4.55111111 74.63822222 44.60088889 121.96977778 127.43111111 121.96977778 215.72266667 0 90.112-48.24177778 173.85244445-125.61066667 218.45333333-1.82044445 0-9.10222222 4.55111111-15.47377778 4.55111111z"' + ' fill="#ff0000" p-id="1127"></path>' + ' </svg>' + '</span>' + '<span>璇煶鎾姤</span>'; // //鑷畾涔夎闊冲敜璧�
+ // document.getElementById("voice-custom").onclick = function(){
+ // console.log("鏄剧ず鑷畾涔夎闊�");
+ // }
+
+ stopBroadcastDOM.onclick = function () {
+ this.setAttribute("class", "broadcast on hide");
+ startBroadcastDOM.setAttribute("class", "broadcast off");
+ };
+
+ footerContainer.appendChild(startBroadcastDOM);
+ footerContainer.appendChild(stopBroadcastDOM); // 鍙敜鑷畾涔夎瑷�
+
+ document.getElementById("voice-custom").onclick = function () {
+ console.log("鏄剧ず鑷畾涔夎闊�");
+ startSpeakDOM.setAttribute('class', 'speak off');
+ }; // 鑾峰彇璇煶鍒楄〃
+
+
+ fetchVoiceList(0);
+ var startSpeakDOM = document.createElement('div');
+ var stopSpeakDOM = document.createElement('div');
+ startSpeakDOM.setAttribute('class', 'speak off hide');
+ stopSpeakDOM.setAttribute('class', 'speak on hide');
+ startSpeakDOM.setAttribute('id', 'startSpeak');
+ stopSpeakDOM.setAttribute('id', 'stopSpeak');
+ startSpeakDOM.innerHTML = '<span title="鎸変綇璇磋瘽">' + ' <svg t="1581994757678" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"' + ' p-id="1639" width="16" height="16">' + ' <path' + ' d="M757.059829 393.846154v-52.512821h262.564103v52.512821H757.059829z m-420.102564 481.367521v96.273504h175.042735a8.752137 8.752137 0 0 1 8.752137 8.752137v35.008547a8.752137 8.752137 0 0 1-8.752137 8.752137H109.401709a8.752137 8.752137 0 0 1-8.752136-8.752137v-35.008547a8.752137 8.752137 0 0 1 8.752136-8.752137h175.042735v-96.273504C129.767932 875.213675 4.376068 749.821812 4.376068 595.145299V463.863248a26.25641 26.25641 0 1 1 52.512821 0v113.777778c0 140.174222 113.637744 253.811966 253.811966 253.811965s253.811966-113.637744 253.811966-253.811965V463.863248a26.25641 26.25641 0 1 1 52.51282 0v131.282051c0 154.676513-125.391863 280.068376-280.068376 280.068376z m-26.25641-96.273504c-111.178393 0-201.299145-90.120752-201.299146-201.299145V201.299145C109.401709 90.120752 199.522462 0 310.700855 0s201.299145 90.120752 201.299145 201.299145v376.341881c0 111.178393-90.120752 201.299145-201.299145 201.299145z m691.418803-280.068376H757.059829v-52.512821h245.059829v52.512821z m-17.504273 105.025641H757.059829v-52.512821h227.555556v52.512821z m-17.504274 105.025641H757.059829v-52.512821h210.051282v52.512821z m-8.752137 105.025641H757.059829v-52.512821h201.299145v52.512821z m-17.504273 105.025641H757.059829v-52.512821h183.794872v52.512821z m-26.25641 105.025641H757.059829v-52.512821h157.538462v52.512821z"' + ' p-id="1640" fill="#ffffff"></path>' + ' </svg>' + '</span>' + '<span>鎸変綇璇磋瘽</span>';
+ stopSpeakDOM.innerHTML = '<span title="鎸変綇璇磋瘽">' + '<svg t="1581994757678" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"' + ' p-id="1639" width="16" height="16">' + ' <path' + ' d="M757.059829 393.846154v-52.512821h262.564103v52.512821H757.059829z m-420.102564 481.367521v96.273504h175.042735a8.752137 8.752137 0 0 1 8.752137 8.752137v35.008547a8.752137 8.752137 0 0 1-8.752137 8.752137H109.401709a8.752137 8.752137 0 0 1-8.752136-8.752137v-35.008547a8.752137 8.752137 0 0 1 8.752136-8.752137h175.042735v-96.273504C129.767932 875.213675 4.376068 749.821812 4.376068 595.145299V463.863248a26.25641 26.25641 0 1 1 52.512821 0v113.777778c0 140.174222 113.637744 253.811966 253.811966 253.811965s253.811966-113.637744 253.811966-253.811965V463.863248a26.25641 26.25641 0 1 1 52.51282 0v131.282051c0 154.676513-125.391863 280.068376-280.068376 280.068376z m-26.25641-96.273504c-111.178393 0-201.299145-90.120752-201.299146-201.299145V201.299145C109.401709 90.120752 199.522462 0 310.700855 0s201.299145 90.120752 201.299145 201.299145v376.341881c0 111.178393-90.120752 201.299145-201.299145 201.299145z m691.418803-280.068376H757.059829v-52.512821h245.059829v52.512821z m-17.504273 105.025641H757.059829v-52.512821h227.555556v52.512821z m-17.504274 105.025641H757.059829v-52.512821h210.051282v52.512821z m-8.752137 105.025641H757.059829v-52.512821h201.299145v52.512821z m-17.504273 105.025641H757.059829v-52.512821h183.794872v52.512821z m-26.25641 105.025641H757.059829v-52.512821h157.538462v52.512821z"' + ' p-id="1640" fill="#ff0000"></path>' + '</svg>' + '</span>' + '<span>鏉惧紑鍙戦��</span>';
+ footerContainer.appendChild(startSpeakDOM);
+ footerContainer.appendChild(stopSpeakDOM);
+
+ document.getElementById("voice-list").onscroll = function (e) {
+ var sum = this.scrollHeight;
+ console.log("sum", sum, this.scrollTop, document.getElementById("voice-list").clientHeight);
+
+ if (sum <= this.scrollTop + this.clientHeight) {
+ console.log("鎷栧姩鍒板簳锛屾墽琛屽姞杞�", EZUIKit.state.page);
+ fetchVoiceList(++EZUIKit.state.page);
+ }
+ }; // $("#voice-list").unbind("scroll").bind("scroll", function (e) {
+ // // console.log("e",e,this.scrollHeight, $(this).scrollTop() + $(this).height())
+ // var sum = this.scrollHeight;
+ // if (sum <= $(this).scrollTop() + $(this).height()) {
+ // console.log("鎷栧姩鍒板簳锛屾墽琛屽姞杞�", page);
+ // fetchVoiceList(++page);
+ // }
+ // loading = false;
+ // });
+ // time-area
+
+
+ var timeAreaDOM = document.createElement('div');
+ timeAreaDOM.setAttribute('class', 'time-area');
+ timeAreaDOM.setAttribute('id', 'time-area');
+ timeAreaDOM.innerHTML = '00:00';
+ footerContainer.appendChild(timeAreaDOM); // 鎸変綇璇磋瘽
+
+ var recorder;
+
+ document.getElementById('startSpeak').onmousedown = function () {
+ if (EZUIKit.state.countTimer) {
+ window.layer.msg("璇煶璁惧姝e繖锛岃绋嶅悗閲嶈瘯");
+ return false;
+ }
+
+ console.log("鎸変綇璇磋瘽");
+ startSpeakDOM.setAttribute('class', 'speak off hide');
+ stopSpeakDOM.setAttribute('class', 'speak on'); // console.log("startRecording",startRecording);
+ // startRecording();
+
+ voiceInit();
+ countTime('add', 0);
+ setTimeout(function () {
+ EZUIKit.state.recodeTime = 0;
+ startRecording();
+ }, 1000);
+
+ if (EZUIKit.state.recodeTimer) {
+ // 鍏堟竻绌鸿鏁板櫒
+ clearInterval(EZUIKit.state.recodeTimer);
+ }
+
+ EZUIKit.state.recodeTimer = setInterval(function () {
+ if (EZUIKit.state.recodeTime >= 59) {
+ _this.stopTalk();
+
+ countTime('destory', 0);
+ this.setAttribute("class", "ptp-talk on hide");
+ startTalkDOM.setAttribute("class", "ptp-talk off");
+ window.layer.msg("涓嶈秴杩�1鍒嗛挓");
+ } else {
+ EZUIKit.state.recodeTime = EZUIKit.state.recodeTime + 1;
+ }
+ }, 1000);
+ /** 褰曢煶鎺у埗 */
+
+ var audio_context;
+
+ function startUserMedia(stream) {
+ var input = audio_context.createMediaStreamSource(stream);
+ recorder = new window.Recorder(input);
+ }
+
+ function startRecording() {
+ recorder && recorder.record();
+ }
+
+ function voiceInit() {
+ console.log("run init");
+
+ try {
+ // webkit shim
+ window.AudioContext = window.AudioContext || window.webkitAudioContext;
+ navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
+ window.URL = window.URL || window.webkitURL;
+ audio_context = new AudioContext();
+ console.log('Audio context set up.');
+ console.log('navigator.getUserMedia ' + (navigator.getUserMedia ? 'available.' : 'not present!'));
+ } catch (e) {
+ console.log("err", e);
+ window.layer.msg('No web audio support in this browser!');
+ }
+
+ navigator.getUserMedia({
+ audio: true
+ }, startUserMedia, function (e) {
+ console.log('No live audio input: ' + e);
+ });
+ }
+ }; // 鏉惧紑鍙戦��
+
+
+ document.getElementById('stopSpeak').onmouseup = function () {
+ console.log("鏉惧紑鍙戦��");
+ stopSpeakDOM.setAttribute('class', 'speak on hide');
+ stopSpeakFun();
+
+ function stopSpeakFun() {
+ countTime('destory', 0);
+
+ if (EZUIKit.state.recodeTime < 1) {
+ window.layer.msg("璇磋瘽鏃堕棿杩囩煭");
+ clearInterval(EZUIKit.state.recodeTimer);
+ return false;
+ }
+
+ clearInterval(EZUIKit.state.recodeTimer);
+ wavUpload();
+ }
+
+ function wavUpload() {
+ try {
+ recorder && recorder.stop(); // createAudioDom();
+
+ recorder && recorder.exportWAV(function (wav_file) {
+ console.log("wav_file", wav_file);
+
+ if (wav_file.size < 1000) {
+ window.layer.msg("褰曢煶澶辫触锛岃閲嶈瘯"); // recodeTime = 0;
+
+ EZUIKit.state.recodeTime = 0;
+ return false;
+ } // 娴嬭瘯
+
+
+ countTime('sub', EZUIKit.state.recodeTime + 2); // 寤舵椂
+
+ var formdata = new FormData(); // form 琛ㄥ崟 {key:value}
+
+ formdata.append("voiceFile", wav_file); // form input type="file"
+
+ formdata.append("accessToken", _this.opt.accessToken);
+ formdata.append("deviceSerial", _this.opt.deviceSerial);
+ formdata.append("channelNo", _this.opt.channelNo); // padding = true;
+
+ function apiSuccess(data) {
+ console.log("data.data", data.data);
+
+ if (data.code == 200) {
+ // $("#startBroadcast").show();
+ // $("#stopBroadcast").hide();
+ countTime('sub', EZUIKit.state.recodeTime + 2);
+ } else if (data.code == "10001") {
+ window.layer.msg("鏈壘鍒板綋鍓嶈闊�");
+ } else {
+ window.layer.msg(data.msg || '鍙戦�佸け璐ワ紝璇风◢鍚庡啀璇�');
+ } // padding = false;
+
+ }
+
+ function apiError(err) {
+ console.log("err", err);
+ }
+
+ request(domain + '/api/lapp/voice/sendonce', 'POST', {
+ voiceFile: wav_file,
+ accessToken: _this.opt.accessToken,
+ deviceSerial: _this.opt.deviceSerial,
+ channelNo: _this.opt.channelNo
+ }, '', apiSuccess, apiError);
+ });
+ recorder && recorder.clear();
+ } catch (err) {
+ console.log(err);
+ }
+ }
+ };
+ }
+ }
+ }
+ });
+ }); // iframe 浼犻�掓暟鎹�
+
+ var _this = this;
+
+ window.addEventListener("message", function (event) {
+ event.origin;
+ var id = _this.opt.id;
+
+ if (event.data.type) {
+ switch (event.data.type) {
+ case 'openSound':
+ if (id == event.data.id && params.openSoundCallBack) {
+ params.openSoundCallBack(event.data);
+ }
+
+ break;
+
+ case 'closeSound':
+ if (id == event.data.id && params.closeSoundCallBack) {
+ params.closeSoundCallBack(event.data);
+ }
+
+ break;
+
+ case 'capturePicture':
+ if (id == event.data.id && params.capturePictureCallBack) {
+ params.capturePictureCallBack(event.data);
+ }
+
+ break;
+
+ case 'startSave':
+ if (id == event.data.id && params.startSaveCallBack) {
+ params.startSaveCallBack(event.data);
+ }
+
+ break;
+
+ case 'stopSave':
+ if (id == event.data.id && params.stopSaveCallBack) {
+ params.stopSaveCallBack(event.data);
+ }
+
+ break;
+
+ case 'fullScreen':
+ if (id == event.data.id && params.fullScreenCallBack) {
+ params.fullScreenCallBack(event.data);
+ }
+
+ break;
+
+ case 'getOSDTime':
+ if (id == event.data.id && params.getOSDTimeCallBack) {
+ params.getOSDTimeCallBack(event.data);
+ }
+
+ break;
+
+ case 'handleSuccess':
+ if (id == event.data.id && params.handleSuccess) {
+ params.handleSuccess(event.data);
+ }
+
+ break;
+
+ case 'handleError':
+ if (id == event.data.id && params.handleError) {
+ params.handleError(event.data);
+ }
+
+ break;
+
+ case 'dblclick':
+ if (id == event.data.id && _this.opt.bSupporDoubleClickFull) {
+ if (_this.opt.fullScreenStatus === 0) {
+ _this.fullScreen();
+ } else {
+ _this.cancelFullScreen();
+ }
+ }
+
+ break;
+
+ case 'startTalk':
+ _this.startTalk(); // params.startTalk();
+
+
+ _this.closeSound();
+
+ break;
+
+ case 'stopTalk':
+ // window.stopTalk()
+ _this.stopTalk();
+
+ _this.openSound();
+
+ break;
+
+ case 'clickEventHandle':
+ console.log("event.data", event.data);
+
+ if (params.clickEventHandle) {
+ params.clickEventHandle(event.data);
+ }
+
+ break;
+
+ case 'removeEventHandle':
+ if (params.removeEventHandle) {
+ params.removeEventHandle(event.data);
+ }
+
+ break;
+
+ case 'esc':
+ if (params.clickEventHandle) {
+ params.clickEventHandle(event.data);
+ }
+
+ break;
+
+ case 'iframeFullScreen':
+ if (id == event.data.id) {
+ var requestFullScreen = function requestFullScreen(element) {
+ var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullScreen;
+
+ if (requestMethod) {
+ requestMethod.call(element);
+ } else if (typeof window.ActiveXObject !== "undefined") {
+ var wscript = new ActiveXObject("WScript.Shell");
+
+ if (wscript !== null) {
+ wscript.SendKeys("{F11}");
+ }
+ }
+ };
+
+ requestFullScreen(document.getElementById("EZUIKitPlayer-" + event.data.id));
+ }
+
+ break;
+ }
+ }
+ }); // 鍏ㄥ睆鍙樺寲鍥炶皟
+
+ function fullscreenchange(data) {
+ _this.opt.fullScreenStatus = data ? 1 : 0;
+
+ if (params.fullScreenChangeCallBack) {
+ params.fullScreenChangeCallBack({
+ data: data,
+ id: _this.opt.id
+ });
+ }
+ }
+
+ if (typeof document.fullScreen !== "undefined") {
+ document.addEventListener("fullscreenchange", function () {
+ var e = document.fullscreen || false;
+ fullscreenchange(e);
+ });
+ } else if (typeof document.webkitIsFullScreen !== "undefined") {
+ document.addEventListener("webkitfullscreenchange", function () {
+ var e = document.webkitIsFullScreen || false;
+ fullscreenchange(e);
+ });
+ } else if (typeof document.mozFullScreen !== "undefined") {
+ document.addEventListener("mozfullscreenchange", function () {
+ var e = document.mozFullScreen || false;
+ fullscreenchange(e);
+ });
+ }
+ }; // 鎾斁鐩稿叧API
+
+
+ EZUIKitPlayer.prototype.play = function (data) {
+ var id = 'EZUIKitPlayer-' + this.opt.id;
+ var player = document.getElementById(id).contentWindow;
+
+ if (_typeof(data) === 'object' && data.url) {
+ this.opt.url = data.url;
+ }
+
+ if (_typeof(data) === 'object' && data.accessToken) {
+ this.opt.accessToken = data.accessToken;
+ }
+
+ if (typeof data === 'string') {
+ this.opt.url = data;
+ }
+
+ player.postMessage({
+ action: "play",
+ accessToken: this.opt.accessToken,
+ url: this.opt.url
+ }, domain + "/ezopen/h5/iframe");
+
+ var _this = this;
+
+ this.opt.videoLoading = true;
+ var promise = new Promise(function (resolve, reject) {
+ window.addEventListener("message", function (event) {
+ var playId = _this.opt.id;
+
+ if (playId == event.data.id && event.data.type === 'handleSuccess') {
+ setTimeout(function () {
+ _this.opt.videoLoading = false;
+ }, 1000);
+ resolve(event.data);
+ }
+ });
+ });
+ return promise;
+ };
+
+ EZUIKitPlayer.prototype.stop = function () {
+ var id = 'EZUIKitPlayer-' + this.opt.id;
+ var player = document.getElementById(id).contentWindow;
+ player.postMessage("stop", domain + "/ezopen/h5/iframe");
+
+ var _this = this;
+
+ var promise = new Promise(function (resolve, reject) {
+ window.addEventListener("message", function (event) {
+ var playId = _this.opt.id;
+
+ if (playId == event.data.id && event.data.type === 'stop') {
+ resolve(event.data);
+ }
+ });
+ });
+ return promise;
+ };
+
+ EZUIKitPlayer.prototype.openSound = function () {
+ var id = 'EZUIKitPlayer-' + this.opt.id;
+ var player = document.getElementById(id).contentWindow;
+ player.postMessage("openSound", domain + "/ezopen/h5/iframe");
+
+ var _this = this;
+
+ var promise = new Promise(function (resolve, reject) {
+ window.addEventListener("message", function (event) {
+ var playId = _this.opt.id;
+
+ if (playId == event.data.id && event.data.type === 'openSound') {
+ resolve(event.data);
+ }
+ });
+ });
+ return promise;
+ };
+
+ EZUIKitPlayer.prototype.closeSound = function () {
+ var id = 'EZUIKitPlayer-' + this.opt.id;
+ var player = document.getElementById(id).contentWindow;
+ player.postMessage("closeSound", domain + "/ezopen/h5/iframe");
+
+ var _this = this;
+
+ var promise = new Promise(function (resolve, reject) {
+ window.addEventListener("message", function (event) {
+ var playId = _this.opt.id;
+
+ if (playId == event.data.id && event.data.type === 'closeSound') {
+ resolve(event.data);
+ }
+ });
+ });
+ return promise;
+ };
+
+ EZUIKitPlayer.prototype.startSave = function (fileName) {
+ var id = 'EZUIKitPlayer-' + this.opt.id;
+ var player = document.getElementById(id).contentWindow;
+ player.postMessage({
+ action: "startSave",
+ fileName: fileName || 'default'
+ }, domain + "/ezopen/h5/iframe");
+
+ var _this = this;
+
+ var promise = new Promise(function (resolve, reject) {
+ window.addEventListener("message", function (event) {
+ var playId = _this.opt.id;
+
+ if (playId == event.data.id && event.data.type === 'startSave') {
+ resolve(event.data);
+ }
+ });
+ });
+ return promise;
+ };
+
+ EZUIKitPlayer.prototype.stopSave = function () {
+ var id = 'EZUIKitPlayer-' + this.opt.id;
+ var player = document.getElementById(id).contentWindow;
+ player.postMessage("stopSave", domain + "/ezopen/h5/iframe");
+
+ var _this = this;
+
+ var promise = new Promise(function (resolve, reject) {
+ window.addEventListener("message", function (event) {
+ var playId = _this.opt.id;
+
+ if (playId == event.data.id && event.data.type === 'stopSave') {
+ resolve(event.data);
+ }
+ });
+ });
+ return promise;
+ };
+
+ EZUIKitPlayer.prototype.fullScreen = function () {
+ if (this.opt.fullScreenStatus === 1) {
+ return false;
+ }
+
+ var id = 'EZUIKitPlayer-' + this.opt.id;
+ var player = document.getElementById(id).contentWindow;
+
+ if (navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)) {
+ // console.log('绉诲姩绔叏灞�');
+ var width = document.documentElement.clientWidth;
+ var height = document.documentElement.clientHeight; // wrapper = document.getElementById("test"),
+
+ var wrapper = document.body; //document.body 灞炴�ц繑鍥� <body> 鍏冪礌锛� document.documentElement 灞炴�ц繑鍥� <html> 鍏冪礌銆�
+
+ wrapper = document.getElementById(id);
+ var style = "";
+ style += "width:" + height + "px;"; // 娉ㄦ剰鏃嬭浆鍚庣殑瀹介珮鍒囨崲
+
+ style += "height:" + width + "px;";
+ style += "-webkit-transform: rotate(90deg); transform: rotate(90deg);"; // 娉ㄦ剰鏃嬭浆涓偣鐨勫鐞�
+
+ style += "-webkit-transform-origin: " + width / 2 + "px " + width / 2 + "px;";
+ style += "transform-origin: " + width / 2 + "px " + width / 2 + "px;";
+ style += 'position: fixed;top: 0;left: 0;z-index:10';
+ wrapper.style.cssText = style; // var cancelFullDOM = document.createElement('div');
+ // cancelFullDOM.id = id + "cancel-full-screen"
+ // var cancelFullDOMStyle="width:30px;height:"+height+"px;z-index:1000;position:fixed;top:0px;right:0px;";
+ // cancelFullDOMStyle += "background-image: url(https://resource.ys7cloud.com/group1/M00/00/7E/CtwQE1-01qeAH2wAAAABOliqQ5g167.png);"
+ // cancelFullDOMStyle += "background-size: contain;background-repeat:no-repeat;background-color:rgba(0,0,0,0.2)"
+ // cancelFullDOM.style = cancelFullDOMStyle;
+ // cancelFullDOM.onclick = function(){
+ // _this.cancelFullScreen();
+ // }
+ // document.body.appendChild(cancelFullDOM);
+
+ setTimeout(function () {
+ player.postMessage('autoResize', domain + "/ezopen/h5/iframe");
+ }, 500);
+ } else {
+ // console.log('pc绔叏灞�');
+ var requestFullScreen = function requestFullScreen(element) {
+ var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullScreen;
+
+ if (requestMethod) {
+ requestMethod.call(element);
+ } else if (typeof window.ActiveXObject !== "undefined") {
+ var wscript = new ActiveXObject("WScript.Shell");
+
+ if (wscript !== null) {
+ wscript.SendKeys("{F11}");
+ }
+ }
+ };
+
+ requestFullScreen(document.getElementById(id));
+ }
+
+ if (this.params.fullScreenCallBack) {
+ this.params.fullScreenCallBack(this.opt.id);
+ }
+
+ this.opt.fullScreenStatus = 1;
+ };
+
+ EZUIKitPlayer.prototype.cancelFullScreen = function () {
+ if (this.opt.fullScreenStatus === 0) {
+ return false;
+ }
+
+ var id = 'EZUIKitPlayer-' + this.opt.id;
+ var player = document.getElementById(id).contentWindow;
+
+ if (navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)) {
+ var width = document.getElementById(id).width;
+ var height = document.getElementById(id).height; // wrapper = document.getElementById("test"),
+
+ var wrapper = document.body; //document.body 灞炴�ц繑鍥� <body> 鍏冪礌锛� document.documentElement 灞炴�ц繑鍥� <html> 鍏冪礌銆�
+
+ wrapper = document.getElementById(id);
+ var style = "";
+ style += "width:" + width + "px;";
+ style += "height:" + height + "px;";
+ style += "-webkit-transform: none; transform: none;";
+ style += "-webkit-transform-origin: 0 0;";
+ style += "transform-origin: 0 0;";
+ wrapper.style.cssText = style;
+ setTimeout(function () {
+ player.postMessage("autoResize", domain + "/ezopen/h5/iframe");
+ }, 500);
+ var cancelFullDOMId = id + "cancel-full-screen";
+ var cancelFullDOM = document.getElementById(cancelFullDOMId);
+
+ if (cancelFullDOM) {
+ document.body.removeChild(cancelFullDOM);
+ }
+ } else {
+ if (document.exitFullscreen) {
+ document.exitFullscreen();
+ } else if (document.webkitCancelFullScreen) {
+ document.webkitCancelFullScreen();
+ } else if (document.mozCancelFullScreen) {
+ document.mozCancelFullScreen();
+ }
+ }
+
+ if (this.params.cancelFullScreenCallBack) {
+ this.params.cancelFullScreenCallBack(this.opt.id);
+ }
+
+ this.opt.fullScreenStatus = 0;
+ };
+
+ EZUIKitPlayer.prototype.capturePicture = function (fileName, isUndownload) {
+ var id = 'EZUIKitPlayer-' + this.opt.id;
+ var player = document.getElementById(id).contentWindow;
+ player.postMessage({
+ action: "capturePicture",
+ fileName: fileName || 'default',
+ isUndownload: isUndownload
+ }, domain + "/ezopen/h5/iframe");
+
+ var _this = this;
+
+ var promise = new Promise(function (resolve, reject) {
+ window.addEventListener("message", function (event) {
+ var playId = _this.opt.id;
+
+ if (playId == event.data.id && event.data.type === 'capturePicture') {
+ resolve(event.data);
+ }
+ });
+ });
+ return promise;
+ };
+
+ EZUIKitPlayer.prototype.enableZoom = function () {
+ var id = 'EZUIKitPlayer-' + this.opt.id;
+ var player = document.getElementById(id).contentWindow;
+ player.postMessage("enableZoom", domain + "/ezopen/h5/iframe");
+ };
+
+ EZUIKitPlayer.prototype.closeZoom = function () {
+ var id = 'EZUIKitPlayer-' + this.opt.id;
+ var player = document.getElementById(id).contentWindow;
+ player.postMessage("closeZoom", domain + "/ezopen/h5/iframe");
+ };
+
+ EZUIKitPlayer.prototype.getOSDTime = function () {
+ var id = 'EZUIKitPlayer-' + this.opt.id;
+ var player = document.getElementById(id).contentWindow;
+ player.postMessage("getOSDTime", domain + "/ezopen/h5/iframe");
+
+ var _this = this;
+
+ var promise = new Promise(function (resolve, reject) {
+ window.addEventListener("message", function (event) {
+ var playId = _this.opt.id;
+
+ if (playId == event.data.id && event.data.type === 'getOSDTime') {
+ resolve(event.data);
+ }
+ });
+ });
+ return promise;
+ };
+
+ EZUIKitPlayer.prototype.autoResize = function () {
+ var id = 'EZUIKitPlayer-' + this.opt.id;
+ var player = document.getElementById(id).contentWindow;
+ player.postMessage("autoResize", domain + "/ezopen/h5/iframe");
+ };
+
+ EZUIKitPlayer.prototype.reSize = function (width, height) {
+ var id = 'EZUIKitPlayer-' + this.opt.id;
+ var player = document.getElementById(id).contentWindow;
+ var containerDOM = document.getElementById(this.opt.id);
+ containerDOM.style.width = width + 'px';
+ containerDOM.style.height = height + 'px';
+ document.getElementById(this.opt.id).style.width = width + 'px';
+ document.getElementById(this.opt.id).style.height = height + 'px';
+ var playDOM = document.getElementById(id);
+ playDOM.setAttribute("width", width);
+ playDOM.setAttribute("height", height);
+ playDOM.style.width = width + 'px';
+ playDOM.style.height = height + 'px';
+ setTimeout(function () {
+ player.postMessage({
+ action: 'autoResize'
+ }, domain + "/ezopen/h5/iframe");
+ }, 500);
+ };
+
+ EZUIKitPlayer.prototype.startTalk = function () {
+ console.log("鎵ц寮�濮嬪璁�");
+ console.log(this.opt);
+
+ var _this = this;
+
+ EZUIKit.opt = this.opt;
+
+ if (window.EZUIKit) {
+ window.EZUIKit.opt = this.opt;
+ }
+
+ var apiSuccess = function apiSuccess(data) {
+ if (data.code == 200) {
+ var apiResult = data.data;
+
+ if (apiResult) {
+ // 涓存椂灏唄ttps杞崲涓簑ebsocket
+ var rtcTrunk = apiResult.rtcUrl;
+
+ if (rtcTrunk.indexOf("ws") === -1) {
+ rtcTrunk = rtcTrunk.replace("https", "wss").replace("rtcgw", "rtcgw-ws");
+ }
+
+ _this.opt.rtcUrl = rtcTrunk;
+ _this.opt.ttsUrl = "tts://" + apiResult.ttsUrl;
+ var talk = "talk://" + _this.opt.deviceSerial + ":0:" + _this.opt.channelNo + ":cas.ys7.com:6500";
+ _this.opt.talkLink = _this.opt.ttsUrl + "/" + talk;
+ _this.opt.stream = apiResult.stream;
+ window.startTalk();
+ }
+ }
+ };
+
+ request(_this.opt.apiDomain, 'POST', {
+ accessToken: _this.opt.accessToken,
+ deviceSerial: _this.opt.deviceSerial,
+ channelNo: _this.opt.channelNo
+ }, '', apiSuccess);
+ };
+
+ EZUIKitPlayer.prototype.stopTalk = function () {
+ console.log("鎵ц缁撴潫瀵硅");
+ window.stopTalk();
+ };
+
+ EZUIKitPlayer.prototype.edit = function () {
+ var id = 'EZUIKitPlayer-' + this.opt.id;
+ var player = document.getElementById(id).contentWindow;
+ player.postMessage("edit", domain + "/ezopen/h5/iframe");
+ };
+
+ EZUIKitPlayer.prototype.btnReRender = function (data) {
+ var id = 'EZUIKitPlayer-' + this.opt.id;
+ var player = document.getElementById(id).contentWindow;
+ player.postMessage({
+ action: "btnReRender",
+ data: data
+ }, domain + "/ezopen/h5/iframe");
+ };
+
+ EZUIKitPlayer.prototype.changePlayUrl = function (data) {
+ if (data.deviceSerial) {
+ this.opt.deviceSerial = data.deviceSerial;
+ }
+
+ if (data.channelNo) {
+ this.opt.channelNo = data.channelNo;
+ }
+
+ if (data.accessToken) {
+ this.opt.accessToken = data.accessToken;
+ }
+
+ var id = 'EZUIKitPlayer-' + this.opt.id;
+ var player = document.getElementById(id).contentWindow;
+ player.postMessage({
+ action: "changePlayUrl",
+ data: data
+ }, domain + "/ezopen/h5/iframe");
+ };
+
+ EZUIKitPlayer.prototype.fetchThemeData = function () {
+ var id = 'EZUIKitPlayer-' + this.opt.id;
+ var player = document.getElementById(id).contentWindow;
+ player.postMessage({
+ action: "fetchThemeData"
+ }, domain + "/ezopen/h5/iframe");
+ };
+
+ EZUIKitPlayer.prototype.setThemeData = function (accessToken, header, footer) {
+ var id = 'EZUIKitPlayer-' + this.opt.id;
+ var player = document.getElementById(id).contentWindow;
+ player.postMessage({
+ action: "setThemeData",
+ data: {
+ accessToken: accessToken,
+ header: header,
+ footer: footer
+ }
+ }, domain + "/ezopen/h5/iframe");
+ };
+ /**
+ * 瑙嗛鎾斁鍣�-缁撴潫
+ */
+
+
+ EZUIKit.EZUIKitPlayer = EZUIKitPlayer;
+ window.EZUIKitV3 = EZUIKit;
+ var EZUIKitV3 = EZUIKit;
+ return EZUIKitV3;
+});
+
+var EZUIKitV3$1 = EZUIKitV3;
+
+/**
+ * Created by wangweijie5 on 2016/12/16.
+ */
+
+var _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;
+ };
+}();
+
+function _classCallCheck(instance, Constructor) {
+ if (!(instance instanceof Constructor)) {
+ throw new TypeError("Cannot call a class as a function");
+ }
+}
+
+var __instance = function () {
+ var instance = void 0;
+ return function (newInstance) {
+ if (newInstance) instance = newInstance;
+ return instance;
+ };
+}();
+
+(function () {
+ function AudioRenderer() {
+ _classCallCheck(this, AudioRenderer);
+
+ if (__instance()) return __instance(); // 纭繚鍙湁鍗曚緥
+
+ if (AudioRenderer.unique !== undefined) {
+ return AudioRenderer.unique;
+ }
+
+ AudioRenderer.unique = this;
+ this.oAudioContext = null;
+ this.currentVolume = 80; // 鍒濆闊抽噺
+
+ this.bSetVolume = false;
+ this.gainNode = null;
+ this.iWndNum = -1; // 绐楀彛鍙�
+
+ this.mVolumes = new Map(); // 鐢ㄤ簬瀛樺偍鎵�鏈夐煶閲�
+ // Init AudioContext
+
+ var AudioContext = window.AudioContext || window.webkitAudioContext;
+ this.oAudioContext = new AudioContext();
+
+ this.writeString = function (view, offset, string) {
+ for (var i = 0; i < string.length; i++) {
+ view.setUint8(offset + i, string.charCodeAt(i));
+ }
+ };
+
+ this.setBufferToDataview = function (output, offset, input) {
+ for (var i = 0; i < input.length; i++, offset++) {
+ output.setUint8(offset, input[i]);
+ }
+ };
+
+ __instance(this);
+ }
+ /**
+ * @synopsis 闊抽鎾斁
+ *
+ * @param dataBuf [IN] 闊抽缂撳瓨
+ * @param dataLen [IN] 缂撳瓨闀垮害
+ * @param audioInfo [IN] 闊抽鍙傛暟
+ *
+ * @returns 鐘舵�佺爜
+ */
+
+
+ _createClass(AudioRenderer, [{
+ key: 'Play',
+ value: function Play(dataBuf, dataLen, audioInfo) {
+ var bufferData = new ArrayBuffer(44 + dataLen);
+ var viewTalk = new DataView(bufferData);
+ var sampleRates = audioInfo.samplesPerSec;
+ var channels = audioInfo.channels;
+ var bitsPerSample = audioInfo.bitsPerSample; //console.log("audiorender sampleRates"+sampleRates+"channels:"+channels+"bitsPerSample:"+bitsPerSample);
+
+ /* RIFF identifier */
+
+ this.writeString(viewTalk, 0, 'RIFF');
+ /* file length */
+
+ viewTalk.setUint32(4, 32 + dataLen * 2, true);
+ /* RIFF type */
+
+ this.writeString(viewTalk, 8, 'WAVE');
+ /* format chunk identifier */
+
+ this.writeString(viewTalk, 12, 'fmt ');
+ /* format chunk length */
+
+ viewTalk.setUint32(16, 16, true);
+ /* sample format (raw) */
+
+ viewTalk.setUint16(20, 1, true);
+ /* channel count */
+
+ viewTalk.setUint16(22, channels, true);
+ /* sample rate */
+
+ viewTalk.setUint32(24, sampleRates, true);
+ /* byte rate (sample rate * block align) */
+
+ viewTalk.setUint32(28, sampleRates * 2, true);
+ /* block align (channel count * bytes per sample)/8 */
+
+ viewTalk.setUint16(32, channels * bitsPerSample / 8, true);
+ /* bits per sample */
+
+ viewTalk.setUint16(34, bitsPerSample, true);
+ /* data chunk identifier */
+
+ this.writeString(viewTalk, 36, 'data');
+ /* data chunk length */
+
+ viewTalk.setUint32(40, dataLen, true);
+ this.setBufferToDataview(viewTalk, 44, dataBuf);
+ var self = this;
+ this.oAudioContext.decodeAudioData(viewTalk.buffer, function (buffer) {
+ var bufferSource = self.oAudioContext.createBufferSource();
+
+ if (bufferSource == null) {
+ return -1;
+ }
+
+ bufferSource.buffer = buffer;
+ bufferSource.start(0);
+
+ if (self.gainNode == null || self.bSetVolume) {
+ self.gainNode = self.oAudioContext.createGain(); // self.gainNode.gain.value = self.currentVolume;
+ // // self.currentVolume = self.gainNode.gain.value;
+ // self.gainNode.connect(self.oAudioContext.destination);
+
+ self.bSetVolume = false;
+ }
+
+ self.gainNode.gain.value = self.currentVolume / 100; // self.currentVolume = self.gainNode.gain.value;
+
+ self.gainNode.connect(self.oAudioContext.destination);
+ bufferSource.connect(self.gainNode);
+ }, function (e) {
+ console.log("decode error");
+ return -1;
+ });
+ return 0;
+ }
+ /**
+ * @synopsis 鍋滄鎾斁
+ *
+ * @returns 杩斿洖闊抽噺
+ */
+
+ }, {
+ key: 'Stop',
+ value: function Stop() {
+ if (this.gainNode != null) {
+ this.gainNode.disconnect();
+ this.gainNode = null;
+ } // this.oAudioContext.close();
+ // AudioRenderer.unique = undefined;
+ // __instance() = null;
+
+
+ return true;
+ }
+ /**
+ * @synopsis 璁剧疆闊抽噺
+ *
+ * @param iVolume [IN] 闊抽噺
+ *
+ * @returns 鐘舵�佺爜
+ */
+
+ }, {
+ key: 'SetVolume',
+ value: function SetVolume(iVolume) {
+ this.bSetVolume = true;
+ this.currentVolume = iVolume; // 鍌ㄥ瓨褰撳墠绐楀彛璁剧疆闊抽噺鍊�
+
+ this.mVolumes.set(this.iWndNum, this.currentVolume);
+ return true;
+ }
+ /**
+ * @synopsis 璁剧疆绐楀彛鍙�
+ *
+ * @param iWndNum [IN] 绐楀彛鍙�
+ *
+ * @returns 鐘舵�佺爜
+ */
+
+ }, {
+ key: 'SetWndNum',
+ value: function SetWndNum(iWndNum) {
+ this.iWndNum = iWndNum; // 鑾峰彇褰撳墠绐楀彛璁剧疆闊抽噺鍊�
+
+ var iVolume = this.mVolumes.get(iWndNum);
+
+ if (iVolume == undefined) {
+ iVolume = 80; // 榛樿闊抽噺
+ }
+
+ this.currentVolume = iVolume;
+ return true;
+ }
+ /**
+ * @synopsis 鑾峰彇闊抽噺
+ *
+ * @returns 杩斿洖闊抽噺
+ */
+
+ }, {
+ key: 'GetVolume',
+ value: function GetVolume() {
+ // 鑾峰彇褰撳墠绐楀彛璁剧疆闊抽噺鍊�
+ var iVolume = this.mVolumes.get(this.iWndNum);
+
+ if (iVolume == undefined) {
+ iVolume = 80; // 榛樿闊抽噺
+ }
+
+ return iVolume;
+ }
+ }]);
+
+ window.AudioRenderer = AudioRenderer;
+ return AudioRenderer;
+})();
+
+//attribute淇グ绗︾敤浜庡0鏄庣敱娴忚鍣紙javascript锛変紶杈撶粰椤剁偣鐫�鑹插櫒鐨勫彉閲忓�硷紱
+// vertexPos鍗虫垜浠畾涔夌殑椤剁偣鍧愭爣锛�
+// gl_Position鏄竴涓唴寤虹殑浼犲嚭鍙橀噺銆�
+
+var vertexYUVShader = ['attribute vec4 vertexPos;', 'attribute vec2 texturePos;', 'varying vec2 textureCoord;', 'void main()', '{', 'gl_Position = vertexPos;', 'textureCoord = texturePos;', '}'].join('\n'); //鍍忕礌鐫�鑹插櫒(yuv->rgb)
+
+var fragmentYUVShader = ['precision highp float;', 'varying highp vec2 textureCoord;', 'uniform sampler2D ySampler;', 'uniform sampler2D uSampler;', 'uniform sampler2D vSampler;', 'const mat4 YUV2RGB = mat4', '(', '1.1643828125, 0, 1.59602734375, -.87078515625,', '1.1643828125, -.39176171875, -.81296875, .52959375,', '1.1643828125, 2.017234375, 0, -1.081390625,', '0, 0, 0, 1', ');', 'void main(void) {', 'highp float y = texture2D(ySampler, textureCoord).r;', 'highp float u = texture2D(uSampler, textureCoord).r;', 'highp float v = texture2D(vSampler, textureCoord).r;', 'gl_FragColor = vec4(y, u, v, 1) * YUV2RGB;', '}'].join('\n');
+
+(function (root, factory) {
+ // root.SuperRender = factory();
+ window.SuperRender = factory();
+})(undefined, function () {
+ function RenderManager(canvas) {
+ this.canvasElement = document.getElementById(canvas);
+ this.initContextGL();
+
+ if (this.contextGL) {
+ this.YUVProgram = this.initProgram(vertexYUVShader, fragmentYUVShader);
+ this.initBuffers();
+ this.initTextures();
+ }
+ }
+ /**
+ * 鍒濆鍖朩ebGL涓婁笅鏂�
+ */
+
+ RenderManager.prototype.initContextGL = function () {
+ var canvas = this.canvasElement;
+ var gl = null;
+
+ try {
+ gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
+ } catch (e) {
+ gl = null;
+ }
+
+ if (!gl || typeof gl.getParameter !== "function") {
+ gl = null;
+ }
+
+ this.contextGL = gl;
+ console.log("WebGL1.0");
+ };
+ /**
+ * 鍒濆鍖栫潃鑹插櫒绋嬪簭
+ * @param vertexShaderScript 椤剁偣鐫�鑹插櫒鑴氭湰
+ * @param fragmentShaderScript 鐗囨鐫�鑹插櫒鑴氭湰
+ */
+
+
+ RenderManager.prototype.initProgram = function (vertexShaderScript, fragmentShaderScript) {
+ var gl = this.contextGL;
+ var vertexShader = gl.createShader(gl.VERTEX_SHADER); //鍒涘缓瀹氱偣鐫�鑹插櫒
+
+ gl.shaderSource(vertexShader, vertexShaderScript);
+ gl.compileShader(vertexShader);
+
+ if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
+ console.log('Vertex shader failed to compile: ' + gl.getShaderInfoLog(vertexShader));
+ }
+
+ var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
+ gl.shaderSource(fragmentShader, fragmentShaderScript);
+ gl.compileShader(fragmentShader);
+
+ if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
+ console.log('Fragment shader failed to compile: ' + gl.getShaderInfoLog(fragmentShader));
+ }
+
+ var program = gl.createProgram();
+ gl.attachShader(program, vertexShader);
+ gl.attachShader(program, fragmentShader);
+ gl.linkProgram(program);
+
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
+ console.log('Program failed to compile: ' + gl.getProgramInfoLog(program));
+ }
+
+ gl.deleteShader(vertexShader);
+ gl.deleteShader(fragmentShader);
+ return program;
+ };
+ /**
+ * 鍒濆鍖栨暟鎹紦瀛�
+ */
+
+
+ RenderManager.prototype.initBuffers = function () {
+ var gl = this.contextGL;
+ var vertexPosBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 1, -1, 1, 1, -1, -1, -1]), gl.STATIC_DRAW);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ var texturePosBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, texturePosBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 0, 0, 0, 1, 1, 0, 1]), gl.DYNAMIC_DRAW);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ this.vertexPosBuffer = vertexPosBuffer;
+ this.texturePosBuffer = texturePosBuffer;
+ };
+ /**
+ * 鍒涘缓绾圭悊
+ */
+
+
+ RenderManager.prototype.initTexture = function () {
+ var gl = this.contextGL;
+ var textureRef = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, textureRef);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ return textureRef;
+ };
+ /**
+ * 鍒濆鍖朰UV绾圭悊
+ */
+
+
+ RenderManager.prototype.initTextures = function () {
+ var gl = this.contextGL;
+ var program = this.YUVProgram;
+ gl.useProgram(program);
+ var yTextureRef = this.initTexture();
+ var ySamplerRef = gl.getUniformLocation(program, 'ySampler');
+ gl.uniform1i(ySamplerRef, 0);
+ this.yTextureRef = yTextureRef;
+ var uTextureRef = this.initTexture();
+ var uSamplerRef = gl.getUniformLocation(program, 'uSampler');
+ gl.uniform1i(uSamplerRef, 1);
+ this.uTextureRef = uTextureRef;
+ var vTextureRef = this.initTexture();
+ var vSamplerRef = gl.getUniformLocation(program, 'vSampler');
+ gl.uniform1i(vSamplerRef, 2);
+ this.vTextureRef = vTextureRef;
+ gl.useProgram(null);
+ };
+ /**
+ * 鏄剧ず甯ф暟鎹�
+ * @param nWidth 瀹藉害
+ * @param nHeight 楂樺害
+ * @param nHeight 甯ф暟鎹�
+ */
+
+
+ RenderManager.prototype.SR_DisplayFrameData = function (nWidth, nHeight, pData, dWidth, dHeight) {
+ if (nWidth <= 0 || nHeight <= 0) {
+ return;
+ }
+
+ var gl = this.contextGL;
+
+ if (null == pData) {
+ gl.clearColor(0.0, 0.0, 0.0, 0.0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ return;
+ }
+
+ var canvas = this.canvasElement;
+ this.nWindowWidth = canvas.width;
+ this.nWindowHeight = canvas.height;
+ var nWindowWidth = this.nWindowWidth;
+ var nWindowHeight = this.nWindowHeight;
+ gl.clearColor(0.8, 0.8, 1.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.viewport(0, 0, nWindowWidth, nWindowHeight);
+ this.updateFrameData(nWidth, nHeight, pData, dWidth, dHeight);
+ var program = this.YUVProgram;
+ gl.useProgram(program);
+ var vertexPosBuffer = this.vertexPosBuffer;
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer);
+ var vertexPosRef = gl.getAttribLocation(program, 'vertexPos');
+ gl.enableVertexAttribArray(vertexPosRef);
+ gl.vertexAttribPointer(vertexPosRef, 2, gl.FLOAT, false, 0, 0);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ var texturePosBuffer = this.texturePosBuffer;
+ gl.bindBuffer(gl.ARRAY_BUFFER, texturePosBuffer);
+ var texturePosRef = gl.getAttribLocation(program, 'texturePos');
+ gl.enableVertexAttribArray(texturePosRef);
+ gl.vertexAttribPointer(texturePosRef, 2, gl.FLOAT, false, 0, 0);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+ gl.disableVertexAttribArray(vertexPosRef);
+ gl.disableVertexAttribArray(texturePosRef);
+ gl.useProgram(null);
+ };
+ /**
+ * 涓婁紶YUV鏁版嵁鍒扮汗鐞�
+ * @param nWidth 瀹藉害
+ * @param nHeight 楂樺害
+ * @param nHeight 甯ф暟鎹�
+ */
+
+
+ RenderManager.prototype.updateFrameData = function (width, height, data, dWidth, dHeight) {
+ var gl = this.contextGL;
+ var yTextureRef = this.yTextureRef;
+ var uTextureRef = this.uTextureRef;
+ var vTextureRef = this.vTextureRef;
+ var i420Data = data; // debugger;
+
+ if (width == dWidth && height == dHeight) {
+ var yDataLength = width * height;
+ var yData = i420Data.subarray(0, yDataLength);
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, yTextureRef);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, width, height, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, yData);
+ var cbDataLength = width / 2 * height / 2;
+ var cbData = i420Data.subarray(width * height, width * height + cbDataLength);
+ gl.activeTexture(gl.TEXTURE2);
+ gl.bindTexture(gl.TEXTURE_2D, vTextureRef);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, width / 2, height / 2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, cbData);
+ var crDataLength = cbDataLength;
+ var crData = i420Data.subarray(width * height + width * height / 4, width * height + width * height / 4 + crDataLength);
+ gl.activeTexture(gl.TEXTURE1);
+ gl.bindTexture(gl.TEXTURE_2D, uTextureRef);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, width / 2, height / 2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, crData);
+ } else {
+ // //瑁佸壀瀹�
+ var yDataLength = dWidth * dHeight;
+ var yData = new Uint8Array(yDataLength);
+
+ for (var i = 0; i < dHeight; i++) {
+ //var ySonData=new Uint8Array(dWidth) ;
+ var ySonData = i420Data.subarray(i * width, i * width + dWidth);
+
+ for (var j = 0; j < dWidth; j++) {
+ yData[i * dWidth + j] = ySonData[j];
+ }
+ }
+
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, yTextureRef);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, dWidth, dHeight, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, yData);
+ yData = null;
+ ySonData = null;
+ var cbDataLength = dWidth / 2 * dHeight / 2;
+ var cbData = new Uint8Array(cbDataLength); //var cbSonData=new Uint8Array(dWidth/2) ;
+
+ for (var i = 0; i < dHeight / 2; i++) {
+ var cbSonData = i420Data.subarray(width * height + i * width / 2, width * height + i * width / 2 + dWidth / 2);
+
+ for (var j = 0; j < dWidth / 2; j++) {
+ cbData[i * dWidth / 2 + j] = cbSonData[j];
+ }
+ }
+
+ gl.activeTexture(gl.TEXTURE2);
+ gl.bindTexture(gl.TEXTURE_2D, vTextureRef);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, dWidth / 2, dHeight / 2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, cbData);
+ cbData = null;
+ cbSonData = null;
+ var crDataLength = cbDataLength;
+ var crData = new Uint8Array(crDataLength);
+
+ for (var i = 0; i < dHeight / 2; i++) {
+ var crSonData = i420Data.subarray(width * height * 5 / 4 + i * width / 2, width * height * 5 / 4 + i * width / 2 + dWidth / 2);
+
+ for (var j = 0; j < dWidth / 2; j++) {
+ crData[i * dWidth / 2 + j] = crSonData[j];
+ }
+ }
+
+ gl.activeTexture(gl.TEXTURE1);
+ gl.bindTexture(gl.TEXTURE_2D, uTextureRef);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, dWidth / 2, dHeight / 2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, crData);
+ crData = null;
+ crSonData = null;
+ }
+ };
+ /**
+ * 璁剧疆鏄剧ず鍖哄煙
+ * @param stDisplayRect 鏄剧ず鍖哄煙
+ */
+
+
+ RenderManager.prototype.SR_SetDisplayRect = function (stDisplayRect) {
+ var gl = this.contextGL;
+ var nWindowWidth = this.nWindowWidth;
+ var nWindowHeight = this.nWindowHeight;
+ var texturePosValues = null;
+
+ if (stDisplayRect && nWindowWidth > 0 && nWindowHeight > 0) {
+ var fLeft = stDisplayRect.left / nWindowWidth;
+ var fTop = stDisplayRect.top / nWindowHeight;
+ var fRight = stDisplayRect.right / nWindowWidth;
+ var fBottom = stDisplayRect.bottom / nWindowHeight;
+ texturePosValues = new Float32Array([fRight, fTop, fLeft, fTop, fRight, fBottom, fLeft, fBottom]);
+ } else {
+ texturePosValues = new Float32Array([1, 0, 0, 0, 1, 1, 0, 1]);
+ }
+
+ var texturePosBuffer = this.texturePosBuffer;
+ gl.bindBuffer(gl.ARRAY_BUFFER, texturePosBuffer);
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, texturePosValues);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ };
+ /**
+ * 閲婃斁鏄剧ず璧勬簮
+ */
+
+
+ RenderManager.prototype.SR_Destroy = function () {
+ var gl = this.contextGL;
+ var YUVProgram = this.YUVProgram;
+ gl.deleteProgram(YUVProgram);
+ var vertexPosBuffer = this.vertexPosBuffer;
+ var texturePosBuffer = this.texturePosBuffer;
+ gl.deleteBuffer(vertexPosBuffer);
+ gl.deleteBuffer(texturePosBuffer);
+ var yTextureRef = this.yTextureRef;
+ var uTextureRef = this.uTextureRef;
+ var vTextureRef = this.vTextureRef;
+ gl.deleteTexture(yTextureRef);
+ gl.deleteTexture(uTextureRef);
+ gl.deleteTexture(vTextureRef); //gl.getExtension('WEBGL_lose_context').loseContext();
+ };
+
+ return RenderManager;
+});
+
+var matchTemplate = function matchTemplate(templateName, params) {
+ var IFRAMETEMPLATE = ['theme', 'standard'];
+ var LOCALTEMPLATE = ['pcLive', 'pcRec', 'mobileLive', 'mobileRec', 'noData', 'security', 'voice', 'simple'];
+
+ if (typeof templateName === 'undefined') {
+ if (params.themeData) {
+ return {
+ templateType: 'themeData',
+ templateId: 'themeData'
+ };
+ }
+
+ return {
+ templateType: 'local',
+ templateId: ''
+ };
+ }
+
+ if (typeof templateName === 'string') {
+ if (templateName.length === 32) {
+ return {
+ templateType: 'remote',
+ templateId: templateName
+ };
+ } else if (IFRAMETEMPLATE.indexOf(templateName) !== -1) {
+ // 绮剧畝鐗堜笖涓嶄娇鐢ㄥご閮紝搴曢儴锛屼粎鎾斁瑙嗛锛屽缓璁娇鐢ㄦ寜闇�鍔犺浇閬垮厤iframe鍐呭瓨棰濆娑堣��
+ if (templateName === 'simple' && typeof params.header === 'undefined' && typeof params.footer === 'undefined') {
+ return {
+ templateType: 'local',
+ templateId: ''
+ };
+ }
+
+ return {
+ templateType: 'iframe',
+ templateId: templateName
+ };
+ } else if (LOCALTEMPLATE.indexOf(templateName) !== -1) {
+ return {
+ templateType: 'local',
+ templateId: templateName
+ };
+ }
+ }
+};
+
+var isVersion2Available = function isVersion2Available() {
+ var ua = window.navigator.userAgent.toLowerCase(); //鑾峰彇鐢ㄦ埛绔俊鎭�
+
+ var info = {
+ sa: /version.*safari/.test(ua),
+ //鍖归厤Safari娴忚鍣�
+ ch: /chrome/.test(ua),
+ //鍖归厤Chrome娴忚鍣�
+ ff: /gecko/.test(ua) && !/webkit/.test(ua) //鍖归厤Firefox娴忚鍣�
+
+ };
+ var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
+
+ if (isMobile) {
+ return false;
+ } else if (info.ch) {
+ var getChromeVersion = function getChromeVersion() {
+ var arr = window.navigator.userAgent.split(' ');
+ var chromeVersion = '';
+
+ for (var i = 0; i < arr.length; i++) {
+ if (/chrome/i.test(arr[i])) chromeVersion = arr[i];
+ }
+
+ if (chromeVersion) {
+ return Number(chromeVersion.split('/')[1].split('.')[0]);
+ } else {
+ return false;
+ }
+ };
+
+ return getChromeVersion() > 91 && !!window.SharedArrayBuffer;
+ }
+
+ return false;
+};
+
+var EZUIKitPlayer = /*#__PURE__*/function () {
+ function EZUIKitPlayer(params) {
+ var _this = this;
+
+ _classCallCheck$1(this, EZUIKitPlayer);
+
+ var _params$autoplay = params.autoplay,
+ autoplay = _params$autoplay === void 0 ? true : _params$autoplay; // 濡傛灉璁剧疆浜嗘ā鏉匡紙闄ょ簿绠�鐗堬級锛屾澶勪笉鑷姩鎾斁锛屾牴鎹ā鏉垮垽鏂槸鍚︽墽琛岃嚜鍔ㄦ挱鏀�:
+
+ if (params.template && params.template !== "simple" || params.themeData) {
+ autoplay = false;
+ }
+
+ this.params = params;
+ this.autoplay = autoplay;
+ window.EZUIKit[params.id] = {
+ state: {
+ EZUIKitPlayer: {
+ init: window.EZUIKit[params.id] && window.EZUIKit[params.id].state && window.EZUIKit[params.id].state.EZUIKitPlayer.init || false,
+ themeInit: window.EZUIKit[params.id] && window.EZUIKit[params.id].state && window.EZUIKit[params.id].state.EZUIKitPlayer.themeInit || false,
+ talkInit: window.EZUIKit[params.id] && window.EZUIKit[params.id].state && window.EZUIKit[params.id].state.EZUIKitPlayer.talkInit || false
+ }
+ }
+ };
+
+ if (matchTemplate(this.params.template, params).templateType !== 'iframe') {
+ this.Monitor = new Monitor({
+ env: !(typeof params.disableMonitor !== 'undefined' && params.disableMonitor) ? 'online' : 'test12'
+ }, this);
+ this.id = params.id;
+ this.width = params.width;
+ this.height = params.height;
+ this.url = params.url;
+ this.accessToken = params.accessToken;
+ this.themeId = matchTemplate(params.template, params).templateId;
+ this.id = params.id;
+ this.audio = true;
+ this.poster = params.poster;
+ this.speed = 1;
+ this.disabledTimeLine = false;
+ this.disabledPTZ = false;
+ this.enableSharedArrayBufferGuide = false;
+ this.capacity = {};
+ this.env = {
+ domain: "https://open.ys7.com"
+ };
+ var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
+ this.isMobile = isMobile; // 鍏煎澶氭鍒濆鍖�
+
+ if (document.getElementById("".concat(this.id, "-wrap"))) {
+ document.getElementById("".concat(this.id, "-wrap")).innerHTML = "";
+ document.getElementById("".concat(this.id, "-wrap")).id = this.id;
+ }
+
+ this.staticPath = isVersion2Available() ? "https://open.ys7.com/console/ezuikit_static/v6/v2" : "https://open.ys7.com/console/ezuikit_static/v6/v1";
+
+ if (typeof params.staticPath === 'string') {
+ if (params.staticPath.startsWith("http")) {
+ this.staticPath = params.staticPath;
+ } else {
+ this.staticPath = window.location.protocol + '//' + window.location.host + params.staticPath;
+ }
+
+ if (isVersion2Available()) {
+ this.staticPath += '/v2';
+ } else {
+ this.staticPath += '/v1';
+ }
+ }
+
+ if (typeof params.audio !== 'undefined') {
+ this.audio = params.audio;
+ }
+
+ if (typeof params.env !== 'undefined') {
+ this.env = Object.assign(this.env, params.env);
+ }
+
+ if (typeof params.isMobile !== 'undefined') {
+ this.isMobile = params.isMobile;
+ }
+
+ if (typeof params.disabledTimeLine !== 'undefined') {
+ this.disabledTimeLine = params.disabledTimeLine;
+ }
+
+ if (typeof params.disabledPTZ !== 'undefined') {
+ this.disabledPTZ = params.disabledPTZ;
+ }
+
+ if (typeof params.enableSharedArrayBufferGuide !== 'undefined') {
+ this.enableSharedArrayBufferGuide = params.enableSharedArrayBufferGuide;
+ }
+
+ var pluginUrl = "".concat(this.staticPath, "/js/jsPluginV1-1.0.0.min.js");
+
+ if (isVersion2Available()) {
+ console.log("鍚敤澶氱嚎绋嬭В鏋愯棰�");
+ pluginUrl = "".concat(this.staticPath, "/js/jsPluginV2-2.0.1.min.js");
+ } else {
+ // 鏄惁寮曞鐢ㄦ埛寮�鍚胺姝屽疄楠屽 Google Labs 鐗规��
+ //enableSharedArrayBufferGuide
+ var getChromeVersion = function getChromeVersion() {
+ var arr = navigator.userAgent.split(' ');
+ var chromeVersion = '';
+
+ for (var i = 0; i < arr.length; i++) {
+ if (/chrome/i.test(arr[i])) {
+ chromeVersion = arr[i];
+ }
+ }
+
+ if (chromeVersion) {
+ return Number(chromeVersion.split('/')[1].split('.')[0]);
+ }
+
+ return false;
+ }; // pc绔� 璋锋瓕娴忚鍣� 鐗堟湰92 ~ 105
+
+
+ if (!isMobile && 91 < getChromeVersion < 106 && this.enableSharedArrayBufferGuide) {
+ console.log("鎻愮ず鐢ㄦ埛寮�鍚胺姝屽疄楠屽鐗规��");
+ var wapDomId = "".concat(this.id, "-wrap");
+ var guideDom = document.createElement("div");
+ var guideSpan = document.createElement("span");
+ guideSpan.innerHTML = "鎮ㄥ綋鍓嶆祻瑙堝櫒鍙互寮�鍚胺姝屽疄楠屽澶氱嚎绋嬬壒鎬э紝鑾峰彇鏇村ソ鎾斁浣撻獙锛岄伩鍏嶆祻瑙堝櫒鍗¢】鍙婂穿婧�,璇﹁";
+ guideDom.appendChild(guideSpan);
+ var guideLink = document.createElement("a");
+ guideLink.href = "https://open.ys7.com/help/384";
+ guideLink.setAttribute("target", "_blank");
+ guideDom.appendChild(guideLink);
+ guideLink.innerHTML = "寮�鍚鏄�"; //guideDom.innerHTML = "鎮ㄧ殑娴忚鍣ㄥ綋鍓嶄娇鐢ㄥ崟杩涚▼鎾斁瑙嗛锛屽彲鑳藉洜鍐呭瓨鍗犵敤杩囬珮瀵艰嚧娴忚鍣ㄥ崱椤�,鎮ㄥ彲鍙傝�兟疯胺姝屾祻瑙堝櫒寮�鍚绾跨▼锛堥摼鎺ワ級路寮�鍚胺姝屽疄楠屽澶氱嚎绋嬬壒鎬э紝鑾峰彇鏇村ソ鎾斁浣撻獙";
+
+ guideDom.id = "".concat(this.id, "-guide");
+ guideDom.style = "font-size:12px;color:red;";
+ setTimeout(function () {
+ if (document.getElementById(wapDomId)) {
+ document.getElementById(wapDomId).insertBefore(guideDom, document.getElementById(_this.id));
+ }
+ }, 5000);
+ }
+ }
+
+ this.pluginStatus = new Status(this, this.id);
+ addJs(pluginUrl, function () {
+ if (_this.autoplay) {
+ _this.initTime = new Date().getTime();
+
+ _this.Monitor.dclog({
+ url: _this.url,
+ action: 0,
+ text: 'startInit'
+ });
+
+ _this.Monitor.localInfoLog({
+ Serial: matchEzopenUrl(_this.url).deviceSerial,
+ Channel: matchEzopenUrl(_this.url).channelNo,
+ Ver: isVersion2Available() ? "v7.0.0" : "v6.0.0",
+ ExterVer: isVersion2Available() ? "v7.0.0" : "v6.0.0"
+ });
+
+ var initEZUIKitPlayerPromise = _this.initEZUIKitPlayer(params);
+
+ var getRealUrlPromise = _this._getRealUrlPromise(params.accessToken, params.url);
+
+ Promise.all([initEZUIKitPlayerPromise, getRealUrlPromise]).then(function (values) {
+ if (values[1]) {
+ _this.playStartTime = new Date().getTime();
+
+ _this._pluginPlay(values[1], function () {
+ console.log("鑷姩鎾斁鎴愬姛");
+
+ _this.Monitor.dclog({
+ url: _this.url,
+ action: 202,
+ d: new Date().getTime() - _this.initTime,
+ text: 'autoPlaySuccess'
+ });
+ }, function () {
+ console.log("鑷姩鎾斁澶辫触");
+
+ _this.Monitor.dclog({
+ url: _this.url,
+ action: 402,
+ d: new Date().getTime() - _this.initTime,
+ text: 'autoPlayError'
+ });
+ });
+ } else {
+ console.log("promise of one", values);
+ }
+
+ window.EZUIKit[params.id].state.EZUIKitPlayer.init = true;
+
+ if (document.getElementById("".concat(params.id, "canvas_draw0"))) {
+ document.getElementById("".concat(params.id, "canvas_draw0")).style.border = "none";
+ }
+ })["catch"](function (err) {
+ console.log("err", err);
+
+ _this.pluginStatus.loadingSetText({
+ text: err && err.msg || "鑾峰彇鎾斁鍦板潃澶辫触",
+ color: 'red'
+ });
+ });
+ } else {
+ _this.initTime = new Date().getTime();
+
+ _this.Monitor.dclog({
+ url: _this.url,
+ action: 0,
+ text: 'startInit'
+ });
+
+ _this.Monitor.localInfoLog({
+ Serial: matchEzopenUrl(_this.url).deviceSerial,
+ Channel: matchEzopenUrl(_this.url).channelNo,
+ Ver: isVersion2Available() ? "v7.0.0" : "v6.0.0"
+ });
+
+ var initEZUIKitPlayerPromise = _this.initEZUIKitPlayer(params);
+
+ initEZUIKitPlayerPromise.then(function (data) {
+ console.log("鍒濆鍖栨垚鍔�", data);
+ window.EZUIKit[params.id].state.EZUIKitPlayer.init = true;
+
+ if (document.getElementById("".concat(params.id, "canvas_draw0"))) {
+ document.getElementById("".concat(params.id, "canvas_draw0")).style.border = "none";
+ }
+
+ _this.Monitor.dclog({
+ url: _this.url,
+ action: 201,
+ d: new Date().getTime() - _this.initTime,
+ text: 'initSuccess'
+ });
+ });
+ }
+ }, function () {
+ if (isVersion2Available()) {
+ return !!window.JSPluginV2;
+ }
+
+ return !!window.JSPluginV1;
+ });
+
+ if (params.plugin && params.plugin.indexOf("talk") !== -1) {
+ this.Talk = new Talk(this);
+ window.EZUIKit[params.id].state.EZUIKitPlayer.talkInit = true;
+ }
+
+ this.getDeviceCapacity();
+ } else {
+ return new EZUIKitV3$1.EZUIKitPlayer(params);
+ }
+ }
+
+ _createClass$1(EZUIKitPlayer, [{
+ key: "initEZUIKitPlayer",
+ value: function initEZUIKitPlayer(params) {
+ var _this2 = this;
+
+ var id = params.id,
+ _params$width = params.width,
+ width = _params$width === void 0 ? 600 : _params$width,
+ _params$height = params.height,
+ height = _params$height === void 0 ? 400 : _params$height;
+
+ if (!params.width || !params.height) {
+ var videoDOMBounding = document.getElementById(id).getBoundingClientRect();
+
+ if (!params.width && videoDOMBounding.width > 0) {
+ width = videoDOMBounding.width;
+ }
+
+ if (!params.height && videoDOMBounding.height > 0) {
+ height = videoDOMBounding.height;
+ }
+ }
+
+ if (!document.getElementById("".concat(id, "-wrap"))) {
+ var wapDom = document.createElement("div");
+ wapDom.id = "".concat(id, "-wrap");
+ wapDom.style = "display:inline-block;width:".concat(width, "px;position:relative;vertical-align: bottom;");
+ document.getElementById(id).parentNode.insertBefore(wapDom, document.getElementById(id));
+ document.getElementById(id).parentNode.removeChild(document.getElementById(id)); // wapDom.appendChild(document.getElementById(id));
+
+ wapDom.innerHTML = "<div id=".concat(id, "></div>");
+ document.getElementById(id).style = "display:inline-block;width:".concat(width, "px;height:").concat(height, "px;");
+ document.getElementById(id).style.verticalAlign = "top";
+ }
+
+ if (this.themeId) {
+ this.Theme = new Theme(this, params.id);
+ window.EZUIKit[params.id].state.EZUIKitPlayer.themeInit = true;
+ this.Monitor.dclog({
+ url: this.url,
+ action: 2,
+ text: this.themeId
+ });
+
+ if (typeof this.params.handleThemeChange === 'function') {
+ this.handleThemeChange = this.params.handleThemeChange;
+ }
+ } // 鍒濆鍖朚essage妯″潡
+
+
+ var pluginMessage = new Message(this, id);
+ this.Message = pluginMessage;
+
+ var initDecoder = function initDecoder(resolve, reject) {
+ var jSPlugin;
+
+ if (isVersion2Available()) {
+ jSPlugin = new window.JSPluginV2({
+ szId: id,
+ iType: 2,
+ iWidth: width,
+ iHeight: height,
+ iMaxSplit: 1,
+ iCurrentSplit: 1,
+ szBasePath: "",
+ staticPath: _this2.staticPath,
+ oStyle: {
+ border: "none",
+ background: "#000000"
+ }
+ }); // 澧炲姞瑙嗛瀹瑰櫒
+ //var pluginStatus = new Status(this, id);
+
+ _this2.pluginStatus.loadingStart(id);
+
+ _this2.pluginStatus.loadingSetText({
+ text: '鍒濆鍖栨挱鏀惧櫒瀹屾垚'
+ });
+
+ jSPlugin.EventCallback = {
+ pluginErrorHandler: function pluginErrorHandler(iWndIndex, iErrorCode, oError) {
+ //鎻掍欢閿欒鍥炶皟
+ console.log(iWndIndex, iErrorCode, oError);
+
+ if (iErrorCode === 1003) {
+ console.log("鏂祦");
+
+ _this2.pluginStatus.loadingSetText({
+ text: "杩炴帴鏂紑锛岃閲嶈瘯",
+ color: 'red'
+ });
+
+ if (typeof _this2.params.handleError === 'function') {
+ _this2.params.handleError({
+ msg: "杩炴帴鏂紑锛岃閲嶈瘯",
+ retcode: 1003,
+ id: _this2.params.id,
+ type: "handleError"
+ });
+ }
+ }
+ }
+ };
+ _this2.env = {
+ domain: "https://open.ys7.com"
+ };
+
+ if (typeof params.env !== 'undefined') {
+ _this2.env = Object.assign(_this2.env, params.env);
+ }
+
+ if (typeof params.handleTalkSuccess !== 'undefined') {
+ _this2.handleTalkSuccess = params.handleTalkSuccess;
+ }
+
+ if (typeof params.handleTalkError !== 'undefined') {
+ _this2.handleTalkError = params.handleTalkError;
+ }
+
+ _this2.errorHander = new Code();
+ _this2.jSPlugin = jSPlugin; // if (this.themeId) {
+ // this.Theme = new Theme(this, id);
+ // window.EZUIKit[params.id].state.EZUIKitPlayer.themeInit = true;
+ // }
+
+ var checkTimer = setInterval(function () {
+ if (_this2.jSPlugin.Module && _this2.jSPlugin.Module._JSPlayM4_GetSDKVersion && _this2.jSPlugin.Module._JSPlayM4_GetSDKVersion()) {
+ clearInterval(checkTimer);
+
+ if (typeof _this2.params.handleInitSuccess === 'function') {
+ _this2.params.handleInitSuccess({
+ retcode: 0,
+ id: _this2.params.id,
+ type: "handleInitSuccess"
+ });
+ }
+
+ resolve({
+ meta: {
+ retcode: 200,
+ msg: "鍒濆鍖栨垚鍔�"
+ }
+ });
+ }
+ }, 50);
+ } else {
+ jSPlugin = new window.JSPluginV1({
+ szId: id,
+ iType: 2,
+ iWidth: width,
+ iHeight: height,
+ iMaxSplit: 1,
+ iCurrentSplit: 1,
+ szBasePath: "",
+ staticPath: _this2.staticPath,
+ oStyle: {
+ border: "none",
+ background: "#000000"
+ }
+ }); // 澧炲姞瑙嗛瀹瑰櫒
+ //var pluginStatus = new Status(this, id);
+
+ _this2.pluginStatus.loadingStart(id);
+
+ _this2.pluginStatus.loadingSetText({
+ text: '鍒濆鍖栨挱鏀惧櫒瀹屾垚'
+ });
+
+ jSPlugin.EventCallback = {
+ loadEventHandler: function loadEventHandler() {},
+ zoomEventResponse: function
+ /*iMode, aPoint*/
+ zoomEventResponse() {//鐢靛瓙鏀惧ぇ鍥炶皟
+ },
+ windowEventSelect: function windowEventSelect(iWndIndex) {//鎻掍欢閫変腑绐楀彛鍥炶皟
+ },
+ pluginErrorHandler: function pluginErrorHandler(iWndIndex, iErrorCode, oError) {
+ //鎻掍欢閿欒鍥炶皟
+ console.log(iWndIndex, iErrorCode, oError);
+
+ if (iErrorCode === 1003) {
+ console.log("鏂祦");
+
+ _this2.pluginStatus.loadingSetText({
+ text: "杩炴帴鏂紑锛岃閲嶈瘯",
+ color: 'red'
+ });
+
+ if (typeof _this2.params.handleError === 'function') {
+ _this2.params.handleError({
+ msg: "杩炴帴鏂紑锛岃閲嶈瘯",
+ retcode: 1003,
+ id: _this2.params.id,
+ type: "handleError"
+ });
+ }
+ }
+ },
+ windowEventOver: function windowEventOver(iWndIndex) {},
+ windowEventOut: function windowEventOut(iWndIndex) {},
+ windowEventUp: function windowEventUp(iWndIndex) {},
+ windowFullCcreenChange: function windowFullCcreenChange(bFull) {},
+ firstFrameDisplay: function firstFrameDisplay(iWndIndex, iWidth, iHeight) {
+ console.log(iWidth, iHeight);
+ jSPlugin.JS_SetCanFullScreen(false);
+
+ _this2.pluginStatus.loadingClear();
+ },
+ performanceLack: function performanceLack() {},
+ mouseEvent: function mouseEvent(iMouseEventType, iMouseX, iMouseY) {}
+ };
+ _this2.env = {
+ domain: "https://open.ys7.com"
+ };
+
+ if (typeof params.env !== 'undefined') {
+ _this2.env = Object.assign(_this2.env, params.env);
+ }
+
+ if (typeof params.handleTalkSuccess !== 'undefined') {
+ _this2.handleTalkSuccess = params.handleTalkSuccess;
+ }
+
+ if (typeof params.handleTalkError !== 'undefined') {
+ _this2.handleTalkError = params.handleTalkError;
+ }
+
+ _this2.errorHander = new Code();
+ _this2.jSPlugin = jSPlugin; // if (this.themeId) {
+ // this.Theme = new Theme(this, id);
+ // window.EZUIKit[params.id].state.EZUIKitPlayer.themeInit = true;
+ // }
+ // 寰呴渶瑕佹敼閫爌lugin锛屽紓姝ュ垽鏂紱
+
+ if (typeof _this2.params.handleInitSuccess === 'function') {
+ _this2.params.handleInitSuccess({
+ retcode: 0,
+ id: _this2.params.id,
+ type: "handleInitSuccess"
+ });
+ }
+
+ resolve({
+ meta: {
+ retcode: 200,
+ msg: "鍒濆鍖栨垚鍔�"
+ }
+ });
+ }
+ };
+
+ var initDecoderPromise = new Promise(initDecoder);
+ return initDecoderPromise;
+ }
+ }, {
+ key: "_getRealUrlPromise",
+ value: function _getRealUrlPromise(accessToken, url) {
+ var _this3 = this;
+
+ var apiDomain = this.env.domain;
+
+ if (this.env) {
+ apiDomain = this.env.domain;
+ }
+
+ var getRealUrlPromise = function getRealUrlPromise(resolve, reject) {
+ var realUrl = '';
+ var apiUrl = apiDomain + "/api/lapp/live/url/ezopen";
+ var data = new FormData();
+ data.append("ezopen", url);
+ data.append("isFlv", "false");
+ data.append("userAgent", window.navigator.userAgent);
+ data.append("isHttp", "false");
+ data.append("accessToken", accessToken);
+ fetch(apiUrl, {
+ method: "POST",
+ // headers: {
+ // 'Content-Type': 'application/json'
+ // },
+ body: data
+ }).then(function (response) {
+ return response.json();
+ }).then(function (data) {
+ if (data.code == 200 || data.retcode == 0) {
+ var playUrl = "";
+ var stream = "";
+
+ if (data.ext && data.ext.token) {
+ realUrl += data.data;
+ stream = data.ext.token;
+ playUrl = data.data;
+ } else if (data.data && data.data.token) {
+ realUrl += data.data.url;
+ stream = data.data.token;
+ playUrl = data.data.url;
+ }
+
+ var type = url.indexOf('live') !== -1 ? 'live' : 'playback';
+
+ if (type === 'live') {
+ realUrl = realUrl + '&ssn=' + stream + '&auth=1&biz=4&cln=100';
+ } else {
+ realUrl = realUrl + '&ssn=' + stream + '&auth=1&cln=100';
+ }
+
+ console.log(realUrl); // 璁剧疆绉橀挜 - 濡傛灉鍦板潃涓寘鍚閽ュ弬鏁帮紝鎾斁鍓嶉厤缃埌JSPlugin瀵瑰簲瀹炰緥涓�
+
+ var validateCode = getQueryString('checkCode', realUrl);
+
+ if (validateCode) {
+ if (typeof _this3.jSPlugin.decoderVersion !== 'undefined' && _this3.jSPlugin.decoderVersion === '2.0') {
+ _this3.validateCode = validateCode;
+ } else {
+ console.log("璁剧疆瀵嗛挜", validateCode);
+
+ _this3.jSPlugin.JS_SetSecretKey(0, validateCode);
+ }
+ } // 鍥炴斁澶勭悊
+
+
+ if (realUrl.indexOf('playback') !== -1) {
+ var wsBegin = getQueryString('begin', playUrl) || getQueryString('begin', url);
+ var wsEnd = getQueryString('end', playUrl) || getQueryString('end', url); // 鍏煎鍚勭鏃堕棿鏍煎紡
+
+ if (!wsBegin) {
+ var defaultDate = new Date();
+ realUrl = realUrl + '&begin=' + defaultDate.Format('yyyyMMdd') + 'T000000Z';
+ } else {
+ realUrl = realUrl.replace('&begin=' + getQueryString('begin', playUrl), '&begin=' + formatRecTime(wsBegin, '000000'));
+
+ if (!getQueryString('begin', realUrl)) {
+ realUrl += '&begin=' + formatRecTime(wsBegin, '000000');
+ }
+ }
+
+ if (!wsEnd) {
+ realUrl = realUrl + '&end=' + formatRecTime(getQueryString('begin', realUrl).substr(0, 8), '235959');
+ } else {
+ realUrl = realUrl.replace('&end=' + getQueryString('end', playUrl), '&end=' + formatRecTime(wsEnd, '235959'));
+
+ if (!getQueryString('end', realUrl)) {
+ realUrl += '&end=' + formatRecTime(wsEnd, '235959');
+ }
+ } // api閿欒澶勭悊
+
+
+ if (!getQueryString('stream', playUrl)) {
+ realUrl = realUrl.replace('stream', '&stream');
+ }
+
+ if (url.indexOf('.cloud') !== -1) {
+ var recAPISuccess = function recAPISuccess(data) {
+ if (data.code == 200) {
+ var recSliceArr = [];
+
+ if (data.data && data.data.files && data.data.files.length > 0) {
+ var dataArr = data.data.files;
+ var nextFileTime = new Date().getTime();
+ var isAll = data.data.isAll; // mock
+ // var number = 0;
+ //isAll = false;
+
+ if (isAll) {
+ recSliceArr = recSliceArrFun(dataArr);
+ var recSliceArrJSON = JSON.stringify(recSliceArr).replace('\\', '');
+ realUrl += '&recSlice=' + recSliceArrJSON.replace('\\', '') + '&r=' + Math.random();
+ resolve(realUrl);
+ } else {
+ // 浜戝瓨鍌ㄥ洖璋冧簨鍔�
+ var recTransaction = function recTransaction() {
+ function recAPIV2Success(data) {
+ if (data.data && data.data.files && data.data.files.length > 0) {
+ //if(number < 2 ) {
+ if (data.data.isAll == false) {
+ if (data.data.files) {
+ dataArr = dataArr.concat(data.data.files);
+ }
+
+ nextFileTime = data.data.nextFileTime > 0 ? data.data.nextFileTime : new Date().getTime();
+ recTransaction();
+ } else {
+ recSliceArr = recSliceArrFun(dataArr);
+ var recSliceArrJSON = JSON.stringify(recSliceArr).replace('\\', '');
+ realUrl += '&recSlice=' + recSliceArrJSON.replace('\\', '') + '&r=' + Math.random();
+ resolve(realUrl);
+ } // mock
+ //number = number + 1;
+
+ } else {
+ recSliceArr = recSliceArrFun(dataArr);
+ var recSliceArrJSON = JSON.stringify(recSliceArr).replace('\\', '');
+ realUrl += '&recSlice=' + recSliceArrJSON.replace('\\', '') + '&r=' + Math.random();
+ resolve(realUrl);
+ }
+ }
+
+ recSliceParams.startTime = nextFileTime;
+ request(recSliceUrl, 'POST', recSliceParams, '', recAPIV2Success);
+ };
+
+ recTransaction();
+ }
+ } else {
+ reject({
+ retcode: -1,
+ msg: "鏈壘鍒板綍鍍忕墖娈�"
+ });
+ }
+ } else {
+ reject({
+ retcode: -1,
+ msg: "鏈壘鍒板綍鍍忕墖娈�"
+ });
+ }
+
+ function recSliceArrFun(data) {
+ var downloadPathArr = [];
+ data.forEach(function (item, index) {
+ if (downloadPathArr.length == 0 || item.downloadPath !== downloadPathArr[downloadPathArr.length - 1].downloadPath) {
+ downloadPathArr.push({
+ downloadPath: item.downloadPath,
+ ownerId: item.ownerId,
+ iStorageVersion: item.iStorageVersion,
+ videoType: item.videoType,
+ iPlaySpeed: 0,
+ startTime: item.startTime,
+ endTime: item.endTime
+ });
+ } else {
+ downloadPathArr[downloadPathArr.length - 1].endTime = item.endTime;
+ }
+ });
+ return downloadPathArr;
+ }
+ };
+
+ //浜戝瓨鍌ㄥ洖鏀�
+ // 璋冪敤鍥炴斁API鎺ュ彛鑾峰彇鍥炴斁鐗囨 - start
+ var recBegin = reRormatRecTime(getQueryString('begin', realUrl));
+ var recEnd = reRormatRecTime(getQueryString('end', realUrl));
+ var deviceSerial = getQueryString('serial', realUrl);
+ var channelNo = getQueryString('chn', realUrl);
+ var recSliceUrl = apiDomain + "/api/lapp/video/by/time";
+ var recSliceParams = {
+ accessToken: _this3.accessToken,
+ recType: 1,
+ deviceSerial: deviceSerial,
+ channelNo: channelNo,
+ startTime: recBegin,
+ endTime: recEnd,
+ version: '2.0'
+ };
+ request(recSliceUrl, 'POST', recSliceParams, '', recAPISuccess);
+ } else {
+ // 鏈湴鍥炴斁
+ //alarm rec - start
+ if (url.indexOf('alarmId') !== -1) {
+ var _recAPISuccess = function _recAPISuccess(data) {
+ if (data.code == 200) {
+ var recSliceArr = [];
+
+ if (data.data) {
+ recSliceArr = recSliceArrFun([data.data]);
+ var recSliceArrJSON = JSON.stringify(recSliceArr).replace('\\', '');
+ realUrl += '&recSlice=' + recSliceArrJSON.replace('\\', '');
+ console.log("realUrl", realUrl, data.data.recType);
+
+ if (data.data.recType == 1) {
+ realUrl = realUrl.replace('/playback', '/cloudplayback');
+ } else {
+ realUrl = realUrl.replace('/cloudplayback', '/playback');
+ } // _this.opt.sources[0] = realUrl;
+
+
+ resolve(realUrl); // request(nodeUrl, 'GET', '', '', nodeSuccess, nodeError);
+ }
+ }
+
+ function recSliceArrFun(data) {
+ var downloadPathArr = [];
+ data.forEach(function (item, index) {
+ if (downloadPathArr.length == 0 || item.downloadPath !== downloadPathArr[downloadPathArr.length - 1].downloadPath) {
+ downloadPathArr.push({
+ downloadPath: item.downloadPath,
+ ownerId: item.ownerId,
+ iStorageVersion: item.iStorageVersion,
+ videoType: item.videoType,
+ iPlaySpeed: 0,
+ startTime: item.startTime,
+ endTime: item.endTime
+ });
+ } else {
+ downloadPathArr[downloadPathArr.length - 1].endTime = item.endTime;
+ }
+ });
+ console.log("downloadPathArr", downloadPathArr);
+ return downloadPathArr;
+ }
+ };
+
+ console.log("杩涘叆alarmId鍥炴斁"); // 璋冪敤鍥炴斁API鎺ュ彛鑾峰彇鍥炴斁鐗囨 - start
+
+ var alarmId = getQueryString('alarmId', realUrl);
+ var recBegin = reRormatRecTime(getQueryString('begin', realUrl));
+ var recEnd = reRormatRecTime(getQueryString('end', realUrl));
+ var deviceSerial = getQueryString('serial', realUrl);
+ var channelNo = getQueryString('chn', realUrl);
+ var recSliceUrl = apiDomain + "/api/lapp/video/by/id";
+ var recSliceParams = {
+ accessToken: _this3.accessToken,
+ // recType: 1,
+ deviceSerial: deviceSerial,
+ channelNo: channelNo,
+ alarmId: alarmId // startTime:recBegin,
+ // endTime:recEnd
+
+ };
+ request(recSliceUrl, 'POST', recSliceParams, '', _recAPISuccess);
+ } else {
+ // arlar rec - end
+ // request(nodeUrl, 'GET', '', '', nodeSuccess, nodeError);
+ resolve(realUrl);
+ }
+ }
+ } else {
+ resolve(realUrl);
+ }
+ } else {
+ _this3.pluginStatus.loadingSetText({
+ text: data.msg,
+ color: 'red'
+ });
+
+ if (typeof _this3.params.handleError === 'function') {
+ _this3.params.handleError({
+ retcode: data.code,
+ msg: data.msg,
+ id: _this3.params.id,
+ type: "handleError"
+ });
+ }
+
+ reject(data);
+ } // fetch real url end
+
+ });
+ };
+
+ return new Promise(function (resolve, reject) {
+ return getRealUrlPromise(resolve, reject);
+ }); // 鏍煎紡鍖栧洖鏀炬椂闂�
+
+ function formatRecTime(time, defaultTime) {
+ // 鐢ㄦ埛鏍煎紡 鏃犻渶鏇存敼 => 20182626T000000Z
+ // return time
+ // 鐢ㄦ埛鏍煎紡闇�瑕佹洿鏀�
+ //鐢ㄦ埛鏃堕棿闀垮害涓� 14 20181226000000 =銆� 20181226000000
+ // 鐢ㄦ埛闀垮害涓�12 201812260000 =銆� 201812260000 + defaultTime鍚庨潰2浣�
+ // 鐢ㄦ埛闀垮害涓�10 2018122600 =銆� 201812260000 + defaultTime鍚庨潰4浣�
+ // 鐢ㄦ埛闀垮害涓�8 20181226 =銆� 201812260000 + defaultTime鍚庨潰6浣�
+ // 缁撴灉 20181226000000 14浣�
+ // 鎻掑叆 TZ
+ var reg = /^[0-9]{8}T[0-9]{6}Z$/;
+
+ if (reg.test(time)) {
+ // 鐢ㄦ埛鏍煎紡 鏃犻渶鏇存敼 => 20182626T000000Z
+ return time;
+ } else if (/[0-9]{8,14}/.test(time)) {
+ var start = 6 - (14 - time.length);
+ var end = defaultTime.length;
+ var standardTime = time + defaultTime.substring(start, end);
+ return standardTime.slice(0, 8) + 'T' + standardTime.slice(8) + 'Z';
+ }
+
+ throw new Error('鍥炴斁鏃堕棿鏍煎紡鏈夎锛岃纭');
+ }
+
+ function reRormatRecTime(time) {
+ var year = time.slice(0, 4);
+ var month = time.slice(4, 6);
+ var day = time.slice(6, 8);
+ var hour = time.slice(9, 11);
+ var minute = time.slice(11, 13);
+ var second = time.slice(13, 15);
+ var date = year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second; // if (_this.opt.domain !== 'open') {
+ // return new Date(date.replace(/-/g, '/')).getTime() + (8 * 60 * 60 * 1000);
+ // }
+
+ return new Date(date.replace(/-/g, '/')).getTime();
+ }
+ }
+ }, {
+ key: "_pluginPlay",
+ value: function _pluginPlay(data, successCallback, errorCallback) {
+ var _this4 = this;
+
+ console.log("get real url result ===", data);
+
+ if (!data) {
+ return false;
+ }
+
+ function getPlayParams(url) {
+ var websocketConnectUrl = url.split('?')[0].replace('/live', '').replace('/playback', '');
+ var websocketStreamingParam = (url.indexOf('/live') === -1 ? url.indexOf('cloudplayback') !== -1 ? '/cloudplayback?' : '/playback?' : '/live?') + url.split('?')[1];
+
+ if (websocketStreamingParam.indexOf('/playback') !== -1) {
+ websocketStreamingParam = websocketStreamingParam.replace("stream=2", 'stream=1');
+ } // 鏈湴鍥炴斁浠呮敮鎸佷富鐮佹祦
+
+
+ return {
+ websocketConnectUrl: websocketConnectUrl,
+ websocketStreamingParam: websocketStreamingParam
+ };
+ }
+
+ var wsUrl = getPlayParams(data).websocketConnectUrl;
+
+ if (this.env && this.env.wsUrl) {
+ wsUrl = this.env.wsUrl;
+ }
+
+ var wsParams = {
+ playURL: getPlayParams(data).websocketStreamingParam
+ };
+ this.jSPlugin.JS_Play(wsUrl, wsParams, 0).then(function () {
+ console.log("鎾斁鎴愬姛");
+
+ if (_this4.validateCode && typeof _this4.jSPlugin.decoderVersion !== 'undefined' && _this4.jSPlugin.decoderVersion === '2.0') {
+ _this4.jSPlugin.JS_SetSecretKey(0, _this4.validateCode);
+ }
+
+ _this4.pluginStatus.loadingClear();
+
+ _this4.pluginStatus.setPlayStatus({
+ play: true,
+ loading: false
+ });
+
+ if (_this4.Theme) {
+ _this4.Theme.setDecoderState({
+ play: true
+ });
+
+ var isOpenSound = lodash.findIndex(_this4.Theme.themeData.footer.btnList, function (v) {
+ return v.iconId === 'sound' && v.isrender === 1 && v.defaultActive === 1;
+ }) > -1;
+ _this4.audio = isOpenSound;
+ }
+
+ if (_this4.audio) {
+ setTimeout(function () {
+ _this4.openSound();
+ }, 500);
+ }
+
+ if (typeof _this4.params.handleSuccess === 'function') {
+ _this4.params.handleSuccess({
+ retcode: 0,
+ id: _this4.params.id,
+ type: "handleSuccess"
+ });
+ }
+
+ successCallback();
+
+ _this4.Monitor.dclog({
+ url: _this4.url,
+ action: 211,
+ d: new Date().getTime() - _this4.playStartTime,
+ text: 'startPlaySuccess'
+ });
+
+ _this4.Monitor.playLog({
+ Enc: _this4.url.indexOf("@") === -1 ? 0 : 1,
+ // 0 涓嶅姞瀵� 1 鍔犲瘑
+ PlTp: _this4.url.indexOf("back") === -1 ? 1 : 2,
+ // 1 鐩存挱 2 鍥炴斁
+ Via: 2,
+ // 2 鏈嶅姟绔彇娴�
+ ErrCd: 0,
+ Cost: new Date().getTime() - _this4.playStartTime,
+ // 姣鏁�
+ Serial: matchEzopenUrl(_this4.url).deviceSerial,
+ Channel: matchEzopenUrl(_this4.url).channelNo,
+ Ver: isVersion2Available() ? "v7.0.0" : "v6.0.0"
+ });
+ }, function (err) {
+ console.log("err", err);
+ var msg = '鎾斁澶辫触锛岃妫�鏌ヨ澶囧強瀹㈡埛绔綉缁�';
+ var retcode = -1;
+
+ if (err && err.oError && err.oError.errorCode) {
+ var errorInfo = _this4.errorHander.matchErrorInfo(err.oError.errorCode);
+
+ msg = errorInfo && errorInfo.description ? errorInfo.description : '鎾斁澶辫触锛岃妫�鏌ヨ澶囧強瀹㈡埛绔綉缁�';
+ retcode = err.oError.errorCode;
+ }
+
+ _this4.pluginStatus.loadingSetText({
+ text: msg,
+ color: 'red'
+ });
+
+ if (typeof _this4.params.handleError === 'function') {
+ _this4.params.handleError({
+ retcode: retcode,
+ msg: msg,
+ id: _this4.params.id,
+ type: "handleError"
+ });
+ }
+
+ errorCallback();
+
+ _this4.Monitor.dclog({
+ url: _this4.url,
+ action: 411,
+ d: new Date().getTime() - _this4.playStartTime,
+ text: 'startPlayError'
+ });
+
+ _this4.Monitor.playLog({
+ Enc: _this4.url.indexOf("@") === -1 ? 0 : 1,
+ // 0 涓嶅姞瀵� 1 鍔犲瘑
+ PlTp: _this4.url.indexOf("back") === -1 ? 1 : 2,
+ // 1 鐩存挱 2 鍥炴斁
+ Via: 2,
+ // 2 鏈嶅姟绔彇娴�
+ ErrCd: retcode,
+ Cost: -1,
+ // 姣鏁�
+ Serial: matchEzopenUrl(_this4.url).deviceSerial,
+ Channel: matchEzopenUrl(_this4.url).channelNo,
+ Ver: isVersion2Available() ? "v7.0.0" : "v6.0.0"
+ });
+ });
+ }
+ }, {
+ key: "play",
+ value: function play(options) {
+ var _this5 = this;
+
+ if (this.jSPlugin.bPlay) {
+ return false;
+ }
+
+ this.pluginStatus.setPlayStatus({
+ play: false,
+ loading: true
+ });
+ this.playStartTime = new Date().getTime();
+ this.Monitor.dclog({
+ url: this.url,
+ action: 1,
+ d: new Date().getTime() - this.initTime,
+ text: 'startPlay'
+ });
+
+ if (options) {
+ if (typeof options.url === 'string') {
+ this.url = options.url;
+ }
+
+ if (typeof options.accessToken === 'string') {
+ this.accessToken = options.accessToken;
+ }
+
+ if (this.Theme && (typeof options.url === 'string' || typeof options.accessToken === 'string')) {
+ this.Theme.getDeviceInfo();
+ }
+ }
+
+ var promise = new Promise(function (resolve, reject) {
+ _this5._getRealUrlPromise(_this5.accessToken, _this5.url).then(function (data) {
+ _this5._pluginPlay(data, function () {
+ return resolve(true);
+ }, function () {
+ return reject(false);
+ });
+ })["catch"](function (err) {
+ var msg = err.msg ? err.msg : '鎾斁澶辫触锛岃妫�鏌ヨ澶囧強瀹㈡埛绔綉缁�';
+
+ _this5.pluginStatus.loadingSetText({
+ text: msg,
+ color: 'red'
+ });
+
+ if (typeof _this5.params.handleError === 'function') {
+ _this5.params.handleError({
+ retcode: err.oError ? err.oError.errorCode : -1,
+ msg: msg,
+ id: _this5.params.id,
+ type: "handleError"
+ });
+ }
+
+ reject(false);
+ });
+ });
+ return promise;
+ }
+ }, {
+ key: "stop",
+ value: function stop() {
+ var _this6 = this;
+
+ if (!this.jSPlugin.bPlay) {
+ console.log("褰撳墠闈炴挱鏀剧姸鎬�");
+ var promise = new Promise(function (resolve, reject) {
+ reject({
+ retcode: -1,
+ msg: "褰撳墠闈炴挱鏀剧姸鎬�"
+ });
+ });
+ return promise;
+ }
+
+ this.pluginStatus.setPlayStatus({
+ loading: true
+ });
+ return this.jSPlugin.JS_Stop(0).then(function () {
+ console.log("鍋滄鎴愬姛");
+
+ _this6.pluginStatus.setPlayStatus({
+ play: false,
+ loading: false
+ });
+
+ if (_this6.Theme) {
+ _this6.Theme.setDecoderState({
+ play: false
+ });
+ }
+ });
+ }
+ }, {
+ key: "changeVideoLevel",
+ value: function changeVideoLevel(level) {
+ var _this7 = this;
+ var initUrl = this.url;
+ var url = level ? initUrl.replace(".live", ".hd.live") : initUrl.replace(".hd.live", ".live");
+ this.jSPlugin.playURL = level ? this.jSPlugin.playURL.replace("stream=2", "stream=1") : this.jSPlugin.playURL.replace("stream=1", "stream=2");
+ console.log("changeVideoLevel", url, this.jSPlugin.playURL);
+ this.url = url;
+ var promise = new Promise(function (resolve, reject) {
+ _this7.pause().then(function () {
+ console.log("鏆傚仠鎴愬姛");
+
+ _this7.resume().then(function (data) {
+ console.log("鎭㈠鎴愬姛");
+ });
+ })["catch"](function () {
+ console.log("鏆傚仠澶辫触");
+
+ _this7.resume().then(function (data) {
+ console.log("鎭㈠鎴愬姛");
+ });
+ });
+ });
+ return promise;
+ }
+ }, {
+ key: "changePlayUrl",
+ value: function changePlayUrl(options) {
+ var _this8 = this;
+
+ var initUrl = this.url;
+ var url = matchUrl(initUrl, options);
+ console.log("changePlayUrl", url);
+ this.url = url;
+ var promise = new Promise(function (resolve, reject) {
+ _this8.stop().then(function () {
+ console.log("changePlayUrl stop success"); // 浜戝彴鍒濆鍖�
+
+ if (_this8.Theme && _this8.Theme.Ptz) {
+ _this8.Theme.setDecoderState({
+ pantile: false
+ });
+
+ _this8.Theme.Ptz.hide();
+ } // 褰曞埗鍒濆鍖�
+
+
+ if (_this8.Theme) {
+ _this8.Theme.setDecoderState({
+ recordvideo: false
+ });
+ } // 鐢靛瓙鏀惧ぇ鍒濆鍖�
+
+
+ if (_this8.Theme) {
+ _this8.Theme.setDecoderState({
+ zoom: false
+ });
+
+ if (_this8.Zoom) {
+ _this8.Zoom.stopZoom();
+ }
+ } // 瀵硅鍒濆鍖�
+
+
+ if (_this8.Theme && _this8.Theme.decoderState.state.talk) {
+ _this8.stopTalk();
+
+ _this8.Theme.setDecoderState({
+ talk: false
+ });
+ }
+
+ if (options.accessToken) {
+ _this8.accessToken = options.accessToken;
+ return _this8.play({
+ accessToken: options.accessToken,
+ url: url
+ }).then(function () {
+ console.log("changePlayUrl replay success"); // 褰撳墠澶勪簬缃戦〉鍏ㄥ睆鐘舵��
+
+ if (_this8.Theme && _this8.Theme.decoderState.state.webExpend) {
+ _this8.Theme.webExpend();
+ } // 褰撳墠澶勪簬鍏ㄥ睆鐘舵��
+
+
+ if (_this8.Theme && _this8.Theme.decoderState.state.expend) {
+ _this8.Theme.expend();
+ }
+
+ resolve(url);
+ })["catch"](function (err) {
+ reject(url);
+ });
+ }
+
+ _this8.play(url).then(function () {
+ console.log("changePlayUrl replay success"); // 褰撳墠澶勪簬缃戦〉鍏ㄥ睆鐘舵��
+
+ if (_this8.Theme && _this8.Theme.decoderState.state.webExpend) {
+ _this8.Theme.webExpend();
+ } // 褰撳墠澶勪簬鍏ㄥ睆鐘舵��
+
+
+ if (_this8.Theme && _this8.Theme.decoderState.state.expend) {
+ _this8.Theme.expend();
+ }
+
+ resolve(url);
+ })["catch"](function (err) {
+ reject(url);
+ });
+ })["catch"](function (err) {
+ console.log("鍒囨崲杩囩▼鍋滄澶辫触", err);
+
+ if (options.accessToken) {
+ _this8.accessToken = options.accessToken;
+ return _this8.play({
+ accessToken: options.accessToken,
+ url: url
+ }).then(function () {
+ resolve(url);
+ })["catch"](function (err) {
+ reject(url);
+ });
+ }
+
+ _this8.play(url).then(function () {
+ resolve(url);
+ })["catch"](function (err) {
+ reject(url);
+ });
+ });
+ });
+ /**
+ * 鍖归厤鎾斁鍦板潃 鐢ㄦ埛鎾斁鍦板潃鍒囨崲
+ * options
+ * type | string | live,rec
+ * hd | boolean | true,false
+ * deviceSerial
+ * channelNO
+ * begin
+ * end
+ */
+
+ function matchUrl(matchInitUrl, matchOptions) {
+ if (matchOptions.url) {
+ return matchOptions.url;
+ }
+
+ var type = matchInitUrl.split("/")[4].split(".")[matchInitUrl.split("/")[4].split(".").length - 1].split("?")[0];
+
+ if (type === 'rec' && matchInitUrl.indexOf(".cloud.rec") !== -1) {
+ type = 'cloud.rec';
+ }
+
+ if (matchOptions.type) {
+ type = matchOptions.type;
+ }
+
+ var deviceSerial = matchInitUrl.split("/")[3];
+
+ if (matchOptions.deviceSerial) {
+ deviceSerial = matchOptions.deviceSerial;
+ }
+
+ var channelNo = matchInitUrl.split("/")[4].split(".")[0];
+
+ if (matchOptions.channelNo) {
+ channelNo = matchOptions.channelNo;
+ } // 濡傛灉鍒囨崲璁惧锛屼箣鍓嶈澶囨湁楠岃瘉鐮侊紝鏂拌澶囨棤楠岃瘉鐮侊紝寤鸿浼犵┖楠岃瘉鐮�,娓呯悊楠岃瘉鐮侊紙闄嶄綆瑙g爜娑堣�楋級
+
+
+ var validCode = matchInitUrl.split("/")[2].split("@").length === 2 ? matchInitUrl.split("/")[2].split("@")[0] : "";
+
+ if (typeof matchOptions.validCode !== 'undefined') {
+ validCode = matchOptions.validCode;
+ }
+
+ var hd = typeof matchOptions.hd === 'undefined' ? matchInitUrl.indexOf('.hd') !== -1 : matchOptions.hd;
+ var result = "ezopen://".concat(validCode ? "".concat(validCode, "@") : "", "open.ys7.com/").concat(deviceSerial, "/").concat(channelNo).concat(hd ? '.hd' : '', ".").concat(type);
+
+ if (type === 'live') {
+ return result;
+ }
+
+ result = "ezopen://".concat(validCode ? "".concat(validCode, "@") : "", "open.ys7.com/").concat(deviceSerial, "/").concat(channelNo, ".").concat(type);
+
+ if (matchOptions.begin && matchOptions.end) {
+ result += "?begin=".concat(matchOptions.begin, "&end=").concat(matchOptions.end);
+ } else if (matchOptions.begin) {
+ result += "?begin=".concat(matchOptions.begin);
+ } else if (getQueryString("begin", matchInitUrl)) {
+ result += "?begin=".concat(getQueryString("begin", matchInitUrl));
+ }
+
+ return result;
+ }
+
+ return promise;
+ }
+ }, {
+ key: "getOSDTime",
+ value: function getOSDTime() {
+ var _this9 = this;
+
+ var promise = new Promise(function (resolve, reject) {
+ _this9.jSPlugin.JS_GetOSDTime(0).then(function (data) {
+ resolve({
+ code: 0,
+ retcode: 0,
+ data: data
+ }); // 鍏煎鏃х増鏈琧allback
+
+ if (typeof _this9.params.getOSDTimeCallBack === 'function') {
+ _this9.params.getOSDTimeCallBack({
+ id: _this9.id,
+ type: 'getOSDTime',
+ code: 0,
+ data: data
+ });
+ }
+ })["catch"](function (err) {
+ reject({
+ code: -1,
+ retcode: -1,
+ data: err
+ }); // 鍏煎鏃х増鏈琧allback
+
+ if (typeof _this9.params.getOSDTimeCallBack === 'function') {
+ _this9.params.getOSDTimeCallBack({
+ id: _this9.id,
+ type: 'getOSDTime',
+ code: -1,
+ data: -1
+ });
+ }
+ });
+ });
+ return promise;
+ }
+ }, {
+ key: "capturePicture",
+ value: function capturePicture(name) {
+ var _this10 = this;
+
+ var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
+ var capturePictureRT = this.jSPlugin.JS_CapturePicture(0, name, "JPEG", callback, !!callback);
+
+ if (isPromise(capturePictureRT)) {
+ // 鍏煎鏃х増鏈琧allback
+ if (typeof this.params.capturePictureCallBack === 'function') {
+ capturePictureRT.then(function () {
+ _this10.params.capturePictureCallBack({
+ id: _this10.id,
+ type: 'capturePicture',
+ code: 0
+ });
+ })["catch"](function () {
+ _this10.params.capturePictureCallBack({
+ id: _this10.id,
+ type: 'capturePicture',
+ code: -1
+ });
+ });
+ }
+
+ return capturePictureRT;
+ }
+
+ return new Promise(function (resolve) {
+ resolve(capturePictureRT);
+ });
+ }
+ }, {
+ key: "startSave",
+ value: function startSave(name) {
+ var _this11 = this;
+
+ var startSaveRT = this.jSPlugin.JS_StartSave(0, name);
+
+ if (isPromise(startSaveRT)) {
+ // 鍏煎鏃х増鏈琧allback
+ if (typeof this.params.startSaveCallBack === 'function') {
+ startSaveRT.then(function () {
+ _this11.params.startSaveCallBack({
+ id: _this11.id,
+ type: 'startSave',
+ code: 0
+ });
+ })["catch"](function () {
+ _this11.params.startSaveCallBack({
+ id: _this11.id,
+ type: 'startSave',
+ code: -1
+ });
+ });
+ }
+
+ return startSaveRT;
+ }
+
+ if (this.Theme) {
+ this.Theme.setDecoderState({
+ recordvideo: true
+ });
+ }
+
+ return new Promise(function (resolve) {
+ resolve(startSaveRT);
+ });
+ }
+ }, {
+ key: "stopSave",
+ value: function stopSave() {
+ var _this12 = this;
+
+ var stopSaveRT = this.jSPlugin.JS_StopSave(0);
+
+ if (isPromise(stopSaveRT)) {
+ // 鍏煎鏃х増鏈琧allback
+ if (typeof this.params.startSaveCallBack === 'function') {
+ stopSaveRT.then(function () {
+ _this12.params.stopSaveCallBack({
+ id: _this12.id,
+ type: 'stopSave',
+ code: 0
+ });
+ })["catch"](function () {
+ _this12.params.stopSaveCallBack({
+ id: _this12.id,
+ type: 'stopSave',
+ code: -1
+ });
+ });
+ }
+
+ return stopSaveRT;
+ }
+
+ if (this.Theme) {
+ this.Theme.setDecoderState({
+ recordvideo: false
+ });
+ }
+
+ return new Promise(function (resolve) {
+ resolve(stopSaveRT);
+ });
+ }
+ }, {
+ key: "openSound",
+ value: function openSound() {
+ var openSoundRT = this.jSPlugin.JS_OpenSound(0);
+ console.log("鎵撳紑澹伴煶", openSoundRT);
+
+ if (isPromise(openSoundRT)) {
+ return openSoundRT;
+ }
+
+ if (this.Theme) {
+ this.Theme.setDecoderState({
+ sound: true
+ });
+ } // 鍏煎鏃х増鏈琧allback
+
+
+ if (typeof this.params.openSoundCallBack === 'function') {
+ this.params.openSoundCallBack({
+ id: this.id,
+ type: 'openSound',
+ code: openSoundRT
+ });
+ }
+
+ return new Promise(function (resolve) {
+ resolve(openSoundRT);
+ });
+ }
+ }, {
+ key: "closeSound",
+ value: function closeSound() {
+ var closeSoundRT = this.jSPlugin.JS_CloseSound(0);
+
+ if (isPromise(closeSoundRT)) {
+ return closeSoundRT;
+ }
+
+ if (this.Theme) {
+ this.Theme.setDecoderState({
+ sound: false
+ });
+ } // 鍏煎鏃х増鏈琧allback
+
+
+ if (typeof this.params.closeSoundCallBack === 'function') {
+ this.params.closeSoundCallBack({
+ id: this.id,
+ type: 'closeSound',
+ code: closeSoundRT
+ });
+ }
+
+ return new Promise(function (resolve) {
+ resolve(closeSoundRT);
+ });
+ }
+ }, {
+ key: "enableZoom",
+ value: function enableZoom() {
+ var enableZoomRT = this.jSPlugin.JS_EnableZoom(0);
+
+ if (isPromise(enableZoomRT)) {
+ return enableZoomRT;
+ }
+
+ return new Promise(function (resolve) {
+ resolve(enableZoomRT);
+ });
+ }
+ }, {
+ key: "closeZoom",
+ value: function closeZoom() {
+ var closeZoomRT = this.jSPlugin.JS_DisableZoom(0);
+
+ if (isPromise(closeZoomRT)) {
+ return closeZoomRT;
+ }
+
+ return new Promise(function (resolve) {
+ resolve(closeZoomRT);
+ });
+ }
+ }, {
+ key: "setPoster",
+ value: function setPoster(url) {
+ // this.pluginStatus.setPoster(url);
+ if (isVersion2Available()) {
+ if (document.getElementById("".concat(this.id))) {
+ document.getElementById("".concat(this.id)).style.backgroundImage = "url(".concat(url, ")");
+ document.getElementById("".concat(this.id)).style.backgroundSize = "cover";
+ }
+ } else {
+ if (document.getElementById("".concat(this.id, "canvas0"))) {
+ document.getElementById("".concat(this.id, "canvas0")).style.backgroundImage = "url(".concat(url, ")");
+ document.getElementById("".concat(this.id, "canvas0")).style.backgroundSize = "cover";
+ }
+ }
+ }
+ }, {
+ key: "reSize",
+ value: function reSize(width, height) {
+ var headerHeight = 0;
+ var timeLineHeight = 0;
+ this.params.height = height;
+ this.params.width = width; //鎬讳綋楂樺害鍖呭惈妯℃澘
+
+ if (this.Theme && this.Theme.isNeedRenderHeader && document.getElementById("".concat(this.id, "-headControl"))) {
+ headerHeight = parseInt(document.getElementById("".concat(this.id, "-headControl")).style.height, 10);
+ }
+
+ if (this.Theme && this.Theme.isNeedRenderTimeLine && !this.isMobile) {
+ timeLineHeight = 48;
+ }
+
+ height = height - headerHeight - timeLineHeight;
+ this.width = width;
+ this.height = height;
+ document.getElementById("".concat(this.id, "-wrap")).style = "width:".concat(width, "px;position:relative;display:inline-block;vertical-align: bottom;");
+ document.getElementById("".concat(this.id)).style.width = width + 'px';
+ document.getElementById("".concat(this.id)).style.height = height + 'px';
+
+ if (this.jSPlugin && this.jSPlugin.bPlay) {
+ if (this.jSPlugin) {
+ this.jSPlugin.iHeight = height;
+ this.jSPlugin.iWidth = width;
+ }
+
+ this.jSPlugin.JS_Resize(width, height);
+ } else {
+ if (document.getElementById("".concat(this.id, "-player"))) {
+ document.getElementById("".concat(this.id, "-player")).style.width = width;
+ document.getElementById("".concat(this.id, "-player")).style.height = height;
+ }
+
+ var scale = 1;
+
+ if (document.getElementById("".concat(this.id, "canvas0"))) {
+ var isNeedScale = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i);
+
+ if (isNeedScale) {
+ scale = 2;
+ }
+
+ document.getElementById("".concat(this.id, "canvas0")).style.width = width * scale;
+ document.getElementById("".concat(this.id, "canvas0")).style.height = height * scale;
+ document.getElementById("".concat(this.id, "canvas0")).width = width * scale;
+ document.getElementById("".concat(this.id, "canvas0")).height = height * scale;
+ document.getElementById("".concat(this.id, "canvas0")).parentNode.style.width = width * scale;
+ document.getElementById("".concat(this.id, "canvas0")).parentNode.style.height = height * scale;
+ document.getElementById("".concat(this.id, "canvas_draw0")).height = height * scale;
+ }
+
+ if (this.jSPlugin) {
+ this.jSPlugin.iHeight = height * scale;
+ this.jSPlugin.iWidth = width * scale;
+ }
+ }
+ }
+ }, {
+ key: "fast",
+ value: function fast(next) {
+ var _this13 = this;
+
+ var speed = this.speed;
+
+ if (next) {
+ var fastRT = this.jSPlugin.JS_Fast(0, next);
+ } else {
+ if (speed === 1) {
+ speed = 2;
+ } else if (speed === 2) {
+ speed = 4;
+ } else {
+ if (typeof this.params.handleError === 'function') {
+ this.params.handleError({
+ msg: "鎾斁閫熷害鏈�澶т负4鍊嶉�熷害",
+ retcode: 1003,
+ id: this.id,
+ type: "handleError"
+ });
+ }
+
+ return new Promise(function (resolve, reject) {
+ _this13.speed = speed;
+ reject({
+ code: -1,
+ data: {
+ speed: speed,
+ result: "鎾斁閫熷害鏈�澶т负4鍊嶉�熷害"
+ }
+ });
+ });
+ }
+
+ var fastRT = this.jSPlugin.JS_Fast(0);
+ }
+
+ return new Promise(function (resolve) {
+ _this13.speed = speed;
+ resolve({
+ code: 0,
+ data: {
+ speed: speed,
+ result: fastRT
+ }
+ });
+ });
+ }
+ }, {
+ key: "slow",
+ value: function slow() {
+ var _this14 = this;
+
+ var speed = this.speed;
+
+ if (speed === 4) {
+ speed = 2;
+ } else if (speed === 2) {
+ speed = 1;
+ } else {
+ if (typeof this.params.handleError === 'function') {
+ this.params.handleError({
+ msg: "鎾斁閫熷害鏈�灏忎负1鍊嶉�熷害",
+ retcode: 1003,
+ id: this.id,
+ type: "handleError"
+ });
+ }
+
+ return new Promise(function (resolve, reject) {
+ _this14.speed = speed;
+ reject({
+ code: -1,
+ data: {
+ speed: speed,
+ result: "鎾斁閫熷害鏈�灏忎负1鍊嶉�熷害"
+ }
+ });
+ });
+ }
+
+ var slowRT = this.jSPlugin.JS_Slow(0);
+ return new Promise(function (resolve) {
+ _this14.speed = speed;
+ resolve({
+ code: 0,
+ data: {
+ speed: speed,
+ result: slowRT
+ }
+ });
+ });
+ }
+ }, {
+ key: "seek",
+ value: function seek(startTime, endTime) {
+ var url = this.url;
+ var currentDay = (getQueryString('begin', url) || new Date().Format('yyyyMMdd')).substr(0, 8);
+ endTime = formatRecTime(currentDay, '235959');
+
+ if (startTime.length === 6) {
+ startTime = formatRecTime(currentDay, startTime);
+ } else if (startTime.length === 16) {
+ if (startTime.substr(0, 8) !== currentDay) {
+ if (typeof this.params.handleError === 'function') {
+ this.params.handleError({
+ msg: "seek鏃堕棿涓嶈兘璺ㄦ棩鏈�",
+ retcode: -1,
+ id: this.id,
+ type: "handleError"
+ });
+ }
+
+ return false;
+ }
+ } else {
+ if (typeof this.params.handleError === 'function') {
+ this.params.handleError({
+ msg: "seek鏃堕棿鏍煎紡閿欒",
+ retcode: -1,
+ id: this.id,
+ type: "handleError"
+ });
+ }
+
+ return false;
+ } // 鏍煎紡鍖栧洖鏀炬椂闂�
+
+
+ function formatRecTime(time, defaultTime) {
+ // 鐢ㄦ埛鏍煎紡 鏃犻渶鏇存敼 => 20182626T000000Z
+ // return time
+ // 鐢ㄦ埛鏍煎紡闇�瑕佹洿鏀�
+ //鐢ㄦ埛鏃堕棿闀垮害涓� 14 20181226000000 =銆� 20181226000000
+ // 鐢ㄦ埛闀垮害涓�12 201812260000 =銆� 201812260000 + defaultTime鍚庨潰2浣�
+ // 鐢ㄦ埛闀垮害涓�10 2018122600 =銆� 201812260000 + defaultTime鍚庨潰4浣�
+ // 鐢ㄦ埛闀垮害涓�8 20181226 =銆� 201812260000 + defaultTime鍚庨潰6浣�
+ // 缁撴灉 20181226000000 14浣�
+ // 鎻掑叆 TZ
+ var reg = /^[0-9]{8}T[0-9]{6}Z$/;
+
+ if (reg.test(time)) {
+ // 鐢ㄦ埛鏍煎紡 鏃犻渶鏇存敼 => 20182626T000000Z
+ return time;
+ } else if (/[0-9]{8,14}/.test(time)) {
+ var start = 6 - (14 - time.length);
+ var end = defaultTime.length;
+ var standardTime = time + defaultTime.substring(start, end);
+ return standardTime.slice(0, 8) + 'T' + standardTime.slice(8) + 'Z';
+ }
+
+ throw new Error('鍥炴斁鏃堕棿鏍煎紡鏈夎锛岃纭');
+ }
+
+ var seekRT = this.jSPlugin.JS_Seek(0, startTime, endTime);
+ console.log("seekRT", seekRT);
+
+ if (isPromise(seekRT)) {
+ return seekRT;
+ }
+
+ return new Promise(function (resolve) {
+ resolve(seekRT);
+ });
+ }
+ }, {
+ key: "fullScreen",
+ value: function fullScreen() {
+ var _this15 = this;
+
+ var promise = requestFullScreenPromise(document.getElementById("".concat(this.id)));
+ promise.then(function (data) {
+ console.log("鍏ㄥ睆promise", window.screen.availWidth);
+
+ _this15.jSPlugin.JS_Resize(window.screen.availWidth, window.screen.availHeight); // 鍏煎鏃х増鏈琧allback
+
+
+ if (typeof _this15.params.fullScreenCallBack === 'function') {
+ _this15.params.fullScreenCallBack({
+ id: _this15.id,
+ type: 'fullScreen',
+ code: 0
+ });
+ }
+ }); // 鐩戝惉鍏ㄥ睆浜嬩欢瑙﹀彂
+
+ var fullscreenchange = function fullscreenchange() {
+ var isFullScreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
+
+ if (!isFullScreen) {
+ _this15.jSPlugin.JS_Resize(_this15.width, _this15.height);
+ } // 鍏煎鏃х増鏈琧allback
+
+
+ if (typeof _this15.params.fullScreenChangeCallBack === 'function') {
+ _this15.params.fullScreenChangeCallBack({
+ id: _this15.id,
+ type: 'fullScreen',
+ code: isFullScreen
+ });
+ }
+ };
+
+ ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange'].forEach(function (item) {
+ window.addEventListener(item, function (data) {
+ return fullscreenchange();
+ });
+ });
+ }
+ }, {
+ key: "cancelFullScreen",
+ value: function cancelFullScreen() {
+ var _this16 = this;
+
+ var cancelPromise = cancelFullScreenPromise();
+ cancelPromise.then(function (data) {
+ console.log("鍙栨秷鍏ㄥ睆", data, _this16.jSPlugin);
+
+ _this16.jSPlugin.JS_Resize(_this16.width, _this16.height);
+ });
+ }
+ }, {
+ key: "startTalk",
+ value: function startTalk() {
+ this.Talk.startTalk();
+ }
+ }, {
+ key: "stopTalk",
+ value: function stopTalk() {
+ this.Talk.stopTalk();
+ }
+ }, {
+ key: "destroy",
+ value: function destroy() {
+ var destroyRT = this.jSPlugin.JS_DestroyWorker(0);
+
+ if (this.Theme) {
+ this.Theme = null;
+ window.EZUIKit[this.params.id].state.EZUIKitPlayer.themeInit = false;
+ }
+
+ if (isPromise(destroyRT)) {
+ return destroyRT;
+ }
+
+ return new Promise(function (resolve) {
+ resolve(destroyRT);
+ });
+ }
+ }, {
+ key: "getDeviceCapacity",
+ value: function getDeviceCapacity() {
+ var _this17 = this;
+
+ var apiDomain = this.env.domain;
+
+ if (this.env) {
+ apiDomain = this.env.domain;
+ }
+
+ var capacityUrl = apiDomain + "/api/lapp/device/capacity";
+
+ var capacitySuccess = function capacitySuccess(data) {
+ if (data.code == 200 && data.data) {
+ _this17.capacity = data.data;
+ }
+ };
+
+ var capacityParams = {
+ accessToken: this.accessToken,
+ deviceSerial: matchEzopenUrl(this.url).deviceSerial
+ };
+ request(capacityUrl, 'POST', capacityParams, '', capacitySuccess);
+ }
+ }, {
+ key: "pause",
+ value: function pause() {
+ return this.jSPlugin.JS_Pause(0);
+ }
+ }, {
+ key: "resume",
+ value: function resume(time) {
+ return this.jSPlugin.JS_Resume(time);
+ }
+ }]);
+
+ return EZUIKitPlayer;
+}();
+
+(function (global, factory) {
+
+ if ((typeof module === "undefined" ? "undefined" : _typeof(module)) === "object" && _typeof(module.exports) === "object") {
+ module.exports = global.document ? factory(global, true) : function (w) {
+ if (!w.document) {
+ throw new Error("EZUIPlayer requires a window with a document");
+ }
+
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ } // Pass this if window is not defined yet
+
+})(typeof window !== "undefined" ? window : undefined, function (window, noGlobal) {
+ var EZUIKit = {
+ Core: Core,
+ HLS: HLS,
+ FLV: FLV,
+ EZUIKitPlayer: EZUIKitPlayer
+ };
+ window.EZUIKit = EZUIKit;
+ return EZUIKit;
+});
diff --git a/static/logo.png b/static/logo.png
new file mode 100644
index 0000000..19bdf71
--- /dev/null
+++ b/static/logo.png
Binary files differ
diff --git a/static/splash.png b/static/splash.png
new file mode 100644
index 0000000..eb17b17
--- /dev/null
+++ b/static/splash.png
Binary files differ
--
Gitblit v1.9.3