Commit 5a7a7a12bde268c104610d3e81a08df06ccab5eb

Authored by 648540858
2 parents 66eda32a fec69c71

Merge branch 'wvp-28181-2.0' into main-dev

# Conflicts:
#	src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
#	src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java
#	src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
#	src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
#	src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
#	src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
#	src/main/resources/all-application.yml
#	web_src/config/index.js
#	web_src/src/components/dialog/devicePlayer.vue
Showing 95 changed files with 2211 additions and 1154 deletions

Too many changes to show.

To preserve performance only 95 of 162 files are displayed.

README.md
@@ -27,7 +27,7 @@ wvp使用文档 [https://doc.wvp-pro.cn](https://doc.wvp-pro.cn) @@ -27,7 +27,7 @@ wvp使用文档 [https://doc.wvp-pro.cn](https://doc.wvp-pro.cn)
27 ZLM使用文档 [https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit) 27 ZLM使用文档 [https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit)
28 > wvp文档由gitee提供服务,如果遇到打不开请多刷新几次。 28 > wvp文档由gitee提供服务,如果遇到打不开请多刷新几次。
29 29
30 -# 社群地址 30 +# 付费社群
31 [![社群](doc/_media/shequ.png "shequ")](https://t.zsxq.com/0d8VAD3Dm) 31 [![社群](doc/_media/shequ.png "shequ")](https://t.zsxq.com/0d8VAD3Dm)
32 > 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接退款,大家不需要有顾虑,来白嫖三天也不是不可以。 32 > 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接退款,大家不需要有顾虑,来白嫖三天也不是不可以。
33 33
@@ -104,6 +104,8 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git @@ -104,6 +104,8 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git
104 - [X] 云端录像,推流/代理/国标视频均可以录制在云端服务器,支持预览和下载 104 - [X] 云端录像,推流/代理/国标视频均可以录制在云端服务器,支持预览和下载
105 - [X] 支持打包可执行jar和war 105 - [X] 支持打包可执行jar和war
106 - [X] 支持跨域请求,支持前后端分离部署 106 - [X] 支持跨域请求,支持前后端分离部署
  107 +- [X] 支持Mysql,Postgresql,金仓等数据库
  108 +- [X] 支持Onvif(目前在onvif分支,需要安装onvif服务,服务请在知识星球获取)
107 109
108 # 授权协议 110 # 授权协议
109 本项目自有代码使用宽松的MIT协议,在保留版权信息的情况下可以自由应用于各自商用、非商业的项目。 但是本项目也零碎的使用了一些其他的开源代码,在商用的情况下请自行替代或剔除; 由于使用本项目而产生的商业纠纷或侵权行为一概与本项目及开发者无关,请自行承担法律风险。 在使用本项目代码时,也应该在授权协议中同时表明本项目依赖的第三方库的协议 111 本项目自有代码使用宽松的MIT协议,在保留版权信息的情况下可以自由应用于各自商用、非商业的项目。 但是本项目也零碎的使用了一些其他的开源代码,在商用的情况下请自行替代或剔除; 由于使用本项目而产生的商业纠纷或侵权行为一概与本项目及开发者无关,请自行承担法律风险。 在使用本项目代码时,也应该在授权协议中同时表明本项目依赖的第三方库的协议
doc/README.md
@@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
14 - 完全开源,且使用MIT许可协议。保留版权的情况下可以用于商业项目。 14 - 完全开源,且使用MIT许可协议。保留版权的情况下可以用于商业项目。
15 - 支持多流媒体节点负载均衡。 15 - 支持多流媒体节点负载均衡。
16 16
17 -# 社群 17 +# 付费社群
18 [![社群](_media/shequ.png "shequ")](https://t.zsxq.com/0d8VAD3Dm) 18 [![社群](_media/shequ.png "shequ")](https://t.zsxq.com/0d8VAD3Dm)
19 > 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接退款,大家不需要有顾虑,来白嫖三天也不是不可以。 19 > 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接退款,大家不需要有顾虑,来白嫖三天也不是不可以。
20 20
@@ -62,16 +62,16 @@ @@ -62,16 +62,16 @@
62 - [X] 注册 62 - [X] 注册
63 - [X] 注销 63 - [X] 注销
64 - [X] 实时视音频点播 64 - [X] 实时视音频点播
65 -- [ ] 设备控制  
66 - - [ ] 云台控制 65 +- [X] 设备控制
  66 + - [X] 云台控制
67 - [ ] 远程启动 67 - [ ] 远程启动
68 - - [ ] 录像控制  
69 - - [ ] 报警布防/撤防  
70 - - [ ] 报警复位  
71 - - [ ] 强制关键帧  
72 - - [ ] 拉框放大  
73 - - [ ] 拉框缩小  
74 - - [ ] 看守位控制 68 + - [X] 录像控制
  69 + - [X] 报警布防/撤防
  70 + - [X] 报警复位
  71 + - [X] 强制关键帧
  72 + - [X] 拉框放大
  73 + - [X] 拉框缩小
  74 + - [X] 看守位控制
75 - [ ] 设备配置 75 - [ ] 设备配置
76 - [ ] 报警事件通知和分发 76 - [ ] 报警事件通知和分发
77 - [X] 设备目录订阅 77 - [X] 设备目录订阅
@@ -79,7 +79,7 @@ @@ -79,7 +79,7 @@
79 - [X] 设备目录查询 79 - [X] 设备目录查询
80 - [X] 设备状态查询 80 - [X] 设备状态查询
81 - [ ] 设备配置查询 81 - [ ] 设备配置查询
82 - - [ ] 设备预置位查询 82 + - [X] 设备预置位查询
83 - [X] 状态信息报送 83 - [X] 状态信息报送
84 - [X] 设备视音频文件检索 84 - [X] 设备视音频文件检索
85 - [X] 历史视音频的回放 85 - [X] 历史视音频的回放
@@ -87,7 +87,7 @@ @@ -87,7 +87,7 @@
87 - [x] 暂停 87 - [x] 暂停
88 - [x] 进/退 88 - [x] 进/退
89 - [x] 停止 89 - [x] 停止
90 -- [ ] 视音频文件下载 90 +- [X] 视音频文件下载
91 - [ ] ~~校时~~ 91 - [ ] ~~校时~~
92 - [X] 订阅和通知 92 - [X] 订阅和通知
93 - [X] 事件订阅 93 - [X] 事件订阅
doc/_content/introduction/config.md
@@ -29,10 +29,53 @@ java -jar wvp-pro-*.jar @@ -29,10 +29,53 @@ java -jar wvp-pro-*.jar
29 ``` 29 ```
30 这也是我自己最常用的方式。 30 这也是我自己最常用的方式。
31 ## 2 配置WVP-PRO 31 ## 2 配置WVP-PRO
32 -### 2.1 Mysql数据库配置  
33 -首先你需要创建一个名为wvp(也可使用其他名字)的数据库,并使用sql/mysql.sql导入数据库,初始化数据库结构。  
34 -(这里注意,取决于版本,新版的sql文件夹下有update.sql,补丁包,一定要注意运行导入)  
35 -在application-dev.yml中配置(使用1.2方式的是在jar包的同级目录的application.yml)配置数据库连接,包括数据库连接信息,密码。 32 +wvp支持多种数据库,包括Mysql,Postgresql,金仓等,配置任选一种即可。
  33 +### 2.1 数据库配置
  34 +#### 2.1.1 初始化数据库
  35 +首先使用创建数据库,然后使用sql/初始化.sql初始化数据库,如果是从旧版升级上来的,使用升级sql更新。
  36 +#### 2.1.2 Mysql数据库配置
  37 +数据库名称以wvp为例
  38 +```yaml
  39 +spring:
  40 + datasource:
  41 + type: com.zaxxer.hikari.HikariDataSource
  42 + driver-class-name: com.mysql.cj.jdbc.Driver
  43 + url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true
  44 + username: root
  45 + password: 12345678
  46 +
  47 +mybatis:
  48 + configuration:
  49 + map-underscore-to-camel-case: true
  50 +```
  51 +#### 2.1.3 Postgresql数据库配置
  52 +数据库名称以wvp为例
  53 +```yaml
  54 +spring:
  55 + datasource:
  56 + type: com.zaxxer.hikari.HikariDataSource
  57 + driver-class-name: org.postgresql.Driver
  58 + url: jdbc:postgresql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true
  59 + username: root
  60 + password: 12345678
  61 +
  62 +pagehelper:
  63 + helper-dialect: postgresql
  64 +```
  65 +#### 2.1.4 金仓数据库配置
  66 +数据库名称以wvp为例
  67 +```yaml
  68 +spring:
  69 + datasource:
  70 + type: com.zaxxer.hikari.HikariDataSource
  71 + driver-class-name: com.kingbase8.Driver
  72 + url: jdbc:kingbase8://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=utf8
  73 + username: root
  74 + password: 12345678
  75 +
  76 +pagehelper:
  77 + helper-dialect: postgresql
  78 +```
36 ### 2.2 Redis数据库配置 79 ### 2.2 Redis数据库配置
37 配置wvp中的redis连接信息,建议wvp自己单独使用一个db。 80 配置wvp中的redis连接信息,建议wvp自己单独使用一个db。
38 ### 2.3 配置服务启动端口(可直接使用默认配置) 81 ### 2.3 配置服务启动端口(可直接使用默认配置)
doc/_media/1372762149.jpg 0 → 100644

126 KB

doc/_media/903207146.jpg 0 → 100644

131 KB

doc/_media/logo.jpg 0 → 100644

102 KB

doc/index.html
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
7 <meta name="description" content="Description"> 7 <meta name="description" content="Description">
8 <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0"> 8 <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
9 <link rel="icon" href="_media/favicon.ico" type="image/x-icon" /> 9 <link rel="icon" href="_media/favicon.ico" type="image/x-icon" />
10 - <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/vue.css"> 10 + <link rel="stylesheet" href="./lib/css/vue.css">
11 <!-- <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify/lib/themes/dark.css">--> 11 <!-- <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify/lib/themes/dark.css">-->
12 <style> 12 <style>
13 .cover{ 13 .cover{
@@ -47,11 +47,11 @@ @@ -47,11 +47,11 @@
47 } 47 }
48 </script> 48 </script>
49 <!-- Docsify v4 --> 49 <!-- Docsify v4 -->
50 - <script src="//cdn.jsdelivr.net/npm/docsify@4"></script>  
51 - <script src="//unpkg.com/docsify-plantuml/dist/docsify-plantuml.min.js"></script>  
52 - <script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js"></script>  
53 - <script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/zoom-image.min.js"></script>  
54 - <script src="//cdn.jsdelivr.net/npm/docsify-copy-code/dist/docsify-copy-code.min.js"></script> 50 + <script src="./lib/js/docsify@4.js"></script>
  51 + <script src="./lib/js/docsify-plantuml.min.js"></script>
  52 + <script src="./lib/js/search.min.js"></script>
  53 + <script src="./lib/js/zoom-image.min.js"></script>
  54 + <script src="./lib/js/docsify-copy-code.min.js"></script>
55 55
56 </script> 56 </script>
57 <!-- <script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/disqus.min.js"></script>--> 57 <!-- <script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/disqus.min.js"></script>-->
doc/lib/css/vue.css 0 → 100644
  1 +@import url("https://fonts.googleapis.com/css?family=Roboto+Mono|Source+Sans+Pro:300,400,600");*{-webkit-font-smoothing:antialiased;-webkit-overflow-scrolling:touch;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-text-size-adjust:none;-webkit-touch-callout:none;box-sizing:border-box}body:not(.ready){overflow:hidden}body:not(.ready) .app-nav,body:not(.ready)>nav,body:not(.ready) [data-cloak]{display:none}div#app{font-size:30px;font-weight:lighter;margin:40vh auto;text-align:center}div#app:empty:before{content:"Loading..."}img.emoji{height:1.2em}img.emoji,span.emoji{vertical-align:middle}span.emoji{font-family:Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:1.2em}.progress{background-color:#42b983;background-color:var(--theme-color,#42b983);height:2px;left:0;position:fixed;right:0;top:0;transition:width .2s,opacity .4s;width:0;z-index:999999}.search .search-keyword,.search a:hover{color:#42b983;color:var(--theme-color,#42b983)}.search .search-keyword{font-style:normal;font-weight:700}body,html{height:100%}body{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;color:#34495e;font-family:Source Sans Pro,Helvetica Neue,Arial,sans-serif;font-size:15px;letter-spacing:0;margin:0;overflow-x:hidden}img{max-width:100%}a[disabled]{cursor:not-allowed;opacity:.6}kbd{border:1px solid #ccc;border-radius:3px;display:inline-block;font-size:12px!important;line-height:12px;margin-bottom:3px;padding:3px 5px;vertical-align:middle}li input[type=checkbox]{margin:0 .2em .25em 0;vertical-align:middle}.app-nav{margin:25px 60px 0 0;position:absolute;right:0;text-align:right;z-index:10}.app-nav.no-badge{margin-right:25px}.app-nav p{margin:0}.app-nav>a{margin:0 1rem;padding:5px 0}.app-nav li,.app-nav ul{display:inline-block;list-style:none;margin:0}.app-nav a{color:inherit;font-size:16px;text-decoration:none;transition:color .3s}.app-nav a.active,.app-nav a:hover{color:#42b983;color:var(--theme-color,#42b983)}.app-nav a.active{border-bottom:2px solid #42b983;border-bottom:2px solid var(--theme-color,#42b983)}.app-nav li{display:inline-block;margin:0 1rem;padding:5px 0;position:relative;cursor:pointer}.app-nav li ul{background-color:#fff;border:1px solid;border-color:#ddd #ddd #ccc;border-radius:4px;box-sizing:border-box;display:none;max-height:calc(100vh - 61px);overflow-y:auto;padding:10px 0;position:absolute;right:-15px;text-align:left;top:100%;white-space:nowrap}.app-nav li ul li{display:block;font-size:14px;line-height:1rem;margin:8px 14px;white-space:nowrap}.app-nav li ul a{display:block;font-size:inherit;margin:0;padding:0}.app-nav li ul a.active{border-bottom:0}.app-nav li:hover ul{display:block}.github-corner{border-bottom:0;position:fixed;right:0;text-decoration:none;top:0;z-index:1}.github-corner:hover .octo-arm{animation:octocat-wave .56s ease-in-out}.github-corner svg{color:#fff;fill:#42b983;fill:var(--theme-color,#42b983);height:80px;width:80px}main{display:block;position:relative;width:100vw;height:100%;z-index:0}main.hidden{display:none}.anchor{display:inline-block;text-decoration:none;transition:all .3s}.anchor span{color:#34495e}.anchor:hover{text-decoration:underline}.sidebar{border-right:1px solid rgba(0,0,0,.07);overflow-y:auto;padding:40px 0 0;position:absolute;top:0;bottom:0;left:0;transition:transform .25s ease-out;width:300px;z-index:20}.sidebar>h1{margin:0 auto 1rem;font-size:1.5rem;font-weight:300;text-align:center}.sidebar>h1 a{color:inherit;text-decoration:none}.sidebar>h1 .app-nav{display:block;position:static}.sidebar .sidebar-nav{line-height:2em;padding-bottom:40px}.sidebar li.collapse .app-sub-sidebar{display:none}.sidebar ul{margin:0 0 0 15px;padding:0}.sidebar li>p{font-weight:700;margin:0}.sidebar ul,.sidebar ul li{list-style:none}.sidebar ul li a{border-bottom:none;display:block}.sidebar ul li ul{padding-left:20px}.sidebar::-webkit-scrollbar{width:4px}.sidebar::-webkit-scrollbar-thumb{background:transparent;border-radius:4px}.sidebar:hover::-webkit-scrollbar-thumb{background:hsla(0,0%,53.3%,.4)}.sidebar:hover::-webkit-scrollbar-track{background:hsla(0,0%,53.3%,.1)}.sidebar-toggle{background-color:transparent;background-color:hsla(0,0%,100%,.8);border:0;outline:none;padding:10px;position:absolute;bottom:0;left:0;text-align:center;transition:opacity .3s;width:284px;z-index:30;cursor:pointer}.sidebar-toggle:hover .sidebar-toggle-button{opacity:.4}.sidebar-toggle span{background-color:#42b983;background-color:var(--theme-color,#42b983);display:block;margin-bottom:4px;width:16px;height:2px}body.sticky .sidebar,body.sticky .sidebar-toggle{position:fixed}.content{padding-top:60px;position:absolute;top:0;right:0;bottom:0;left:300px;transition:left .25s ease}.markdown-section{margin:0 auto;max-width:80%;padding:30px 15px 40px;position:relative}.markdown-section>*{box-sizing:border-box;font-size:inherit}.markdown-section>:first-child{margin-top:0!important}.markdown-section hr{border:none;border-bottom:1px solid #eee;margin:2em 0}.markdown-section iframe{border:1px solid #eee;width:1px;min-width:100%}.markdown-section table{border-collapse:collapse;border-spacing:0;display:block;margin-bottom:1rem;overflow:auto;width:100%}.markdown-section th{font-weight:700}.markdown-section td,.markdown-section th{border:1px solid #ddd;padding:6px 13px}.markdown-section tr{border-top:1px solid #ccc}.markdown-section p.tip,.markdown-section tr:nth-child(2n){background-color:#f8f8f8}.markdown-section p.tip{border-bottom-right-radius:2px;border-left:4px solid #f66;border-top-right-radius:2px;margin:2em 0;padding:12px 24px 12px 30px;position:relative}.markdown-section p.tip:before{background-color:#f66;border-radius:100%;color:#fff;content:"!";font-family:Dosis,Source Sans Pro,Helvetica Neue,Arial,sans-serif;font-size:14px;font-weight:700;left:-12px;line-height:20px;position:absolute;height:20px;width:20px;text-align:center;top:14px}.markdown-section p.tip code{background-color:#efefef}.markdown-section p.tip em{color:#34495e}.markdown-section p.warn{background:rgba(66,185,131,.1);border-radius:2px;padding:1rem}.markdown-section ul.task-list>li{list-style-type:none}body.close .sidebar{transform:translateX(-300px)}body.close .sidebar-toggle{width:auto}body.close .content{left:0}@media print{.app-nav,.github-corner,.sidebar,.sidebar-toggle{display:none}}@media screen and (max-width:768px){.github-corner,.sidebar,.sidebar-toggle{position:fixed}.app-nav{margin-top:16px}.app-nav li ul{top:30px}main{height:auto;min-height:100vh;overflow-x:hidden}.sidebar{left:-300px;transition:transform .25s ease-out}.content{left:0;max-width:100vw;position:static;padding-top:20px;transition:transform .25s ease}.app-nav,.github-corner{transition:transform .25s ease-out}.sidebar-toggle{background-color:transparent;width:auto;padding:30px 30px 10px 10px}body.close .sidebar{transform:translateX(300px)}body.close .sidebar-toggle{background-color:hsla(0,0%,100%,.8);transition:background-color 1s;width:284px;padding:10px}body.close .content{transform:translateX(300px)}body.close .app-nav,body.close .github-corner{display:none}.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave .56s ease-in-out}}@keyframes octocat-wave{0%,to{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}section.cover{position:relative;align-items:center;background-position:50%;background-repeat:no-repeat;background-size:cover;min-height:100vh;width:100%;display:none}section.cover.show{display:flex}section.cover.has-mask .mask{background-color:#fff;opacity:.8;position:absolute;top:0;bottom:0;width:100%}section.cover .cover-main{flex:1;margin:0 16px;text-align:center;position:relative}section.cover a{color:inherit}section.cover a,section.cover a:hover{text-decoration:none}section.cover p{line-height:1.5rem;margin:1em 0}section.cover h1{color:inherit;font-size:2.5rem;font-weight:300;margin:.625rem 0 2.5rem;position:relative;text-align:center}section.cover h1 a{display:block}section.cover h1 small{bottom:-.4375rem;font-size:1rem;position:absolute}section.cover blockquote{font-size:1.5rem;text-align:center}section.cover ul{line-height:1.8;list-style-type:none;margin:1em auto;max-width:500px;padding:0}section.cover .cover-main>p:last-child a{border-radius:2rem;border:1px solid #42b983;border-color:var(--theme-color,#42b983);box-sizing:border-box;color:#42b983;color:var(--theme-color,#42b983);display:inline-block;font-size:1.05rem;letter-spacing:.1rem;margin:.5rem 1rem;padding:.75em 2rem;text-decoration:none;transition:all .15s ease}section.cover .cover-main>p:last-child a:last-child{background-color:#42b983;background-color:var(--theme-color,#42b983);color:#fff}section.cover .cover-main>p:last-child a:last-child:hover{color:inherit;opacity:.8}section.cover .cover-main>p:last-child a:hover{color:inherit}section.cover blockquote>p>a{border-bottom:2px solid #42b983;border-bottom:2px solid var(--theme-color,#42b983);transition:color .3s}section.cover blockquote>p>a:hover{color:#42b983;color:var(--theme-color,#42b983)}.sidebar,body{background-color:#fff}.sidebar{color:#364149}.sidebar li{margin:6px 0}.sidebar ul li a{color:#505d6b;font-size:14px;font-weight:400;overflow:hidden;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.sidebar ul li a:hover{text-decoration:underline}.sidebar ul li ul{padding:0}.sidebar ul li.active>a{border-right:2px solid;color:#42b983;color:var(--theme-color,#42b983);font-weight:600}.app-sub-sidebar li:before{content:"-";padding-right:4px;float:left}.markdown-section h1,.markdown-section h2,.markdown-section h3,.markdown-section h4,.markdown-section strong{color:#2c3e50;font-weight:600}.markdown-section a{color:#42b983;color:var(--theme-color,#42b983);font-weight:600}.markdown-section h1{font-size:2rem;margin:0 0 1rem}.markdown-section h2{font-size:1.75rem;margin:45px 0 .8rem}.markdown-section h3{font-size:1.5rem;margin:40px 0 .6rem}.markdown-section h4{font-size:1.25rem}.markdown-section h5{font-size:1rem}.markdown-section h6{color:#777;font-size:1rem}.markdown-section figure,.markdown-section p{margin:1.2em 0}.markdown-section ol,.markdown-section p,.markdown-section ul{line-height:1.6rem;word-spacing:.05rem}.markdown-section ol,.markdown-section ul{padding-left:1.5rem}.markdown-section blockquote{border-left:4px solid #42b983;border-left:4px solid var(--theme-color,#42b983);color:#858585;margin:2em 0;padding-left:20px}.markdown-section blockquote p{font-weight:600;margin-left:0}.markdown-section iframe{margin:1em 0}.markdown-section em{color:#7f8c8d}.markdown-section code,.markdown-section output:after,.markdown-section pre{font-family:Roboto Mono,Monaco,courier,monospace}.markdown-section code,.markdown-section pre{background-color:#f8f8f8}.markdown-section output,.markdown-section pre{margin:1.2em 0;position:relative}.markdown-section output,.markdown-section pre>code{border-radius:2px;display:block}.markdown-section output:after,.markdown-section pre>code{-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial}.markdown-section code{border-radius:2px;color:#e96900;margin:0 2px;padding:3px 5px;white-space:pre-wrap}.markdown-section>:not(h1):not(h2):not(h3):not(h4):not(h5):not(h6) code{font-size:.8rem}.markdown-section pre{padding:0 1.4rem;line-height:1.5rem;overflow:auto;word-wrap:normal}.markdown-section pre>code{color:#525252;font-size:.8rem;padding:2.2em 5px;line-height:inherit;margin:0 2px;max-width:inherit;overflow:inherit;white-space:inherit}.markdown-section output{padding:1.7rem 1.4rem;border:1px dotted #ccc}.markdown-section output>:first-child{margin-top:0}.markdown-section output>:last-child{margin-bottom:0}.markdown-section code:after,.markdown-section code:before,.markdown-section output:after,.markdown-section output:before{letter-spacing:.05rem}.markdown-section output:after,.markdown-section pre:after{color:#ccc;font-size:.6rem;font-weight:600;height:15px;line-height:15px;padding:5px 10px 0;position:absolute;right:0;text-align:right;top:0;content:attr(data-lang)}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#8e908c}.token.namespace{opacity:.7}.token.boolean,.token.number{color:#c76b29}.token.punctuation{color:#525252}.token.property{color:#c08b30}.token.tag{color:#2973b7}.token.string{color:#42b983;color:var(--theme-color,#42b983)}.token.selector{color:#6679cc}.token.attr-name{color:#2973b7}.language-css .token.string,.style .token.string,.token.entity,.token.url{color:#22a2c9}.token.attr-value,.token.control,.token.directive,.token.unit{color:#42b983;color:var(--theme-color,#42b983)}.token.function,.token.keyword{color:#e96900}.token.atrule,.token.regex,.token.statement{color:#22a2c9}.token.placeholder,.token.variable{color:#3d8fd1}.token.deleted{text-decoration:line-through}.token.inserted{border-bottom:1px dotted #202746;text-decoration:none}.token.italic{font-style:italic}.token.bold,.token.important{font-weight:700}.token.important{color:#c94922}.token.entity{cursor:help}code .token{-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;min-height:1.5rem;position:relative;left:auto}
0 \ No newline at end of file 2 \ No newline at end of file
doc/lib/js/docsify-copy-code.min.js 0 → 100644
  1 +/*!
  2 + * docsify-copy-code
  3 + * v2.1.1
  4 + * https://github.com/jperasmus/docsify-copy-code
  5 + * (c) 2017-2020 JP Erasmus <jperasmus11@gmail.com>
  6 + * MIT license
  7 + */
  8 +!function(){"use strict";function s(o){return(s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o})(o)}!function(o,e){void 0===e&&(e={});var t=e.insertAt;if(o&&"undefined"!=typeof document){var n=document.head||document.getElementsByTagName("head")[0],c=document.createElement("style");c.type="text/css","top"===t&&n.firstChild?n.insertBefore(c,n.firstChild):n.appendChild(c),c.styleSheet?c.styleSheet.cssText=o:c.appendChild(document.createTextNode(o))}}(".docsify-copy-code-button,.docsify-copy-code-button span{cursor:pointer;transition:all .25s ease}.docsify-copy-code-button{position:absolute;z-index:1;top:0;right:0;overflow:visible;padding:.65em .8em;border:0;border-radius:0;outline:0;font-size:1em;background:grey;background:var(--theme-color,grey);color:#fff;opacity:0}.docsify-copy-code-button span{border-radius:3px;background:inherit;pointer-events:none}.docsify-copy-code-button .error,.docsify-copy-code-button .success{position:absolute;z-index:-100;top:50%;right:0;padding:.5em .65em;font-size:.825em;opacity:0;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.docsify-copy-code-button.error .error,.docsify-copy-code-button.success .success{right:100%;opacity:1;-webkit-transform:translate(-115%,-50%);transform:translate(-115%,-50%)}.docsify-copy-code-button:focus,pre:hover .docsify-copy-code-button{opacity:1}"),document.querySelector('link[href*="docsify-copy-code"]')&&console.warn("[Deprecation] Link to external docsify-copy-code stylesheet is no longer necessary."),window.DocsifyCopyCodePlugin={init:function(){return function(o,e){o.ready(function(){console.warn("[Deprecation] Manually initializing docsify-copy-code using window.DocsifyCopyCodePlugin.init() is no longer necessary.")})}}},window.$docsify=window.$docsify||{},window.$docsify.plugins=[function(o,r){o.doneEach(function(){var o=Array.apply(null,document.querySelectorAll("pre[data-lang]")),c={buttonText:"Copy to clipboard",errorText:"Error",successText:"Copied"};r.config.copyCode&&Object.keys(c).forEach(function(t){var n=r.config.copyCode[t];"string"==typeof n?c[t]=n:"object"===s(n)&&Object.keys(n).some(function(o){var e=-1<location.href.indexOf(o);return c[t]=e?n[o]:c[t],e})});var e=['<button class="docsify-copy-code-button">','<span class="label">'.concat(c.buttonText,"</span>"),'<span class="error">'.concat(c.errorText,"</span>"),'<span class="success">'.concat(c.successText,"</span>"),"</button>"].join("");o.forEach(function(o){o.insertAdjacentHTML("beforeend",e)})}),o.mounted(function(){document.querySelector(".content").addEventListener("click",function(o){if(o.target.classList.contains("docsify-copy-code-button")){var e="BUTTON"===o.target.tagName?o.target:o.target.parentNode,t=document.createRange(),n=e.parentNode.querySelector("code"),c=window.getSelection();t.selectNode(n),c.removeAllRanges(),c.addRange(t);try{document.execCommand("copy")&&(e.classList.add("success"),setTimeout(function(){e.classList.remove("success")},1e3))}catch(o){console.error("docsify-copy-code: ".concat(o)),e.classList.add("error"),setTimeout(function(){e.classList.remove("error")},1e3)}"function"==typeof(c=window.getSelection()).removeRange?c.removeRange(t):"function"==typeof c.removeAllRanges&&c.removeAllRanges()}})})}].concat(window.$docsify.plugins||[])}();
  9 +//# sourceMappingURL=docsify-copy-code.min.js.map
doc/lib/js/docsify-plantuml.min.js 0 → 100644
  1 +!function(t){function e(a){if(n[a])return n[a].exports;var r=n[a]={i:a,l:!1,exports:{}};return t[a].call(r.exports,r,r.exports,e),r.l=!0,r.exports}var n={};e.m=t,e.c=n,e.d=function(t,n,a){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:a})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=0)}([function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=n(1);window.$docsify||(window.$docsify={}),window.$docsify.plugins=(window.$docsify.plugins||[]).concat(a.a)},function(t,e,n){"use strict";function a(t,e){var t=Object(o.a)(e.skin)+t,n=e.serverPath||"//www.plantuml.com/plantuml/svg/";if(e.renderSvgAsObject){var a=n+Object(l.encode)(r(t));return'<object type="image/svg+xml" data="'+a+'" />'}var a=n+Object(l.encode)(t);return'<img src="'+a+'" />'}function r(t){function e(t,e){for(var n=(a+e).split("/"),r=[],i=0,s=n.length;i<s;i++){var o=n[i];".."===o?r.pop():"."!==o&&r.push(o)}return"[["+r.join("/")}var n=window.location.toString(),a=n.substring(0,n.lastIndexOf("/")+1);return t.replace(/\[\[\$((?:\.?\.\/)*)/g,e)}function i(t,e,n){var r=window.Docsify.dom,i=r.create("span",t);return i.querySelectorAll?((r.findAll(i,e)||[]).forEach(function(t){var e=t.parentNode,i=r.create("p",a(t.innerText,n));e&&(i.dataset.lang=h,t.parentNode.replaceChild(i,t))}),i.innerHTML):t}function s(t,e){const n=Object.assign({},{skin:"default",renderSvgAsObject:!1},e.config.plantuml);t.afterEach(function(t){return i(t,d,n)})}e.a=s;var o=n(2),l=n(5),h=(n.n(l),"plantuml"),d='pre[data-lang="'+h+'"]'},function(t,e,n){"use strict";function a(t){return t in l?l[t]:(console.warn("[Docsify-PlantUML] Invalid skin name: "+t),l[h])}e.a=a;var r=n(3),i=n.n(r),s=n(4),o=n.n(s);const l={default:i.a,classic:o.a},h="default"},function(t,e){t.exports="' fork from https://github.com/matthewjosephtaylor/plantuml-style/blob/master/style.pu\n' Not-ugly plantuml style defaults\n\nskinparam defaultFontName Helvetica\nskinparam defaultFontSize 12\nskinparam sequenceMessageAlign center\nskinparam monochrome true\nskinparam shadowing false\n\nskinparam activity {\n\tArrowColor Black\n\tBackgroundColor White\n\tBorderColor Black\n\tBorderThickness 1\n}\n\nskinparam actor {\n\tBackgroundColor White\n\tBorderColor Black\n}\n\nskinparam usecase {\n\tArrowColor Black\n\tBackgroundColor White\n\tBorderColor Black\n\tBorderThickness 1\n}\n\nskinparam class {\n\tArrowColor Black\n\tBackgroundColor White\n\tBorderColor Black\n\tBorderThickness 1\n}\n\n\nskinparam object {\n\tArrowColor Black\n\tBackgroundColor White\n\tBorderColor Black\n}\n\nskinparam package {\n\tBackgroundColor White\n\tBorderColor Black\n}\n\n'TODO stereotype\n\nskinparam component {\n\tBackgroundColor White\n\tInterfaceBackgroundColor White\n\tBorderColor Black\n\tInterfaceBorderColor Black\n}\n\nskinparam note {\n\tBackgroundColor White\n\tBorderColor Black\n}\n\nskinparam state {\n\tArrowColor Black\n\tBackgroundColor White\n\tBorderColor Black\n}\n\nskinparam sequence {\n\tArrowColor Black\n\tBackgroundColor White\n\tParticipantBackgroundColor White\n\tBorderColor Black\n\tLifeLineBorderColor Black\n\tParticipantBorderColor Black\n\tBoxLineColor Black\n}\n\nskinparam interface {\n\tBackgroundColor White\n\tBorderColor Black\n}\n"},function(t,e){t.exports=""},function(t,e,n){t.exports={encode:n(6).encode,decode:n(7).decode}},function(t,e,n){var a,a;!function(e){t.exports=e()}(function(){return function(){function t(e,n,r){function i(o,l){if(!n[o]){if(!e[o]){var h="function"==typeof a&&a;if(!l&&h)return a(o,!0);if(s)return s(o,!0);var d=new Error("Cannot find module '"+o+"'");throw d.code="MODULE_NOT_FOUND",d}var f=n[o]={exports:{}};e[o][0].call(f.exports,function(t){return i(e[o][1][t]||t)},f,f.exports,t,e,n,r)}return n[o].exports}for(var s="function"==typeof a&&a,o=0;o<r.length;o++)i(r[o]);return i}return t}()({1:[function(t,e,n){"use strict";var a=t("pako/lib/deflate.js");e.exports=function(t){return a.deflateRaw(t,{level:9,to:"string"})}},{"pako/lib/deflate.js":4}],2:[function(t,e,n){"use strict";function a(t){return t<10?String.fromCharCode(48+t):(t-=10)<26?String.fromCharCode(65+t):(t-=26)<26?String.fromCharCode(97+t):(t-=26,0===t?"-":1===t?"_":"?")}function r(t,e,n){var r=t>>2,i=(3&t)<<4|e>>4,s=(15&e)<<2|n>>6,o=63&n,l="";return l+=a(63&r),l+=a(63&i),l+=a(63&s),l+=a(63&o)}e.exports=function(t){for(var e="",n=0;n<t.length;n+=3)n+2===t.length?e+=r(t.charCodeAt(n),t.charCodeAt(n+1),0):n+1===t.length?e+=r(t.charCodeAt(n),0,0):e+=r(t.charCodeAt(n),t.charCodeAt(n+1),t.charCodeAt(n+2));return e}},{}],3:[function(t,e,n){"use strict";var a=t("./deflate"),r=t("./encode64");e.exports.encode=function(t){var e=a(t);return r(e)}},{"./deflate":1,"./encode64":2}],4:[function(t,e,n){"use strict";function a(t){if(!(this instanceof a))return new a(t);this.options=l.assign({level:_,method:p,chunkSize:16384,windowBits:15,memLevel:8,strategy:g,to:""},t||{});var e=this.options;e.raw&&e.windowBits>0?e.windowBits=-e.windowBits:e.gzip&&e.windowBits>0&&e.windowBits<16&&(e.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new f,this.strm.avail_out=0;var n=o.deflateInit2(this.strm,e.level,e.method,e.windowBits,e.memLevel,e.strategy);if(n!==c)throw new Error(d[n]);if(e.header&&o.deflateSetHeader(this.strm,e.header),e.dictionary){var r;if(r="string"==typeof e.dictionary?h.string2buf(e.dictionary):"[object ArrayBuffer]"===u.call(e.dictionary)?new Uint8Array(e.dictionary):e.dictionary,(n=o.deflateSetDictionary(this.strm,r))!==c)throw new Error(d[n]);this._dict_set=!0}}function r(t,e){var n=new a(e);if(n.push(t,!0),n.err)throw n.msg||d[n.err];return n.result}function i(t,e){return e=e||{},e.raw=!0,r(t,e)}function s(t,e){return e=e||{},e.gzip=!0,r(t,e)}var o=t("./zlib/deflate"),l=t("./utils/common"),h=t("./utils/strings"),d=t("./zlib/messages"),f=t("./zlib/zstream"),u=Object.prototype.toString,c=0,_=-1,g=0,p=8;a.prototype.push=function(t,e){var n,a,r=this.strm,i=this.options.chunkSize;if(this.ended)return!1;a=e===~~e?e:!0===e?4:0,"string"==typeof t?r.input=h.string2buf(t):"[object ArrayBuffer]"===u.call(t)?r.input=new Uint8Array(t):r.input=t,r.next_in=0,r.avail_in=r.input.length;do{if(0===r.avail_out&&(r.output=new l.Buf8(i),r.next_out=0,r.avail_out=i),1!==(n=o.deflate(r,a))&&n!==c)return this.onEnd(n),this.ended=!0,!1;0!==r.avail_out&&(0!==r.avail_in||4!==a&&2!==a)||("string"===this.options.to?this.onData(h.buf2binstring(l.shrinkBuf(r.output,r.next_out))):this.onData(l.shrinkBuf(r.output,r.next_out)))}while((r.avail_in>0||0===r.avail_out)&&1!==n);return 4===a?(n=o.deflateEnd(this.strm),this.onEnd(n),this.ended=!0,n===c):2!==a||(this.onEnd(c),r.avail_out=0,!0)},a.prototype.onData=function(t){this.chunks.push(t)},a.prototype.onEnd=function(t){t===c&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=l.flattenChunks(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg},n.Deflate=a,n.deflate=r,n.deflateRaw=i,n.gzip=s},{"./utils/common":5,"./utils/strings":6,"./zlib/deflate":9,"./zlib/messages":10,"./zlib/zstream":12}],5:[function(t,e,n){"use strict";function a(t,e){return Object.prototype.hasOwnProperty.call(t,e)}var r="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;n.assign=function(t){for(var e=Array.prototype.slice.call(arguments,1);e.length;){var n=e.shift();if(n){if("object"!=typeof n)throw new TypeError(n+"must be non-object");for(var r in n)a(n,r)&&(t[r]=n[r])}}return t},n.shrinkBuf=function(t,e){return t.length===e?t:t.subarray?t.subarray(0,e):(t.length=e,t)};var i={arraySet:function(t,e,n,a,r){if(e.subarray&&t.subarray)return void t.set(e.subarray(n,n+a),r);for(var i=0;i<a;i++)t[r+i]=e[n+i]},flattenChunks:function(t){var e,n,a,r,i,s;for(a=0,e=0,n=t.length;e<n;e++)a+=t[e].length;for(s=new Uint8Array(a),r=0,e=0,n=t.length;e<n;e++)i=t[e],s.set(i,r),r+=i.length;return s}},s={arraySet:function(t,e,n,a,r){for(var i=0;i<a;i++)t[r+i]=e[n+i]},flattenChunks:function(t){return[].concat.apply([],t)}};n.setTyped=function(t){t?(n.Buf8=Uint8Array,n.Buf16=Uint16Array,n.Buf32=Int32Array,n.assign(n,i)):(n.Buf8=Array,n.Buf16=Array,n.Buf32=Array,n.assign(n,s))},n.setTyped(r)},{}],6:[function(t,e,n){"use strict";function a(t,e){if(e<65534&&(t.subarray&&s||!t.subarray&&i))return String.fromCharCode.apply(null,r.shrinkBuf(t,e));for(var n="",a=0;a<e;a++)n+=String.fromCharCode(t[a]);return n}var r=t("./common"),i=!0,s=!0;try{String.fromCharCode.apply(null,[0])}catch(t){i=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(t){s=!1}for(var o=new r.Buf8(256),l=0;l<256;l++)o[l]=l>=252?6:l>=248?5:l>=240?4:l>=224?3:l>=192?2:1;o[254]=o[254]=1,n.string2buf=function(t){var e,n,a,i,s,o=t.length,l=0;for(i=0;i<o;i++)n=t.charCodeAt(i),55296==(64512&n)&&i+1<o&&56320==(64512&(a=t.charCodeAt(i+1)))&&(n=65536+(n-55296<<10)+(a-56320),i++),l+=n<128?1:n<2048?2:n<65536?3:4;for(e=new r.Buf8(l),s=0,i=0;s<l;i++)n=t.charCodeAt(i),55296==(64512&n)&&i+1<o&&56320==(64512&(a=t.charCodeAt(i+1)))&&(n=65536+(n-55296<<10)+(a-56320),i++),n<128?e[s++]=n:n<2048?(e[s++]=192|n>>>6,e[s++]=128|63&n):n<65536?(e[s++]=224|n>>>12,e[s++]=128|n>>>6&63,e[s++]=128|63&n):(e[s++]=240|n>>>18,e[s++]=128|n>>>12&63,e[s++]=128|n>>>6&63,e[s++]=128|63&n);return e},n.buf2binstring=function(t){return a(t,t.length)},n.binstring2buf=function(t){for(var e=new r.Buf8(t.length),n=0,a=e.length;n<a;n++)e[n]=t.charCodeAt(n);return e},n.buf2string=function(t,e){var n,r,i,s,l=e||t.length,h=new Array(2*l);for(r=0,n=0;n<l;)if((i=t[n++])<128)h[r++]=i;else if((s=o[i])>4)h[r++]=65533,n+=s-1;else{for(i&=2===s?31:3===s?15:7;s>1&&n<l;)i=i<<6|63&t[n++],s--;s>1?h[r++]=65533:i<65536?h[r++]=i:(i-=65536,h[r++]=55296|i>>10&1023,h[r++]=56320|1023&i)}return a(h,r)},n.utf8border=function(t,e){var n;for(e=e||t.length,e>t.length&&(e=t.length),n=e-1;n>=0&&128==(192&t[n]);)n--;return n<0?e:0===n?e:n+o[t[n]]>e?n:e}},{"./common":5}],7:[function(t,e,n){"use strict";function a(t,e,n,a){for(var r=65535&t|0,i=t>>>16&65535|0,s=0;0!==n;){s=n>2e3?2e3:n,n-=s;do{r=r+e[a++]|0,i=i+r|0}while(--s);r%=65521,i%=65521}return r|i<<16|0}e.exports=a},{}],8:[function(t,e,n){"use strict";function a(t,e,n,a){var i=r,s=a+n;t^=-1;for(var o=a;o<s;o++)t=t>>>8^i[255&(t^e[o])];return-1^t}var r=function(){for(var t,e=[],n=0;n<256;n++){t=n;for(var a=0;a<8;a++)t=1&t?3988292384^t>>>1:t>>>1;e[n]=t}return e}();e.exports=a},{}],9:[function(t,e,n){"use strict";function a(t,e){return t.msg=D[e],e}function r(t){return(t<<1)-(t>4?9:0)}function i(t){for(var e=t.length;--e>=0;)t[e]=0}function s(t){var e=t.state,n=e.pending;n>t.avail_out&&(n=t.avail_out),0!==n&&(O.arraySet(t.output,e.pending_buf,e.pending_out,n,t.next_out),t.next_out+=n,e.pending_out+=n,t.total_out+=n,t.avail_out-=n,e.pending-=n,0===e.pending&&(e.pending_out=0))}function o(t,e){Z._tr_flush_block(t,t.block_start>=0?t.block_start:-1,t.strstart-t.block_start,e),t.block_start=t.strstart,s(t.strm)}function l(t,e){t.pending_buf[t.pending++]=e}function h(t,e){t.pending_buf[t.pending++]=e>>>8&255,t.pending_buf[t.pending++]=255&e}function d(t,e,n,a){var r=t.avail_in;return r>a&&(r=a),0===r?0:(t.avail_in-=r,O.arraySet(e,t.input,t.next_in,r,n),1===t.state.wrap?t.adler=N(t.adler,e,r,n):2===t.state.wrap&&(t.adler=R(t.adler,e,r,n)),t.next_in+=r,t.total_in+=r,r)}function f(t,e){var n,a,r=t.max_chain_length,i=t.strstart,s=t.prev_length,o=t.nice_match,l=t.strstart>t.w_size-ht?t.strstart-(t.w_size-ht):0,h=t.window,d=t.w_mask,f=t.prev,u=t.strstart+lt,c=h[i+s-1],_=h[i+s];t.prev_length>=t.good_match&&(r>>=2),o>t.lookahead&&(o=t.lookahead);do{if(n=e,h[n+s]===_&&h[n+s-1]===c&&h[n]===h[i]&&h[++n]===h[i+1]){i+=2,n++;do{}while(h[++i]===h[++n]&&h[++i]===h[++n]&&h[++i]===h[++n]&&h[++i]===h[++n]&&h[++i]===h[++n]&&h[++i]===h[++n]&&h[++i]===h[++n]&&h[++i]===h[++n]&&i<u);if(a=lt-(u-i),i=u-lt,a>s){if(t.match_start=e,s=a,a>=o)break;c=h[i+s-1],_=h[i+s]}}}while((e=f[e&d])>l&&0!=--r);return s<=t.lookahead?s:t.lookahead}function u(t){var e,n,a,r,i,s=t.w_size;do{if(r=t.window_size-t.lookahead-t.strstart,t.strstart>=s+(s-ht)){O.arraySet(t.window,t.window,s,s,0),t.match_start-=s,t.strstart-=s,t.block_start-=s,n=t.hash_size,e=n;do{a=t.head[--e],t.head[e]=a>=s?a-s:0}while(--n);n=s,e=n;do{a=t.prev[--e],t.prev[e]=a>=s?a-s:0}while(--n);r+=s}if(0===t.strm.avail_in)break;if(n=d(t.strm,t.window,t.strstart+t.lookahead,r),t.lookahead+=n,t.lookahead+t.insert>=ot)for(i=t.strstart-t.insert,t.ins_h=t.window[i],t.ins_h=(t.ins_h<<t.hash_shift^t.window[i+1])&t.hash_mask;t.insert&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[i+ot-1])&t.hash_mask,t.prev[i&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=i,i++,t.insert--,!(t.lookahead+t.insert<ot)););}while(t.lookahead<ht&&0!==t.strm.avail_in)}function c(t,e){var n=65535;for(n>t.pending_buf_size-5&&(n=t.pending_buf_size-5);;){if(t.lookahead<=1){if(u(t),0===t.lookahead&&e===I)return bt;if(0===t.lookahead)break}t.strstart+=t.lookahead,t.lookahead=0;var a=t.block_start+n;if((0===t.strstart||t.strstart>=a)&&(t.lookahead=t.strstart-a,t.strstart=a,o(t,!1),0===t.strm.avail_out))return bt;if(t.strstart-t.block_start>=t.w_size-ht&&(o(t,!1),0===t.strm.avail_out))return bt}return t.insert=0,e===j?(o(t,!0),0===t.strm.avail_out?vt:kt):(t.strstart>t.block_start&&(o(t,!1),t.strm.avail_out),bt)}function _(t,e){for(var n,a;;){if(t.lookahead<ht){if(u(t),t.lookahead<ht&&e===I)return bt;if(0===t.lookahead)break}if(n=0,t.lookahead>=ot&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+ot-1])&t.hash_mask,n=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),0!==n&&t.strstart-n<=t.w_size-ht&&(t.match_length=f(t,n)),t.match_length>=ot)if(a=Z._tr_tally(t,t.strstart-t.match_start,t.match_length-ot),t.lookahead-=t.match_length,t.match_length<=t.max_lazy_match&&t.lookahead>=ot){t.match_length--;do{t.strstart++,t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+ot-1])&t.hash_mask,n=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart}while(0!=--t.match_length);t.strstart++}else t.strstart+=t.match_length,t.match_length=0,t.ins_h=t.window[t.strstart],t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+1])&t.hash_mask;else a=Z._tr_tally(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++;if(a&&(o(t,!1),0===t.strm.avail_out))return bt}return t.insert=t.strstart<ot-1?t.strstart:ot-1,e===j?(o(t,!0),0===t.strm.avail_out?vt:kt):t.last_lit&&(o(t,!1),0===t.strm.avail_out)?bt:wt}function g(t,e){for(var n,a,r;;){if(t.lookahead<ht){if(u(t),t.lookahead<ht&&e===I)return bt;if(0===t.lookahead)break}if(n=0,t.lookahead>=ot&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+ot-1])&t.hash_mask,n=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),t.prev_length=t.match_length,t.prev_match=t.match_start,t.match_length=ot-1,0!==n&&t.prev_length<t.max_lazy_match&&t.strstart-n<=t.w_size-ht&&(t.match_length=f(t,n),t.match_length<=5&&(t.strategy===Y||t.match_length===ot&&t.strstart-t.match_start>4096)&&(t.match_length=ot-1)),t.prev_length>=ot&&t.match_length<=t.prev_length){r=t.strstart+t.lookahead-ot,a=Z._tr_tally(t,t.strstart-1-t.prev_match,t.prev_length-ot),t.lookahead-=t.prev_length-1,t.prev_length-=2;do{++t.strstart<=r&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+ot-1])&t.hash_mask,n=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart)}while(0!=--t.prev_length);if(t.match_available=0,t.match_length=ot-1,t.strstart++,a&&(o(t,!1),0===t.strm.avail_out))return bt}else if(t.match_available){if(a=Z._tr_tally(t,0,t.window[t.strstart-1]),a&&o(t,!1),t.strstart++,t.lookahead--,0===t.strm.avail_out)return bt}else t.match_available=1,t.strstart++,t.lookahead--}return t.match_available&&(a=Z._tr_tally(t,0,t.window[t.strstart-1]),t.match_available=0),t.insert=t.strstart<ot-1?t.strstart:ot-1,e===j?(o(t,!0),0===t.strm.avail_out?vt:kt):t.last_lit&&(o(t,!1),0===t.strm.avail_out)?bt:wt}function p(t,e){for(var n,a,r,i,s=t.window;;){if(t.lookahead<=lt){if(u(t),t.lookahead<=lt&&e===I)return bt;if(0===t.lookahead)break}if(t.match_length=0,t.lookahead>=ot&&t.strstart>0&&(r=t.strstart-1,(a=s[r])===s[++r]&&a===s[++r]&&a===s[++r])){i=t.strstart+lt;do{}while(a===s[++r]&&a===s[++r]&&a===s[++r]&&a===s[++r]&&a===s[++r]&&a===s[++r]&&a===s[++r]&&a===s[++r]&&r<i);t.match_length=lt-(i-r),t.match_length>t.lookahead&&(t.match_length=t.lookahead)}if(t.match_length>=ot?(n=Z._tr_tally(t,1,t.match_length-ot),t.lookahead-=t.match_length,t.strstart+=t.match_length,t.match_length=0):(n=Z._tr_tally(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++),n&&(o(t,!1),0===t.strm.avail_out))return bt}return t.insert=0,e===j?(o(t,!0),0===t.strm.avail_out?vt:kt):t.last_lit&&(o(t,!1),0===t.strm.avail_out)?bt:wt}function m(t,e){for(var n;;){if(0===t.lookahead&&(u(t),0===t.lookahead)){if(e===I)return bt;break}if(t.match_length=0,n=Z._tr_tally(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++,n&&(o(t,!1),0===t.strm.avail_out))return bt}return t.insert=0,e===j?(o(t,!0),0===t.strm.avail_out?vt:kt):t.last_lit&&(o(t,!1),0===t.strm.avail_out)?bt:wt}function b(t,e,n,a,r){this.good_length=t,this.max_lazy=e,this.nice_length=n,this.max_chain=a,this.func=r}function w(t){t.window_size=2*t.w_size,i(t.head),t.max_lazy_match=E[t.level].max_lazy,t.good_match=E[t.level].good_length,t.nice_match=E[t.level].nice_length,t.max_chain_length=E[t.level].max_chain,t.strstart=0,t.block_start=0,t.lookahead=0,t.insert=0,t.match_length=t.prev_length=ot-1,t.match_available=0,t.ins_h=0}function v(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=Q,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new O.Buf16(2*it),this.dyn_dtree=new O.Buf16(2*(2*at+1)),this.bl_tree=new O.Buf16(2*(2*rt+1)),i(this.dyn_ltree),i(this.dyn_dtree),i(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new O.Buf16(st+1),this.heap=new O.Buf16(2*nt+1),i(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new O.Buf16(2*nt+1),i(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function k(t){var e;return t&&t.state?(t.total_in=t.total_out=0,t.data_type=J,e=t.state,e.pending=0,e.pending_out=0,e.wrap<0&&(e.wrap=-e.wrap),e.status=e.wrap?ft:pt,t.adler=2===e.wrap?0:1,e.last_flush=I,Z._tr_init(e),L):a(t,M)}function y(t){var e=k(t);return e===L&&w(t.state),e}function x(t,e){return t&&t.state?2!==t.state.wrap?M:(t.state.gzhead=e,L):M}function z(t,e,n,r,i,s){if(!t)return M;var o=1;if(e===K&&(e=6),r<0?(o=0,r=-r):r>15&&(o=2,r-=16),i<1||i>V||n!==Q||r<8||r>15||e<0||e>9||s<0||s>G)return a(t,M);8===r&&(r=9);var l=new v;return t.state=l,l.strm=t,l.wrap=o,l.gzhead=null,l.w_bits=r,l.w_size=1<<l.w_bits,l.w_mask=l.w_size-1,l.hash_bits=i+7,l.hash_size=1<<l.hash_bits,l.hash_mask=l.hash_size-1,l.hash_shift=~~((l.hash_bits+ot-1)/ot),l.window=new O.Buf8(2*l.w_size),l.head=new O.Buf16(l.hash_size),l.prev=new O.Buf16(l.w_size),l.lit_bufsize=1<<i+6,l.pending_buf_size=4*l.lit_bufsize,l.pending_buf=new O.Buf8(l.pending_buf_size),l.d_buf=1*l.lit_bufsize,l.l_buf=3*l.lit_bufsize,l.level=e,l.strategy=s,l.method=n,y(t)}function B(t,e){return z(t,e,Q,tt,et,X)}function C(t,e){var n,o,d,f;if(!t||!t.state||e>F||e<0)return t?a(t,M):M;if(o=t.state,!t.output||!t.input&&0!==t.avail_in||o.status===mt&&e!==j)return a(t,0===t.avail_out?W:M);if(o.strm=t,n=o.last_flush,o.last_flush=e,o.status===ft)if(2===o.wrap)t.adler=0,l(o,31),l(o,139),l(o,8),o.gzhead?(l(o,(o.gzhead.text?1:0)+(o.gzhead.hcrc?2:0)+(o.gzhead.extra?4:0)+(o.gzhead.name?8:0)+(o.gzhead.comment?16:0)),l(o,255&o.gzhead.time),l(o,o.gzhead.time>>8&255),l(o,o.gzhead.time>>16&255),l(o,o.gzhead.time>>24&255),l(o,9===o.level?2:o.strategy>=$||o.level<2?4:0),l(o,255&o.gzhead.os),o.gzhead.extra&&o.gzhead.extra.length&&(l(o,255&o.gzhead.extra.length),l(o,o.gzhead.extra.length>>8&255)),o.gzhead.hcrc&&(t.adler=R(t.adler,o.pending_buf,o.pending,0)),o.gzindex=0,o.status=ut):(l(o,0),l(o,0),l(o,0),l(o,0),l(o,0),l(o,9===o.level?2:o.strategy>=$||o.level<2?4:0),l(o,yt),o.status=pt);else{var u=Q+(o.w_bits-8<<4)<<8,c=-1;c=o.strategy>=$||o.level<2?0:o.level<6?1:6===o.level?2:3,u|=c<<6,0!==o.strstart&&(u|=dt),u+=31-u%31,o.status=pt,h(o,u),0!==o.strstart&&(h(o,t.adler>>>16),h(o,65535&t.adler)),t.adler=1}if(o.status===ut)if(o.gzhead.extra){for(d=o.pending;o.gzindex<(65535&o.gzhead.extra.length)&&(o.pending!==o.pending_buf_size||(o.gzhead.hcrc&&o.pending>d&&(t.adler=R(t.adler,o.pending_buf,o.pending-d,d)),s(t),d=o.pending,o.pending!==o.pending_buf_size));)l(o,255&o.gzhead.extra[o.gzindex]),o.gzindex++;o.gzhead.hcrc&&o.pending>d&&(t.adler=R(t.adler,o.pending_buf,o.pending-d,d)),o.gzindex===o.gzhead.extra.length&&(o.gzindex=0,o.status=ct)}else o.status=ct;if(o.status===ct)if(o.gzhead.name){d=o.pending;do{if(o.pending===o.pending_buf_size&&(o.gzhead.hcrc&&o.pending>d&&(t.adler=R(t.adler,o.pending_buf,o.pending-d,d)),s(t),d=o.pending,o.pending===o.pending_buf_size)){f=1;break}f=o.gzindex<o.gzhead.name.length?255&o.gzhead.name.charCodeAt(o.gzindex++):0,l(o,f)}while(0!==f);o.gzhead.hcrc&&o.pending>d&&(t.adler=R(t.adler,o.pending_buf,o.pending-d,d)),0===f&&(o.gzindex=0,o.status=_t)}else o.status=_t;if(o.status===_t)if(o.gzhead.comment){d=o.pending;do{if(o.pending===o.pending_buf_size&&(o.gzhead.hcrc&&o.pending>d&&(t.adler=R(t.adler,o.pending_buf,o.pending-d,d)),s(t),d=o.pending,o.pending===o.pending_buf_size)){f=1;break}f=o.gzindex<o.gzhead.comment.length?255&o.gzhead.comment.charCodeAt(o.gzindex++):0,l(o,f)}while(0!==f);o.gzhead.hcrc&&o.pending>d&&(t.adler=R(t.adler,o.pending_buf,o.pending-d,d)),0===f&&(o.status=gt)}else o.status=gt;if(o.status===gt&&(o.gzhead.hcrc?(o.pending+2>o.pending_buf_size&&s(t),o.pending+2<=o.pending_buf_size&&(l(o,255&t.adler),l(o,t.adler>>8&255),t.adler=0,o.status=pt)):o.status=pt),0!==o.pending){if(s(t),0===t.avail_out)return o.last_flush=-1,L}else if(0===t.avail_in&&r(e)<=r(n)&&e!==j)return a(t,W);if(o.status===mt&&0!==t.avail_in)return a(t,W);if(0!==t.avail_in||0!==o.lookahead||e!==I&&o.status!==mt){var _=o.strategy===$?m(o,e):o.strategy===q?p(o,e):E[o.level].func(o,e);if(_!==vt&&_!==kt||(o.status=mt),_===bt||_===vt)return 0===t.avail_out&&(o.last_flush=-1),L;if(_===wt&&(e===U?Z._tr_align(o):e!==F&&(Z._tr_stored_block(o,0,0,!1),e===T&&(i(o.head),0===o.lookahead&&(o.strstart=0,o.block_start=0,o.insert=0))),s(t),0===t.avail_out))return o.last_flush=-1,L}return e!==j?L:o.wrap<=0?H:(2===o.wrap?(l(o,255&t.adler),l(o,t.adler>>8&255),l(o,t.adler>>16&255),l(o,t.adler>>24&255),l(o,255&t.total_in),l(o,t.total_in>>8&255),l(o,t.total_in>>16&255),l(o,t.total_in>>24&255)):(h(o,t.adler>>>16),h(o,65535&t.adler)),s(t),o.wrap>0&&(o.wrap=-o.wrap),0!==o.pending?L:H)}function A(t){var e;return t&&t.state?(e=t.state.status)!==ft&&e!==ut&&e!==ct&&e!==_t&&e!==gt&&e!==pt&&e!==mt?a(t,M):(t.state=null,e===pt?a(t,P):L):M}function S(t,e){var n,a,r,s,o,l,h,d,f=e.length;if(!t||!t.state)return M;if(n=t.state,2===(s=n.wrap)||1===s&&n.status!==ft||n.lookahead)return M;for(1===s&&(t.adler=N(t.adler,e,f,0)),n.wrap=0,f>=n.w_size&&(0===s&&(i(n.head),n.strstart=0,n.block_start=0,n.insert=0),d=new O.Buf8(n.w_size),O.arraySet(d,e,f-n.w_size,n.w_size,0),e=d,f=n.w_size),o=t.avail_in,l=t.next_in,h=t.input,t.avail_in=f,t.next_in=0,t.input=e,u(n);n.lookahead>=ot;){a=n.strstart,r=n.lookahead-(ot-1);do{n.ins_h=(n.ins_h<<n.hash_shift^n.window[a+ot-1])&n.hash_mask,n.prev[a&n.w_mask]=n.head[n.ins_h],n.head[n.ins_h]=a,a++}while(--r);n.strstart=a,n.lookahead=ot-1,u(n)}return n.strstart+=n.lookahead,n.block_start=n.strstart,n.insert=n.lookahead,n.lookahead=0,n.match_length=n.prev_length=ot-1,n.match_available=0,t.next_in=l,t.input=h,t.avail_in=o,n.wrap=s,L}var E,O=t("../utils/common"),Z=t("./trees"),N=t("./adler32"),R=t("./crc32"),D=t("./messages"),I=0,U=1,T=3,j=4,F=5,L=0,H=1,M=-2,P=-3,W=-5,K=-1,Y=1,$=2,q=3,G=4,X=0,J=2,Q=8,V=9,tt=15,et=8,nt=286,at=30,rt=19,it=2*nt+1,st=15,ot=3,lt=258,ht=lt+ot+1,dt=32,ft=42,ut=69,ct=73,_t=91,gt=103,pt=113,mt=666,bt=1,wt=2,vt=3,kt=4,yt=3;E=[new b(0,0,0,0,c),new b(4,4,8,4,_),new b(4,5,16,8,_),new b(4,6,32,32,_),new b(4,4,16,16,g),new b(8,16,32,32,g),new b(8,16,128,128,g),new b(8,32,128,256,g),new b(32,128,258,1024,g),new b(32,258,258,4096,g)],n.deflateInit=B,n.deflateInit2=z,n.deflateReset=y,n.deflateResetKeep=k,n.deflateSetHeader=x,n.deflate=C,n.deflateEnd=A,n.deflateSetDictionary=S,n.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":5,"./adler32":7,"./crc32":8,"./messages":10,"./trees":11}],10:[function(t,e,n){"use strict";e.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],11:[function(t,e,n){"use strict";function a(t){for(var e=t.length;--e>=0;)t[e]=0}function r(t,e,n,a,r){this.static_tree=t,this.extra_bits=e,this.extra_base=n,this.elems=a,this.max_length=r,this.has_stree=t&&t.length}function i(t,e){this.dyn_tree=t,this.max_code=0,this.stat_desc=e}function s(t){return t<256?it[t]:it[256+(t>>>7)]}function o(t,e){t.pending_buf[t.pending++]=255&e,t.pending_buf[t.pending++]=e>>>8&255}function l(t,e,n){t.bi_valid>$-n?(t.bi_buf|=e<<t.bi_valid&65535,o(t,t.bi_buf),t.bi_buf=e>>$-t.bi_valid,t.bi_valid+=n-$):(t.bi_buf|=e<<t.bi_valid&65535,t.bi_valid+=n)}function h(t,e,n){l(t,n[2*e],n[2*e+1])}function d(t,e){var n=0;do{n|=1&t,t>>>=1,n<<=1}while(--e>0);return n>>>1}function f(t){16===t.bi_valid?(o(t,t.bi_buf),t.bi_buf=0,t.bi_valid=0):t.bi_valid>=8&&(t.pending_buf[t.pending++]=255&t.bi_buf,t.bi_buf>>=8,t.bi_valid-=8)}function u(t,e){var n,a,r,i,s,o,l=e.dyn_tree,h=e.max_code,d=e.stat_desc.static_tree,f=e.stat_desc.has_stree,u=e.stat_desc.extra_bits,c=e.stat_desc.extra_base,_=e.stat_desc.max_length,g=0;for(i=0;i<=Y;i++)t.bl_count[i]=0;for(l[2*t.heap[t.heap_max]+1]=0,n=t.heap_max+1;n<K;n++)a=t.heap[n],i=l[2*l[2*a+1]+1]+1,i>_&&(i=_,g++),l[2*a+1]=i,a>h||(t.bl_count[i]++,s=0,a>=c&&(s=u[a-c]),o=l[2*a],t.opt_len+=o*(i+s),f&&(t.static_len+=o*(d[2*a+1]+s)));if(0!==g){do{for(i=_-1;0===t.bl_count[i];)i--;t.bl_count[i]--,t.bl_count[i+1]+=2,t.bl_count[_]--,g-=2}while(g>0);for(i=_;0!==i;i--)for(a=t.bl_count[i];0!==a;)(r=t.heap[--n])>h||(l[2*r+1]!==i&&(t.opt_len+=(i-l[2*r+1])*l[2*r],l[2*r+1]=i),a--)}}function c(t,e,n){var a,r,i=new Array(Y+1),s=0;for(a=1;a<=Y;a++)i[a]=s=s+n[a-1]<<1;for(r=0;r<=e;r++){var o=t[2*r+1];0!==o&&(t[2*r]=d(i[o]++,o))}}function _(){var t,e,n,a,i,s=new Array(Y+1);for(n=0,a=0;a<L-1;a++)for(ot[a]=n,t=0;t<1<<V[a];t++)st[n++]=a;for(st[n-1]=a,i=0,a=0;a<16;a++)for(lt[a]=i,t=0;t<1<<tt[a];t++)it[i++]=a;for(i>>=7;a<P;a++)for(lt[a]=i<<7,t=0;t<1<<tt[a]-7;t++)it[256+i++]=a;for(e=0;e<=Y;e++)s[e]=0;for(t=0;t<=143;)at[2*t+1]=8,t++,s[8]++;for(;t<=255;)at[2*t+1]=9,t++,s[9]++;for(;t<=279;)at[2*t+1]=7,t++,s[7]++;for(;t<=287;)at[2*t+1]=8,t++,s[8]++;for(c(at,M+1,s),t=0;t<P;t++)rt[2*t+1]=5,rt[2*t]=d(t,5);ht=new r(at,V,H+1,M,Y),dt=new r(rt,tt,0,P,Y),ft=new r(new Array(0),et,0,W,q)}function g(t){var e;for(e=0;e<M;e++)t.dyn_ltree[2*e]=0;for(e=0;e<P;e++)t.dyn_dtree[2*e]=0;for(e=0;e<W;e++)t.bl_tree[2*e]=0;t.dyn_ltree[2*G]=1,t.opt_len=t.static_len=0,t.last_lit=t.matches=0}function p(t){t.bi_valid>8?o(t,t.bi_buf):t.bi_valid>0&&(t.pending_buf[t.pending++]=t.bi_buf),t.bi_buf=0,t.bi_valid=0}function m(t,e,n,a){p(t),a&&(o(t,n),o(t,~n)),N.arraySet(t.pending_buf,t.window,e,n,t.pending),t.pending+=n}function b(t,e,n,a){var r=2*e,i=2*n;return t[r]<t[i]||t[r]===t[i]&&a[e]<=a[n]}function w(t,e,n){for(var a=t.heap[n],r=n<<1;r<=t.heap_len&&(r<t.heap_len&&b(e,t.heap[r+1],t.heap[r],t.depth)&&r++,!b(e,a,t.heap[r],t.depth));)t.heap[n]=t.heap[r],n=r,r<<=1;t.heap[n]=a}function v(t,e,n){var a,r,i,o,d=0;if(0!==t.last_lit)do{a=t.pending_buf[t.d_buf+2*d]<<8|t.pending_buf[t.d_buf+2*d+1],r=t.pending_buf[t.l_buf+d],d++,0===a?h(t,r,e):(i=st[r],h(t,i+H+1,e),o=V[i],0!==o&&(r-=ot[i],l(t,r,o)),a--,i=s(a),h(t,i,n),0!==(o=tt[i])&&(a-=lt[i],l(t,a,o)))}while(d<t.last_lit);h(t,G,e)}function k(t,e){var n,a,r,i=e.dyn_tree,s=e.stat_desc.static_tree,o=e.stat_desc.has_stree,l=e.stat_desc.elems,h=-1;for(t.heap_len=0,t.heap_max=K,n=0;n<l;n++)0!==i[2*n]?(t.heap[++t.heap_len]=h=n,t.depth[n]=0):i[2*n+1]=0;for(;t.heap_len<2;)r=t.heap[++t.heap_len]=h<2?++h:0,i[2*r]=1,t.depth[r]=0,t.opt_len--,o&&(t.static_len-=s[2*r+1]);for(e.max_code=h,n=t.heap_len>>1;n>=1;n--)w(t,i,n);r=l;do{n=t.heap[1],t.heap[1]=t.heap[t.heap_len--],w(t,i,1),a=t.heap[1],t.heap[--t.heap_max]=n,t.heap[--t.heap_max]=a,i[2*r]=i[2*n]+i[2*a],t.depth[r]=(t.depth[n]>=t.depth[a]?t.depth[n]:t.depth[a])+1,i[2*n+1]=i[2*a+1]=r,t.heap[1]=r++,w(t,i,1)}while(t.heap_len>=2);t.heap[--t.heap_max]=t.heap[1],u(t,e),c(i,h,t.bl_count)}function y(t,e,n){var a,r,i=-1,s=e[1],o=0,l=7,h=4;for(0===s&&(l=138,h=3),e[2*(n+1)+1]=65535,a=0;a<=n;a++)r=s,s=e[2*(a+1)+1],++o<l&&r===s||(o<h?t.bl_tree[2*r]+=o:0!==r?(r!==i&&t.bl_tree[2*r]++,t.bl_tree[2*X]++):o<=10?t.bl_tree[2*J]++:t.bl_tree[2*Q]++,o=0,i=r,0===s?(l=138,h=3):r===s?(l=6,h=3):(l=7,h=4))}function x(t,e,n){var a,r,i=-1,s=e[1],o=0,d=7,f=4;for(0===s&&(d=138,f=3),a=0;a<=n;a++)if(r=s,s=e[2*(a+1)+1],!(++o<d&&r===s)){if(o<f)do{h(t,r,t.bl_tree)}while(0!=--o);else 0!==r?(r!==i&&(h(t,r,t.bl_tree),o--),h(t,X,t.bl_tree),l(t,o-3,2)):o<=10?(h(t,J,t.bl_tree),l(t,o-3,3)):(h(t,Q,t.bl_tree),l(t,o-11,7));o=0,i=r,0===s?(d=138,f=3):r===s?(d=6,f=3):(d=7,f=4)}}function z(t){var e;for(y(t,t.dyn_ltree,t.l_desc.max_code),y(t,t.dyn_dtree,t.d_desc.max_code),k(t,t.bl_desc),e=W-1;e>=3&&0===t.bl_tree[2*nt[e]+1];e--);return t.opt_len+=3*(e+1)+5+5+4,e}function B(t,e,n,a){var r;for(l(t,e-257,5),l(t,n-1,5),l(t,a-4,4),r=0;r<a;r++)l(t,t.bl_tree[2*nt[r]+1],3);x(t,t.dyn_ltree,e-1),x(t,t.dyn_dtree,n-1)}function C(t){var e,n=4093624447;for(e=0;e<=31;e++,n>>>=1)if(1&n&&0!==t.dyn_ltree[2*e])return D;if(0!==t.dyn_ltree[18]||0!==t.dyn_ltree[20]||0!==t.dyn_ltree[26])return I;for(e=32;e<H;e++)if(0!==t.dyn_ltree[2*e])return I;return D}function A(t){ut||(_(),ut=!0),t.l_desc=new i(t.dyn_ltree,ht),t.d_desc=new i(t.dyn_dtree,dt),t.bl_desc=new i(t.bl_tree,ft),t.bi_buf=0,t.bi_valid=0,g(t)}function S(t,e,n,a){l(t,(T<<1)+(a?1:0),3),m(t,e,n,!0)}function E(t){l(t,j<<1,3),h(t,G,at),f(t)}function O(t,e,n,a){var r,i,s=0;t.level>0?(t.strm.data_type===U&&(t.strm.data_type=C(t)),k(t,t.l_desc),k(t,t.d_desc),s=z(t),r=t.opt_len+3+7>>>3,(i=t.static_len+3+7>>>3)<=r&&(r=i)):r=i=n+5,n+4<=r&&-1!==e?S(t,e,n,a):t.strategy===R||i===r?(l(t,(j<<1)+(a?1:0),3),v(t,at,rt)):(l(t,(F<<1)+(a?1:0),3),B(t,t.l_desc.max_code+1,t.d_desc.max_code+1,s+1),v(t,t.dyn_ltree,t.dyn_dtree)),g(t),a&&p(t)}function Z(t,e,n){return t.pending_buf[t.d_buf+2*t.last_lit]=e>>>8&255,t.pending_buf[t.d_buf+2*t.last_lit+1]=255&e,t.pending_buf[t.l_buf+t.last_lit]=255&n,t.last_lit++,0===e?t.dyn_ltree[2*n]++:(t.matches++,e--,t.dyn_ltree[2*(st[n]+H+1)]++,t.dyn_dtree[2*s(e)]++),t.last_lit===t.lit_bufsize-1}var N=t("../utils/common"),R=4,D=0,I=1,U=2,T=0,j=1,F=2,L=29,H=256,M=H+1+L,P=30,W=19,K=2*M+1,Y=15,$=16,q=7,G=256,X=16,J=17,Q=18,V=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],tt=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],et=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],nt=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],at=new Array(2*(M+2));a(at);var rt=new Array(2*P);a(rt);var it=new Array(512);a(it);var st=new Array(256);a(st);var ot=new Array(L);a(ot);var lt=new Array(P);a(lt);var ht,dt,ft,ut=!1;n._tr_init=A,n._tr_stored_block=S,n._tr_flush_block=O,n._tr_tally=Z,n._tr_align=E},{"../utils/common":5}],12:[function(t,e,n){"use strict";function a(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}e.exports=a},{}]},{},[3])(3)})},function(t,e,n){var a,a;!function(e){t.exports=e()}(function(){return function(){function t(e,n,r){function i(o,l){if(!n[o]){if(!e[o]){var h="function"==typeof a&&a;if(!l&&h)return a(o,!0);if(s)return s(o,!0);var d=new Error("Cannot find module '"+o+"'");throw d.code="MODULE_NOT_FOUND",d}var f=n[o]={exports:{}};e[o][0].call(f.exports,function(t){return i(e[o][1][t]||t)},f,f.exports,t,e,n,r)}return n[o].exports}for(var s="function"==typeof a&&a,o=0;o<r.length;o++)i(r[o]);return i}return t}()({1:[function(t,e,n){"use strict";var a=t("pako/lib/inflate.js");e.exports=function(t){return a.inflateRaw(t,{to:"string"})}},{"pako/lib/inflate.js":4}],2:[function(t,e,n){"use strict";function a(t){var e=t.charCodeAt(0);return"_"===t?63:"-"===t?62:e>=97?e-61:e>=65?e-55:e>=48?e-48:"?"}function r(t){var e=a(t[0]),n=a(t[1]),r=a(t[2]);return[e<<2|n>>4&63,n<<4&240|r>>2&15,r<<6&192|63&a(t[3])]}e.exports=function(t){var e="",n=0;for(n=0;n<t.length;n+=4){var a=r(t.substring(n,n+4));e+=String.fromCharCode(a[0]),e+=String.fromCharCode(a[1]),e+=String.fromCharCode(a[2])}return e}},{}],3:[function(t,e,n){"use strict";var a=t("./inflate"),r=t("./decode64");e.exports.decode=function(t){var e=r(t);return a(e)}},{"./decode64":2,"./inflate":1}],4:[function(t,e,n){"use strict";function a(t){if(!(this instanceof a))return new a(t);this.options=o.assign({chunkSize:16384,windowBits:0,to:""},t||{});var e=this.options;e.raw&&e.windowBits>=0&&e.windowBits<16&&(e.windowBits=-e.windowBits,0===e.windowBits&&(e.windowBits=-15)),!(e.windowBits>=0&&e.windowBits<16)||t&&t.windowBits||(e.windowBits+=32),e.windowBits>15&&e.windowBits<48&&0==(15&e.windowBits)&&(e.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new f,this.strm.avail_out=0;var n=s.inflateInit2(this.strm,e.windowBits);if(n!==h.Z_OK)throw new Error(d[n]);if(this.header=new u,s.inflateGetHeader(this.strm,this.header),e.dictionary&&("string"==typeof e.dictionary?e.dictionary=l.string2buf(e.dictionary):"[object ArrayBuffer]"===c.call(e.dictionary)&&(e.dictionary=new Uint8Array(e.dictionary)),e.raw&&(n=s.inflateSetDictionary(this.strm,e.dictionary))!==h.Z_OK))throw new Error(d[n])}function r(t,e){var n=new a(e);if(n.push(t,!0),n.err)throw n.msg||d[n.err];return n.result}function i(t,e){return e=e||{},e.raw=!0,r(t,e)}var s=t("./zlib/inflate"),o=t("./utils/common"),l=t("./utils/strings"),h=t("./zlib/constants"),d=t("./zlib/messages"),f=t("./zlib/zstream"),u=t("./zlib/gzheader"),c=Object.prototype.toString;a.prototype.push=function(t,e){var n,a,r,i,d,f=this.strm,u=this.options.chunkSize,_=this.options.dictionary,g=!1;if(this.ended)return!1;a=e===~~e?e:!0===e?h.Z_FINISH:h.Z_NO_FLUSH,"string"==typeof t?f.input=l.binstring2buf(t):"[object ArrayBuffer]"===c.call(t)?f.input=new Uint8Array(t):f.input=t,f.next_in=0,f.avail_in=f.input.length;do{if(0===f.avail_out&&(f.output=new o.Buf8(u),f.next_out=0,f.avail_out=u),n=s.inflate(f,h.Z_NO_FLUSH),n===h.Z_NEED_DICT&&_&&(n=s.inflateSetDictionary(this.strm,_)),n===h.Z_BUF_ERROR&&!0===g&&(n=h.Z_OK,g=!1),n!==h.Z_STREAM_END&&n!==h.Z_OK)return this.onEnd(n),this.ended=!0,!1;f.next_out&&(0!==f.avail_out&&n!==h.Z_STREAM_END&&(0!==f.avail_in||a!==h.Z_FINISH&&a!==h.Z_SYNC_FLUSH)||("string"===this.options.to?(r=l.utf8border(f.output,f.next_out),i=f.next_out-r,d=l.buf2string(f.output,r),f.next_out=i,f.avail_out=u-i,i&&o.arraySet(f.output,f.output,r,i,0),this.onData(d)):this.onData(o.shrinkBuf(f.output,f.next_out)))),0===f.avail_in&&0===f.avail_out&&(g=!0)}while((f.avail_in>0||0===f.avail_out)&&n!==h.Z_STREAM_END);return n===h.Z_STREAM_END&&(a=h.Z_FINISH),a===h.Z_FINISH?(n=s.inflateEnd(this.strm),this.onEnd(n),this.ended=!0,n===h.Z_OK):a!==h.Z_SYNC_FLUSH||(this.onEnd(h.Z_OK),f.avail_out=0,!0)},a.prototype.onData=function(t){this.chunks.push(t)},a.prototype.onEnd=function(t){t===h.Z_OK&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=o.flattenChunks(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg},n.Inflate=a,n.inflate=r,n.inflateRaw=i,n.ungzip=r},{"./utils/common":5,"./utils/strings":6,"./zlib/constants":8,"./zlib/gzheader":10,"./zlib/inflate":12,"./zlib/messages":14,"./zlib/zstream":15}],5:[function(t,e,n){"use strict";function a(t,e){return Object.prototype.hasOwnProperty.call(t,e)}var r="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;n.assign=function(t){for(var e=Array.prototype.slice.call(arguments,1);e.length;){var n=e.shift();if(n){if("object"!=typeof n)throw new TypeError(n+"must be non-object");for(var r in n)a(n,r)&&(t[r]=n[r])}}return t},n.shrinkBuf=function(t,e){return t.length===e?t:t.subarray?t.subarray(0,e):(t.length=e,t)};var i={arraySet:function(t,e,n,a,r){if(e.subarray&&t.subarray)return void t.set(e.subarray(n,n+a),r);for(var i=0;i<a;i++)t[r+i]=e[n+i]},flattenChunks:function(t){var e,n,a,r,i,s;for(a=0,e=0,n=t.length;e<n;e++)a+=t[e].length;for(s=new Uint8Array(a),r=0,e=0,n=t.length;e<n;e++)i=t[e],s.set(i,r),r+=i.length;return s}},s={arraySet:function(t,e,n,a,r){for(var i=0;i<a;i++)t[r+i]=e[n+i]},flattenChunks:function(t){return[].concat.apply([],t)}};n.setTyped=function(t){t?(n.Buf8=Uint8Array,n.Buf16=Uint16Array,n.Buf32=Int32Array,n.assign(n,i)):(n.Buf8=Array,n.Buf16=Array,n.Buf32=Array,n.assign(n,s))},n.setTyped(r)},{}],6:[function(t,e,n){"use strict";function a(t,e){if(e<65534&&(t.subarray&&s||!t.subarray&&i))return String.fromCharCode.apply(null,r.shrinkBuf(t,e));for(var n="",a=0;a<e;a++)n+=String.fromCharCode(t[a]);return n}var r=t("./common"),i=!0,s=!0;try{String.fromCharCode.apply(null,[0])}catch(t){i=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(t){s=!1}for(var o=new r.Buf8(256),l=0;l<256;l++)o[l]=l>=252?6:l>=248?5:l>=240?4:l>=224?3:l>=192?2:1;o[254]=o[254]=1,n.string2buf=function(t){var e,n,a,i,s,o=t.length,l=0;for(i=0;i<o;i++)n=t.charCodeAt(i),55296==(64512&n)&&i+1<o&&56320==(64512&(a=t.charCodeAt(i+1)))&&(n=65536+(n-55296<<10)+(a-56320),i++),l+=n<128?1:n<2048?2:n<65536?3:4;for(e=new r.Buf8(l),s=0,i=0;s<l;i++)n=t.charCodeAt(i),55296==(64512&n)&&i+1<o&&56320==(64512&(a=t.charCodeAt(i+1)))&&(n=65536+(n-55296<<10)+(a-56320),i++),n<128?e[s++]=n:n<2048?(e[s++]=192|n>>>6,e[s++]=128|63&n):n<65536?(e[s++]=224|n>>>12,e[s++]=128|n>>>6&63,e[s++]=128|63&n):(e[s++]=240|n>>>18,e[s++]=128|n>>>12&63,e[s++]=128|n>>>6&63,e[s++]=128|63&n);return e},n.buf2binstring=function(t){return a(t,t.length)},n.binstring2buf=function(t){for(var e=new r.Buf8(t.length),n=0,a=e.length;n<a;n++)e[n]=t.charCodeAt(n);return e},n.buf2string=function(t,e){var n,r,i,s,l=e||t.length,h=new Array(2*l);for(r=0,n=0;n<l;)if((i=t[n++])<128)h[r++]=i;else if((s=o[i])>4)h[r++]=65533,n+=s-1;else{for(i&=2===s?31:3===s?15:7;s>1&&n<l;)i=i<<6|63&t[n++],s--;s>1?h[r++]=65533:i<65536?h[r++]=i:(i-=65536,h[r++]=55296|i>>10&1023,h[r++]=56320|1023&i)}return a(h,r)},n.utf8border=function(t,e){var n;for(e=e||t.length,e>t.length&&(e=t.length),n=e-1;n>=0&&128==(192&t[n]);)n--;return n<0?e:0===n?e:n+o[t[n]]>e?n:e}},{"./common":5}],7:[function(t,e,n){"use strict";function a(t,e,n,a){for(var r=65535&t|0,i=t>>>16&65535|0,s=0;0!==n;){s=n>2e3?2e3:n,n-=s;do{r=r+e[a++]|0,i=i+r|0}while(--s);r%=65521,i%=65521}return r|i<<16|0}e.exports=a},{}],8:[function(t,e,n){"use strict";e.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],9:[function(t,e,n){"use strict";function a(t,e,n,a){var i=r,s=a+n;t^=-1;for(var o=a;o<s;o++)t=t>>>8^i[255&(t^e[o])];return-1^t}var r=function(){for(var t,e=[],n=0;n<256;n++){t=n;for(var a=0;a<8;a++)t=1&t?3988292384^t>>>1:t>>>1;e[n]=t}return e}();e.exports=a},{}],10:[function(t,e,n){"use strict";function a(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}e.exports=a},{}],11:[function(t,e,n){"use strict";e.exports=function(t,e){var n,a,r,i,s,o,l,h,d,f,u,c,_,g,p,m,b,w,v,k,y,x,z,B,C;n=t.state,a=t.next_in,B=t.input,r=a+(t.avail_in-5),i=t.next_out,C=t.output,s=i-(e-t.avail_out),o=i+(t.avail_out-257),l=n.dmax,h=n.wsize,d=n.whave,f=n.wnext,u=n.window,c=n.hold,_=n.bits,g=n.lencode,p=n.distcode,m=(1<<n.lenbits)-1,b=(1<<n.distbits)-1;t:do{_<15&&(c+=B[a++]<<_,_+=8,c+=B[a++]<<_,_+=8),w=g[c&m];e:for(;;){if(v=w>>>24,c>>>=v,_-=v,0===(v=w>>>16&255))C[i++]=65535&w;else{if(!(16&v)){if(0==(64&v)){w=g[(65535&w)+(c&(1<<v)-1)];continue e}if(32&v){n.mode=12;break t}t.msg="invalid literal/length code",n.mode=30;break t}k=65535&w,v&=15,v&&(_<v&&(c+=B[a++]<<_,_+=8),k+=c&(1<<v)-1,c>>>=v,_-=v),_<15&&(c+=B[a++]<<_,_+=8,c+=B[a++]<<_,_+=8),w=p[c&b];n:for(;;){if(v=w>>>24,c>>>=v,_-=v,!(16&(v=w>>>16&255))){if(0==(64&v)){w=p[(65535&w)+(c&(1<<v)-1)];continue n}t.msg="invalid distance code",n.mode=30;break t}if(y=65535&w,v&=15,_<v&&(c+=B[a++]<<_,(_+=8)<v&&(c+=B[a++]<<_,_+=8)),(y+=c&(1<<v)-1)>l){t.msg="invalid distance too far back",n.mode=30;break t}if(c>>>=v,_-=v,v=i-s,y>v){if((v=y-v)>d&&n.sane){t.msg="invalid distance too far back",n.mode=30;break t}if(x=0,z=u,0===f){if(x+=h-v,v<k){k-=v;do{C[i++]=u[x++]}while(--v);x=i-y,z=C}}else if(f<v){if(x+=h+f-v,(v-=f)<k){k-=v;do{C[i++]=u[x++]}while(--v);if(x=0,f<k){v=f,k-=v;do{C[i++]=u[x++]}while(--v);x=i-y,z=C}}}else if(x+=f-v,v<k){k-=v;do{C[i++]=u[x++]}while(--v);x=i-y,z=C}for(;k>2;)C[i++]=z[x++],C[i++]=z[x++],C[i++]=z[x++],k-=3;k&&(C[i++]=z[x++],k>1&&(C[i++]=z[x++]))}else{x=i-y;do{C[i++]=C[x++],C[i++]=C[x++],C[i++]=C[x++],k-=3}while(k>2);k&&(C[i++]=C[x++],k>1&&(C[i++]=C[x++]))}break}}break}}while(a<r&&i<o);k=_>>3,a-=k,_-=k<<3,c&=(1<<_)-1,t.next_in=a,t.next_out=i,t.avail_in=a<r?r-a+5:5-(a-r),t.avail_out=i<o?o-i+257:257-(i-o),n.hold=c,n.bits=_}},{}],12:[function(t,e,n){"use strict";function a(t){return(t>>>24&255)+(t>>>8&65280)+((65280&t)<<8)+((255&t)<<24)}function r(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new b.Buf16(320),this.work=new b.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function i(t){var e;return t&&t.state?(e=t.state,t.total_in=t.total_out=e.total=0,t.msg="",e.wrap&&(t.adler=1&e.wrap),e.mode=T,e.last=0,e.havedict=0,e.dmax=32768,e.head=null,e.hold=0,e.bits=0,e.lencode=e.lendyn=new b.Buf32(gt),e.distcode=e.distdyn=new b.Buf32(pt),e.sane=1,e.back=-1,E):N}function s(t){var e;return t&&t.state?(e=t.state,e.wsize=0,e.whave=0,e.wnext=0,i(t)):N}function o(t,e){var n,a;return t&&t.state?(a=t.state,e<0?(n=0,e=-e):(n=1+(e>>4),e<48&&(e&=15)),e&&(e<8||e>15)?N:(null!==a.window&&a.wbits!==e&&(a.window=null),a.wrap=n,a.wbits=e,s(t))):N}function l(t,e){var n,a;return t?(a=new r,t.state=a,a.window=null,n=o(t,e),n!==E&&(t.state=null),n):N}function h(t){return l(t,mt)}function d(t){if(bt){var e;for(p=new b.Buf32(512),m=new b.Buf32(32),e=0;e<144;)t.lens[e++]=8;for(;e<256;)t.lens[e++]=9;for(;e<280;)t.lens[e++]=7;for(;e<288;)t.lens[e++]=8;for(y(z,t.lens,0,288,p,0,t.work,{bits:9}),e=0;e<32;)t.lens[e++]=5;y(B,t.lens,0,32,m,0,t.work,{bits:5}),bt=!1}t.lencode=p,t.lenbits=9,t.distcode=m,t.distbits=5}function f(t,e,n,a){var r,i=t.state;return null===i.window&&(i.wsize=1<<i.wbits,i.wnext=0,i.whave=0,i.window=new b.Buf8(i.wsize)),a>=i.wsize?(b.arraySet(i.window,e,n-i.wsize,i.wsize,0),i.wnext=0,i.whave=i.wsize):(r=i.wsize-i.wnext,r>a&&(r=a),b.arraySet(i.window,e,n-a,r,i.wnext),a-=r,a?(b.arraySet(i.window,e,n-a,a,0),i.wnext=a,i.whave=i.wsize):(i.wnext+=r,i.wnext===i.wsize&&(i.wnext=0),i.whave<i.wsize&&(i.whave+=r))),0}function u(t,e){var n,r,i,s,o,l,h,u,c,_,g,p,m,gt,pt,mt,bt,wt,vt,kt,yt,xt,zt,Bt,Ct=0,At=new b.Buf8(4),St=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!t||!t.state||!t.output||!t.input&&0!==t.avail_in)return N;n=t.state,n.mode===q&&(n.mode=G),o=t.next_out,i=t.output,h=t.avail_out,s=t.next_in,r=t.input,l=t.avail_in,u=n.hold,c=n.bits,_=l,g=h,xt=E;t:for(;;)switch(n.mode){case T:if(0===n.wrap){n.mode=G;break}for(;c<16;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if(2&n.wrap&&35615===u){n.check=0,At[0]=255&u,At[1]=u>>>8&255,n.check=v(n.check,At,2,0),u=0,c=0,n.mode=j;break}if(n.flags=0,n.head&&(n.head.done=!1),!(1&n.wrap)||(((255&u)<<8)+(u>>8))%31){t.msg="incorrect header check",n.mode=ut;break}if((15&u)!==U){t.msg="unknown compression method",n.mode=ut;break}if(u>>>=4,c-=4,yt=8+(15&u),0===n.wbits)n.wbits=yt;else if(yt>n.wbits){t.msg="invalid window size",n.mode=ut;break}n.dmax=1<<yt,t.adler=n.check=1,n.mode=512&u?Y:q,u=0,c=0;break;case j:for(;c<16;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if(n.flags=u,(255&n.flags)!==U){t.msg="unknown compression method",n.mode=ut;break}if(57344&n.flags){t.msg="unknown header flags set",n.mode=ut;break}n.head&&(n.head.text=u>>8&1),512&n.flags&&(At[0]=255&u,At[1]=u>>>8&255,n.check=v(n.check,At,2,0)),u=0,c=0,n.mode=F;case F:for(;c<32;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}n.head&&(n.head.time=u),512&n.flags&&(At[0]=255&u,At[1]=u>>>8&255,At[2]=u>>>16&255,At[3]=u>>>24&255,n.check=v(n.check,At,4,0)),u=0,c=0,n.mode=L;case L:for(;c<16;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}n.head&&(n.head.xflags=255&u,n.head.os=u>>8),512&n.flags&&(At[0]=255&u,At[1]=u>>>8&255,n.check=v(n.check,At,2,0)),u=0,c=0,n.mode=H;case H:if(1024&n.flags){for(;c<16;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}n.length=u,n.head&&(n.head.extra_len=u),512&n.flags&&(At[0]=255&u,At[1]=u>>>8&255,n.check=v(n.check,At,2,0)),u=0,c=0}else n.head&&(n.head.extra=null);n.mode=M;case M:if(1024&n.flags&&(p=n.length,p>l&&(p=l),p&&(n.head&&(yt=n.head.extra_len-n.length,n.head.extra||(n.head.extra=new Array(n.head.extra_len)),b.arraySet(n.head.extra,r,s,p,yt)),512&n.flags&&(n.check=v(n.check,r,p,s)),l-=p,s+=p,n.length-=p),n.length))break t;n.length=0,n.mode=P;case P:if(2048&n.flags){if(0===l)break t;p=0;do{yt=r[s+p++],n.head&&yt&&n.length<65536&&(n.head.name+=String.fromCharCode(yt))}while(yt&&p<l);if(512&n.flags&&(n.check=v(n.check,r,p,s)),l-=p,s+=p,yt)break t}else n.head&&(n.head.name=null);n.length=0,n.mode=W;case W:if(4096&n.flags){if(0===l)break t;p=0;do{yt=r[s+p++],n.head&&yt&&n.length<65536&&(n.head.comment+=String.fromCharCode(yt))}while(yt&&p<l);if(512&n.flags&&(n.check=v(n.check,r,p,s)),l-=p,s+=p,yt)break t}else n.head&&(n.head.comment=null);n.mode=K;case K:if(512&n.flags){for(;c<16;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if(u!==(65535&n.check)){t.msg="header crc mismatch",n.mode=ut;break}u=0,c=0}n.head&&(n.head.hcrc=n.flags>>9&1,n.head.done=!0),t.adler=n.check=0,n.mode=q;break;case Y:for(;c<32;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}t.adler=n.check=a(u),u=0,c=0,n.mode=$;case $:if(0===n.havedict)return t.next_out=o,t.avail_out=h,t.next_in=s,t.avail_in=l,n.hold=u,n.bits=c,Z;t.adler=n.check=1,n.mode=q;case q:if(e===A||e===S)break t;case G:if(n.last){u>>>=7&c,c-=7&c,n.mode=ht;break}for(;c<3;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}switch(n.last=1&u,u>>>=1,c-=1,3&u){case 0:n.mode=X;break;case 1:if(d(n),n.mode=nt,e===S){u>>>=2,c-=2;break t}break;case 2:n.mode=V;break;case 3:t.msg="invalid block type",n.mode=ut}u>>>=2,c-=2;break;case X:for(u>>>=7&c,c-=7&c;c<32;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if((65535&u)!=(u>>>16^65535)){t.msg="invalid stored block lengths",n.mode=ut;break}if(n.length=65535&u,u=0,c=0,n.mode=J,e===S)break t;case J:n.mode=Q;case Q:if(p=n.length){if(p>l&&(p=l),p>h&&(p=h),0===p)break t;b.arraySet(i,r,s,p,o),l-=p,s+=p,h-=p,o+=p,n.length-=p;break}n.mode=q;break;case V:for(;c<14;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if(n.nlen=257+(31&u),u>>>=5,c-=5,n.ndist=1+(31&u),u>>>=5,c-=5,n.ncode=4+(15&u),u>>>=4,c-=4,n.nlen>286||n.ndist>30){t.msg="too many length or distance symbols",n.mode=ut;break}n.have=0,n.mode=tt;case tt:for(;n.have<n.ncode;){for(;c<3;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}n.lens[St[n.have++]]=7&u,u>>>=3,c-=3}for(;n.have<19;)n.lens[St[n.have++]]=0;if(n.lencode=n.lendyn,n.lenbits=7,zt={bits:n.lenbits},xt=y(x,n.lens,0,19,n.lencode,0,n.work,zt),n.lenbits=zt.bits,xt){t.msg="invalid code lengths set",n.mode=ut;break}n.have=0,n.mode=et;case et:for(;n.have<n.nlen+n.ndist;){for(;Ct=n.lencode[u&(1<<n.lenbits)-1],pt=Ct>>>24,mt=Ct>>>16&255,bt=65535&Ct,!(pt<=c);){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if(bt<16)u>>>=pt,c-=pt,n.lens[n.have++]=bt;else{if(16===bt){for(Bt=pt+2;c<Bt;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if(u>>>=pt,c-=pt,0===n.have){t.msg="invalid bit length repeat",n.mode=ut;break}yt=n.lens[n.have-1],p=3+(3&u),u>>>=2,c-=2}else if(17===bt){for(Bt=pt+3;c<Bt;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}u>>>=pt,c-=pt,yt=0,p=3+(7&u),u>>>=3,c-=3}else{for(Bt=pt+7;c<Bt;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}u>>>=pt,c-=pt,yt=0,p=11+(127&u),u>>>=7,c-=7}if(n.have+p>n.nlen+n.ndist){t.msg="invalid bit length repeat",n.mode=ut;break}for(;p--;)n.lens[n.have++]=yt}}if(n.mode===ut)break;if(0===n.lens[256]){t.msg="invalid code -- missing end-of-block",n.mode=ut;break}if(n.lenbits=9,zt={bits:n.lenbits},xt=y(z,n.lens,0,n.nlen,n.lencode,0,n.work,zt),n.lenbits=zt.bits,xt){t.msg="invalid literal/lengths set",n.mode=ut;break}if(n.distbits=6,n.distcode=n.distdyn,zt={bits:n.distbits},xt=y(B,n.lens,n.nlen,n.ndist,n.distcode,0,n.work,zt),n.distbits=zt.bits,xt){t.msg="invalid distances set",n.mode=ut;break}if(n.mode=nt,e===S)break t;case nt:n.mode=at;case at:if(l>=6&&h>=258){t.next_out=o,t.avail_out=h,t.next_in=s,t.avail_in=l,n.hold=u,n.bits=c,k(t,g),o=t.next_out,i=t.output,h=t.avail_out,s=t.next_in,r=t.input,l=t.avail_in,u=n.hold,c=n.bits,n.mode===q&&(n.back=-1);break}for(n.back=0;Ct=n.lencode[u&(1<<n.lenbits)-1],pt=Ct>>>24,mt=Ct>>>16&255,bt=65535&Ct,!(pt<=c);){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if(mt&&0==(240&mt)){for(wt=pt,vt=mt,kt=bt;Ct=n.lencode[kt+((u&(1<<wt+vt)-1)>>wt)],pt=Ct>>>24,mt=Ct>>>16&255,bt=65535&Ct,!(wt+pt<=c);){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}u>>>=wt,c-=wt,n.back+=wt}if(u>>>=pt,c-=pt,n.back+=pt,n.length=bt,0===mt){n.mode=lt;break}if(32&mt){n.back=-1,n.mode=q;break}if(64&mt){t.msg="invalid literal/length code",n.mode=ut;break}n.extra=15&mt,n.mode=rt;case rt:if(n.extra){for(Bt=n.extra;c<Bt;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}n.length+=u&(1<<n.extra)-1,u>>>=n.extra,c-=n.extra,n.back+=n.extra}n.was=n.length,n.mode=it;case it:for(;Ct=n.distcode[u&(1<<n.distbits)-1],pt=Ct>>>24,mt=Ct>>>16&255,bt=65535&Ct,!(pt<=c);){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if(0==(240&mt)){for(wt=pt,vt=mt,kt=bt;Ct=n.distcode[kt+((u&(1<<wt+vt)-1)>>wt)],pt=Ct>>>24,mt=Ct>>>16&255,bt=65535&Ct,!(wt+pt<=c);){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}u>>>=wt,c-=wt,n.back+=wt}if(u>>>=pt,c-=pt,n.back+=pt,64&mt){t.msg="invalid distance code",n.mode=ut;break}n.offset=bt,n.extra=15&mt,n.mode=st;case st:if(n.extra){for(Bt=n.extra;c<Bt;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}n.offset+=u&(1<<n.extra)-1,u>>>=n.extra,c-=n.extra,n.back+=n.extra}if(n.offset>n.dmax){t.msg="invalid distance too far back",n.mode=ut;break}n.mode=ot;case ot:if(0===h)break t;if(p=g-h,n.offset>p){if((p=n.offset-p)>n.whave&&n.sane){t.msg="invalid distance too far back",n.mode=ut;break}p>n.wnext?(p-=n.wnext,m=n.wsize-p):m=n.wnext-p,p>n.length&&(p=n.length),gt=n.window}else gt=i,m=o-n.offset,p=n.length;p>h&&(p=h),h-=p,n.length-=p;do{i[o++]=gt[m++]}while(--p);0===n.length&&(n.mode=at);break;case lt:if(0===h)break t;i[o++]=n.length,h--,n.mode=at;break;case ht:if(n.wrap){for(;c<32;){if(0===l)break t;l--,u|=r[s++]<<c,c+=8}if(g-=h,t.total_out+=g,n.total+=g,g&&(t.adler=n.check=n.flags?v(n.check,i,g,o-g):w(n.check,i,g,o-g)),g=h,(n.flags?u:a(u))!==n.check){t.msg="incorrect data check",n.mode=ut;break}u=0,c=0}n.mode=dt;case dt:if(n.wrap&&n.flags){for(;c<32;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if(u!==(4294967295&n.total)){t.msg="incorrect length check",n.mode=ut;break}u=0,c=0}n.mode=ft;case ft:xt=O;break t;case ut:xt=R;break t;case ct:return D;case _t:default:return N}return t.next_out=o,t.avail_out=h,t.next_in=s,t.avail_in=l,n.hold=u,n.bits=c,(n.wsize||g!==t.avail_out&&n.mode<ut&&(n.mode<ht||e!==C))&&f(t,t.output,t.next_out,g-t.avail_out)?(n.mode=ct,D):(_-=t.avail_in,g-=t.avail_out,t.total_in+=_,t.total_out+=g,n.total+=g,n.wrap&&g&&(t.adler=n.check=n.flags?v(n.check,i,g,t.next_out-g):w(n.check,i,g,t.next_out-g)),t.data_type=n.bits+(n.last?64:0)+(n.mode===q?128:0)+(n.mode===nt||n.mode===J?256:0),(0===_&&0===g||e===C)&&xt===E&&(xt=I),xt)}function c(t){if(!t||!t.state)return N;var e=t.state;return e.window&&(e.window=null),t.state=null,E}function _(t,e){var n;return t&&t.state?(n=t.state,0==(2&n.wrap)?N:(n.head=e,e.done=!1,E)):N}function g(t,e){var n,a,r=e.length;return t&&t.state?(n=t.state,0!==n.wrap&&n.mode!==$?N:n.mode===$&&(a=1,(a=w(a,e,r,0))!==n.check)?R:f(t,e,r,r)?(n.mode=ct,D):(n.havedict=1,E)):N}var p,m,b=t("../utils/common"),w=t("./adler32"),v=t("./crc32"),k=t("./inffast"),y=t("./inftrees"),x=0,z=1,B=2,C=4,A=5,S=6,E=0,O=1,Z=2,N=-2,R=-3,D=-4,I=-5,U=8,T=1,j=2,F=3,L=4,H=5,M=6,P=7,W=8,K=9,Y=10,$=11,q=12,G=13,X=14,J=15,Q=16,V=17,tt=18,et=19,nt=20,at=21,rt=22,it=23,st=24,ot=25,lt=26,ht=27,dt=28,ft=29,ut=30,ct=31,_t=32,gt=852,pt=592,mt=15,bt=!0;n.inflateReset=s,n.inflateReset2=o,n.inflateResetKeep=i,n.inflateInit=h,n.inflateInit2=l,n.inflate=u,n.inflateEnd=c,n.inflateGetHeader=_,n.inflateSetDictionary=g,n.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":5,"./adler32":7,"./crc32":9,"./inffast":11,"./inftrees":13}],13:[function(t,e,n){"use strict";var a=t("../utils/common"),r=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],i=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],s=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],o=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];e.exports=function(t,e,n,l,h,d,f,u){var c,_,g,p,m,b,w,v,k,y=u.bits,x=0,z=0,B=0,C=0,A=0,S=0,E=0,O=0,Z=0,N=0,R=null,D=0,I=new a.Buf16(16),U=new a.Buf16(16),T=null,j=0;for(x=0;x<=15;x++)I[x]=0;for(z=0;z<l;z++)I[e[n+z]]++;for(A=y,C=15;C>=1&&0===I[C];C--);if(A>C&&(A=C),0===C)return h[d++]=20971520,h[d++]=20971520,u.bits=1,0;for(B=1;B<C&&0===I[B];B++);for(A<B&&(A=B),O=1,x=1;x<=15;x++)if(O<<=1,(O-=I[x])<0)return-1;if(O>0&&(0===t||1!==C))return-1;for(U[1]=0,x=1;x<15;x++)U[x+1]=U[x]+I[x];for(z=0;z<l;z++)0!==e[n+z]&&(f[U[e[n+z]]++]=z);if(0===t?(R=T=f,b=19):1===t?(R=r,D-=257,T=i,j-=257,b=256):(R=s,T=o,b=-1),N=0,z=0,x=B,m=d,S=A,E=0,g=-1,Z=1<<A,p=Z-1,1===t&&Z>852||2===t&&Z>592)return 1;for(;;){w=x-E,f[z]<b?(v=0,k=f[z]):f[z]>b?(v=T[j+f[z]],k=R[D+f[z]]):(v=96,k=0),c=1<<x-E,_=1<<S,B=_;do{_-=c,h[m+(N>>E)+_]=w<<24|v<<16|k|0}while(0!==_);for(c=1<<x-1;N&c;)c>>=1;if(0!==c?(N&=c-1,N+=c):N=0,z++,0==--I[x]){if(x===C)break;x=e[n+f[z]]}if(x>A&&(N&p)!==g){for(0===E&&(E=A),m+=B,S=x-E,O=1<<S;S+E<C&&!((O-=I[S+E])<=0);)S++,O<<=1;if(Z+=1<<S,1===t&&Z>852||2===t&&Z>592)return 1;g=N&p,h[g]=A<<24|S<<16|m-d|0}}return 0!==N&&(h[m+N]=x-E<<24|64<<16|0),u.bits=A,0}},{"../utils/common":5}],14:[function(t,e,n){"use strict";e.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],15:[function(t,e,n){"use strict";function a(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}e.exports=a},{}]},{},[3])(3)})}]);
0 \ No newline at end of file 2 \ No newline at end of file
doc/lib/js/docsify@4.js 0 → 100644
  1 +!function(){function c(i){var o=Object.create(null);return function(e){var n=f(e)?e:JSON.stringify(e);return o[n]||(o[n]=i(e))}}var a=c(function(e){return e.replace(/([A-Z])/g,function(e){return"-"+e.toLowerCase()})}),u=Object.prototype.hasOwnProperty,m=Object.assign||function(e){for(var n=arguments,i=1;i<arguments.length;i++){var o,t=Object(n[i]);for(o in t)u.call(t,o)&&(e[o]=t[o])}return e};function f(e){return"string"==typeof e||"number"==typeof e}function d(){}function o(e){return"function"==typeof e}function g(e){e=e.match(/^([^:/?#]+:)?(?:\/{2,}([^/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/);return"string"==typeof e[1]&&0<e[1].length&&e[1].toLowerCase()!==location.protocol||"string"==typeof e[2]&&0<e[2].length&&e[2].replace(new RegExp(":("+{"http:":80,"https:":443}[location.protocol]+")?$"),"")!==location.host}var s=document.body.clientWidth<=600,t=window.history&&window.history.pushState&&window.history.replaceState&&!navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/),i={};function l(e,n){if(void 0===n&&(n=!1),"string"==typeof e){if(void 0!==window.Vue)return b(e);e=n?b(e):i[e]||(i[e]=b(e))}return e}var v=document,h=v.body,_=v.head;function b(e,n){return n?e.querySelector(n):v.querySelector(e)}function k(e,n){return[].slice.call(n?e.querySelectorAll(n):v.querySelectorAll(e))}function w(e,n){return e=v.createElement(e),n&&(e.innerHTML=n),e}function r(e,n){return e.appendChild(n)}function y(e,n){return e.insertBefore(n,e.children[0])}function p(e,n,i){o(n)?window.addEventListener(e,n):e.addEventListener(n,i)}function x(e,n,i){o(n)?window.removeEventListener(e,n):e.removeEventListener(n,i)}function S(e,n,i){e&&e.classList[i?n:"toggle"](i||n)}function e(e,n){var i=(n=void 0===n?document:n).readyState;if("complete"===i||"interactive"===i)return setTimeout(e,0);n.addEventListener("DOMContentLoaded",e)}var n=Object.freeze({__proto__:null,getNode:l,$:v,body:h,head:_,find:b,findAll:k,create:w,appendTo:r,before:y,on:p,off:x,toggleClass:S,style:function(e){r(_,w("style",e))},documentReady:e});function A(e,n){return-1!==e.indexOf(n,e.length-n.length)}var $=decodeURIComponent,z=encodeURIComponent;function F(e){var n={};return(e=e.trim().replace(/^(\?|#|&)/,""))&&e.split("&").forEach(function(e){e=e.replace(/\+/g," ").split("=");n[e[0]]=e[1]&&$(e[1])}),n}function E(e,n){void 0===n&&(n=[]);var i,o=[];for(i in e)-1<n.indexOf(i)||o.push(e[i]?(z(i)+"="+z(e[i])).toLowerCase():z(i));return o.length?"?"+o.join("&"):""}var T=c(function(e){return/(:|(\/{2}))/g.test(e)}),C=c(function(e){return e.split(/[?#]/)[0]}),R=c(function(e){if(/\/$/g.test(e))return e;e=e.match(/(\S*\/)[^/]+$/);return e?e[1]:""}),j=c(function(e){return e.replace(/^\/+/,"/").replace(/([^:])\/{2,}/g,"$1/")}),O=c(function(e){for(var n=e.replace(/^\//,"").split("/"),i=[],o=0,t=n.length;o<t;o++){var a=n[o];".."===a?i.pop():"."!==a&&i.push(a)}return"/"+i.join("/")});function L(e){return e.split("/").filter(function(e){return-1===e.indexOf("#")}).join("/")}function q(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];return j(e.map(L).join("/"))}var P=c(function(e){return e.replace("#","?id=")}),M={};function I(e){this.config=e}function N(e){var n=location.href.indexOf("#");location.replace(location.href.slice(0,0<=n?n:0)+"#"+e)}I.prototype.getBasePath=function(){return this.config.basePath},I.prototype.getFile=function(e,n){void 0===e&&(e=this.getCurrentPath());var i,o,t=this.config,a=this.getBasePath(),r="string"==typeof t.ext?t.ext:".md";return e=t.alias?function e(n,i,o){var t=Object.keys(i).filter(function(e){return(M[e]||(M[e]=new RegExp("^"+e+"$"))).test(n)&&n!==o})[0];return t?e(n.replace(M[t],i[t]),i,n):n}(e,t.alias):e,i=e,o=r,e=(e=new RegExp("\\.("+o.replace(/^\./,"")+"|html)$","g").test(i)?i:/\/$/g.test(i)?i+"README"+o:""+i+o)==="/README"+r&&t.homepage||e,e=T(e)?e:q(a,e),e=n?e.replace(new RegExp("^"+a),""):e},I.prototype.onchange=function(e){(e=void 0===e?d:e)()},I.prototype.getCurrentPath=function(){},I.prototype.normalize=function(){},I.prototype.parse=function(){},I.prototype.toURL=function(e,n,i){var o=i&&"#"===e[0],t=this.parse(P(e));if(t.query=m({},t.query,n),e=(e=t.path+E(t.query)).replace(/\.md(\?)|\.md$/,"$1"),o&&(e=(0<(o=i.indexOf("?"))?i.substring(0,o):i)+e),this.config.relativePath&&0!==e.indexOf("/")){i=i.substring(0,i.lastIndexOf("/")+1);return j(O(i+e))}return j("/"+e)};var H=function(o){function e(e){o.call(this,e),this.mode="hash"}return o&&(e.__proto__=o),((e.prototype=Object.create(o&&o.prototype)).constructor=e).prototype.getBasePath=function(){var e=window.location.pathname||"",n=this.config.basePath,e=A(e,".html")?e+"#/"+n:e+"/"+n;return/^(\/|https?:)/g.test(n)?n:j(e)},e.prototype.getCurrentPath=function(){var e=location.href,n=e.indexOf("#");return-1===n?"":e.slice(n+1)},e.prototype.onchange=function(i){void 0===i&&(i=d);var o=!1;p("click",function(e){e="A"===e.target.tagName?e.target:e.target.parentNode;e&&"A"===e.tagName&&!/_blank/.test(e.target)&&(o=!0)}),p("hashchange",function(e){var n=o?"navigate":"history";o=!1,i({event:e,source:n})})},e.prototype.normalize=function(){var e=this.getCurrentPath();if("/"===(e=P(e)).charAt(0))return N(e);N("/"+e)},e.prototype.parse=function(e){var n="",i=(e=void 0===e?location.href:e).indexOf("#"),i=(e=0<=i?e.slice(i+1):e).indexOf("?");return 0<=i&&(n=e.slice(i+1),e=e.slice(0,i)),{path:e,file:this.getFile(e,!0),query:F(n)}},e.prototype.toURL=function(e,n,i){return"#"+o.prototype.toURL.call(this,e,n,i)},e}(I),D=function(n){function e(e){n.call(this,e),this.mode="history"}return n&&(e.__proto__=n),((e.prototype=Object.create(n&&n.prototype)).constructor=e).prototype.getCurrentPath=function(){var e=this.getBasePath(),n=window.location.pathname;return((n=e&&0===n.indexOf(e)?n.slice(e.length):n)||"/")+window.location.search+window.location.hash},e.prototype.onchange=function(i){var o=this;void 0===i&&(i=d),p("click",function(e){var n="A"===e.target.tagName?e.target:e.target.parentNode;n&&"A"===n.tagName&&!/_blank/.test(n.target)&&(e.preventDefault(),n=n.href,-1!==o.config.crossOriginLinks.indexOf(n)?window.open(n,"_self"):window.history.pushState({key:n},"",n),i({event:e,source:"navigate"}))}),p("popstate",function(e){i({event:e,source:"history"})})},e.prototype.parse=function(e){var n="",i=(e=void 0===e?location.href:e).indexOf("?");0<=i&&(n=e.slice(i+1),e=e.slice(0,i));var o=q(location.origin),i=e.indexOf(o);return{path:e=-1<i?e.slice(i+o.length):e,file:this.getFile(e),query:F(n)}},e}(I),U={};var Z,B,V=/([^{]*?)\w(?=\})/g,Y={YYYY:"getFullYear",YY:"getYear",MM:function(e){return e.getMonth()+1},DD:"getDate",HH:"getHours",mm:"getMinutes",ss:"getSeconds",fff:"getMilliseconds"};function G(e){var n,i=e.loaded,o=e.total,t=e.step;Z||((e=w("div")).classList.add("progress"),r(h,e),Z=e),n=t?80<(n=parseInt(Z.style.width||0,10)+t)?80:n:Math.floor(i/o*100),Z.style.opacity=1,Z.style.width=95<=n?"100%":n+"%",95<=n&&(clearTimeout(B),B=setTimeout(function(e){Z.style.opacity=0,Z.style.width="0%"},200))}var W={};function X(t,e,n){void 0===e&&(e=!1),void 0===n&&(n={});function a(){r.addEventListener.apply(r,arguments)}var i,r=new XMLHttpRequest,o=W[t];if(o)return{then:function(e){return e(o.content,o.opt)},abort:d};for(i in r.open("GET",t),n)u.call(n,i)&&r.setRequestHeader(i,n[i]);return r.send(),{then:function(n,i){var o;void 0===i&&(i=d),e&&(o=setInterval(function(e){return G({step:Math.floor(5*Math.random()+1)})},500),a("progress",G),a("loadend",function(e){G(e),clearInterval(o)})),a("error",i),a("load",function(e){var e=e.target;400<=e.status?i(e):(e=W[t]={content:e.response,opt:{updatedAt:r.getResponseHeader("last-modified")}},n(e.content,e.opt))})},abort:function(e){return 4!==r.readyState&&r.abort()}}}function Q(e,n){e.innerHTML=e.innerHTML.replace(/var\(\s*--theme-color.*?\)/g,n)}var J=v.title;function K(){var e,n=l("section.cover");n&&(e=n.getBoundingClientRect().height,window.pageYOffset>=e||n.classList.contains("hidden")?S(h,"add","sticky"):S(h,"remove","sticky"))}function ee(e,n,o,i){var t=[];null!=(n=l(n))&&(t=k(n,"a"));var a,r=decodeURI(e.toURL(e.getCurrentPath()));return t.sort(function(e,n){return n.href.length-e.href.length}).forEach(function(e){var n=decodeURI(e.getAttribute("href")),i=o?e.parentNode:e;e.title=e.title||e.innerText,0!==r.indexOf(n)||a?S(i,"remove","active"):(a=e,S(i,"add","active"))}),i&&(v.title=a?a.title||a.innerText+" - "+J:J),a}function ne(e,n){for(var i=0;i<n.length;i++){var o=n[i];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}var ie=(function(e,n,i){return n&&ne(e.prototype,n),i&&ne(e,i),e}(oe,[{key:"getIntermediateValue",value:function(e){return this.decimal?e:Math.round(e)}},{key:"getFinalValue",value:function(){return this.end}}]),oe);function oe(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};!function(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}(this,oe),this.start=e.start,this.end=e.end,this.decimal=e.decimal}function te(e,n){for(var i=0;i<n.length;i++){var o=n[i];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}var ae=(function(e,n,i){return n&&te(e.prototype,n),i&&te(e,i),e}(re,[{key:"begin",value:function(){return this.isRunning||this.next===this.end||(this.frame=window.requestAnimationFrame(this._tick.bind(this))),this}},{key:"stop",value:function(){return window.cancelAnimationFrame(this.frame),this.isRunning=!1,this.frame=null,this.timeStart=null,this.next=null,this}},{key:"on",value:function(e,n){return this.events[e]=this.events[e]||[],this.events[e].push(n),this}},{key:"_emit",value:function(e,n){var i=this,e=this.events[e];e&&e.forEach(function(e){return e.call(i,n)})}},{key:"_tick",value:function(e){this.isRunning=!0;var n=this.next||this.start;this.timeStart||(this.timeStart=e),this.timeElapsed=e-this.timeStart,this.next=this.ease(this.timeElapsed,this.start,this.end-this.start,this.duration),this._shouldTick(n)?(this._emit("tick",this.tweener.getIntermediateValue(this.next)),this.frame=window.requestAnimationFrame(this._tick.bind(this))):(this._emit("tick",this.tweener.getFinalValue()),this._emit("done",null))}},{key:"_shouldTick",value:function(e){return{up:this.next<this.end&&e<=this.next,down:this.next>this.end&&e>=this.next}[this.direction]}},{key:"_defaultEase",value:function(e,n,i,o){return(e/=o/2)<1?i/2*e*e+n:-i/2*(--e*(e-2)-1)+n}}]),re);function re(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};!function(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}(this,re),this.duration=e.duration||1e3,this.ease=e.easing||this._defaultEase,this.tweener=e.tweener||new ie(e),this.start=this.tweener.start,this.end=this.tweener.end,this.frame=null,this.next=null,this.isRunning=!1,this.events={},this.direction=this.start<this.end?"up":"down"}var ce=document.currentScript;function ue(e){var n,i=m({auto2top:!1,autoHeader:!1,basePath:"",catchPluginErrors:!0,cornerExternalLinkTarget:"_blank",coverpage:"",crossOriginLinks:[],el:"#app",executeScript:null,ext:".md",externalLinkRel:"noopener",externalLinkTarget:"_blank",formatUpdated:"",ga:"",homepage:"README.md",loadNavbar:null,loadSidebar:null,maxLevel:6,mergeNavbar:!1,name:"",nameLink:window.location.pathname,nativeEmoji:!1,noCompileLinks:[],noEmoji:!1,notFoundPage:!0,relativePath:!1,repo:"",routes:{},routerMode:"hash",subMaxLevel:0,themeColor:"",topMargin:0},"function"==typeof window.$docsify?window.$docsify(e):window.$docsify),o=ce||[].slice.call(document.getElementsByTagName("script")).filter(function(e){return/docsify\./.test(e.src)})[0];if(o)for(var t in i)!u.call(i,t)||f(n=o.getAttribute("data-"+a(t)))&&(i[t]=""===n||n);return!0===i.loadSidebar&&(i.loadSidebar="_sidebar"+i.ext),!0===i.loadNavbar&&(i.loadNavbar="_navbar"+i.ext),!0===i.coverpage&&(i.coverpage="_coverpage"+i.ext),!0===i.repo&&(i.repo=""),!0===i.name&&(i.name=""),window.$docsify=i}var fe={},pe=!1,de=null,ge=!0,se=0;function le(e){if(ge){for(var n,i=l(".sidebar"),o=k(".anchor"),t=b(i,".sidebar-nav"),a=b(i,"li.active"),r=document.documentElement,c=(r&&r.scrollTop||document.body.scrollTop)-se,u=0,f=o.length;u<f;u+=1){var p=o[u];if(p.offsetTop>c){n=n||p;break}n=p}!n||(r=fe[ve(e,n.getAttribute("data-id"))])&&r!==a&&(a&&a.classList.remove("active"),r.classList.add("active"),a=r,!pe&&h.classList.contains("sticky")&&(e=i.clientHeight,r=a.offsetTop+a.clientHeight+40,a=a.offsetTop>=t.scrollTop&&r<=t.scrollTop+e,i.scrollTop=a?t.scrollTop:+r<e?0:r-e))}}function ve(e,n){return decodeURIComponent(e)+"?id="+decodeURIComponent(n)}function he(e,n){var i,o;n&&(o=ue().topMargin,(i=b("#"+n))&&(i=i,void 0===(o=o)&&(o=0),de&&de.stop(),ge=!1,de=new ae({start:window.pageYOffset,end:Math.round(i.getBoundingClientRect().top)+window.pageYOffset-o,duration:500}).on("tick",function(e){return window.scrollTo(0,e)}).on("done",function(){ge=!0,de=null}).begin()),e=fe[ve(e,n)],(n=b(l(".sidebar"),"li.active"))&&n.classList.remove("active"),e&&e.classList.add("active"))}var _e=v.scrollingElement||v.documentElement;var me="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function be(e,n){return e(n={exports:{}},n.exports),n.exports}function ke(e){return $e[e]}var we=be(function(n){function e(){return{baseUrl:null,breaks:!1,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:null,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tokenizer:null,walkTokens:null,xhtml:!1}}n.exports={defaults:e(),getDefaults:e,changeDefaults:function(e){n.exports.defaults=e}}}),ye=(we.defaults,we.getDefaults,we.changeDefaults,/[&<>"']/),xe=/[&<>"']/g,Se=/[<>"']|&(?!#?\w+;)/,Ae=/[<>"']|&(?!#?\w+;)/g,$e={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};var ze=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi;function Fe(e){return e.replace(ze,function(e,n){return"colon"===(n=n.toLowerCase())?":":"#"===n.charAt(0)?"x"===n.charAt(1)?String.fromCharCode(parseInt(n.substring(2),16)):String.fromCharCode(+n.substring(1)):""})}var Ee=/(^|[^\[])\^/g;var Te=/[^\w:]/g,Ce=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;var Re={},je=/^[^:]+:\/*[^/]*$/,Oe=/^([^:]+:)[\s\S]*$/,Le=/^([^:]+:\/*[^/]*)[\s\S]*$/;function qe(e,n){Re[" "+e]||(je.test(e)?Re[" "+e]=e+"/":Re[" "+e]=Pe(e,"/",!0));var i=-1===(e=Re[" "+e]).indexOf(":");return"//"===n.substring(0,2)?i?n:e.replace(Oe,"$1")+n:"/"===n.charAt(0)?i?n:e.replace(Le,"$1")+n:e+n}function Pe(e,n,i){var o=e.length;if(0===o)return"";for(var t=0;t<o;){var a=e.charAt(o-t-1);if(a!==n||i){if(a===n||!i)break;t++}else t++}return e.substr(0,o-t)}var Me=function(e,n){if(n){if(ye.test(e))return e.replace(xe,ke)}else if(Se.test(e))return e.replace(Ae,ke);return e},Ie=Fe,Ne=function(i,e){i=i.source||i,e=e||"";var o={replace:function(e,n){return n=(n=n.source||n).replace(Ee,"$1"),i=i.replace(e,n),o},getRegex:function(){return new RegExp(i,e)}};return o},He=function(e,n,i){if(e){var o;try{o=decodeURIComponent(Fe(i)).replace(Te,"").toLowerCase()}catch(e){return null}if(0===o.indexOf("javascript:")||0===o.indexOf("vbscript:")||0===o.indexOf("data:"))return null}n&&!Ce.test(i)&&(i=qe(n,i));try{i=encodeURI(i).replace(/%25/g,"%")}catch(e){return null}return i},De={exec:function(){}},Ue=function(e){for(var n,i,o=arguments,t=1;t<arguments.length;t++)for(i in n=o[t])Object.prototype.hasOwnProperty.call(n,i)&&(e[i]=n[i]);return e},Ze=function(e,n){var i=e.replace(/\|/g,function(e,n,i){for(var o=!1,t=n;0<=--t&&"\\"===i[t];)o=!o;return o?"|":" |"}).split(/ \|/),o=0;if(i.length>n)i.splice(n);else for(;i.length<n;)i.push("");for(;o<i.length;o++)i[o]=i[o].trim().replace(/\\\|/g,"|");return i},Be=Pe,Ve=function(e,n){if(-1===e.indexOf(n[1]))return-1;for(var i=e.length,o=0,t=0;t<i;t++)if("\\"===e[t])t++;else if(e[t]===n[0])o++;else if(e[t]===n[1]&&--o<0)return t;return-1},Ye=function(e){e&&e.sanitize&&!e.silent&&console.warn("marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options")},Ge=function(e,n){if(n<1)return"";for(var i="";1<n;)1&n&&(i+=e),n>>=1,e+=e;return i+e},We=we.defaults,Xe=Be,Qe=Ze,Je=Me,Ke=Ve;function en(e,n,i){var o=n.href,t=n.title?Je(n.title):null,n=e[1].replace(/\\([\[\]])/g,"$1");return"!"!==e[0].charAt(0)?{type:"link",raw:i,href:o,title:t,text:n}:{type:"image",raw:i,href:o,title:t,text:Je(n)}}var nn=function(){function e(e){this.options=e||We}return e.prototype.space=function(e){e=this.rules.block.newline.exec(e);if(e)return 1<e[0].length?{type:"space",raw:e[0]}:{raw:"\n"}},e.prototype.code=function(e,n){e=this.rules.block.code.exec(e);if(e){n=n[n.length-1];if(n&&"paragraph"===n.type)return{raw:e[0],text:e[0].trimRight()};n=e[0].replace(/^ {1,4}/gm,"");return{type:"code",raw:e[0],codeBlockStyle:"indented",text:this.options.pedantic?n:Xe(n,"\n")}}},e.prototype.fences=function(e){var n=this.rules.block.fences.exec(e);if(n){var i=n[0],e=function(e,n){if(null===(e=e.match(/^(\s+)(?:```)/)))return n;var i=e[1];return n.split("\n").map(function(e){var n=e.match(/^\s+/);return null!==n&&n[0].length>=i.length?e.slice(i.length):e}).join("\n")}(i,n[3]||"");return{type:"code",raw:i,lang:n[2]&&n[2].trim(),text:e}}},e.prototype.heading=function(e){var n=this.rules.block.heading.exec(e);if(n){var i=n[2].trim();return/#$/.test(i)&&(e=Xe(i,"#"),!this.options.pedantic&&e&&!/ $/.test(e)||(i=e.trim())),{type:"heading",raw:n[0],depth:n[1].length,text:i}}},e.prototype.nptable=function(e){e=this.rules.block.nptable.exec(e);if(e){var n={type:"table",header:Qe(e[1].replace(/^ *| *\| *$/g,"")),align:e[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:e[3]?e[3].replace(/\n$/,"").split("\n"):[],raw:e[0]};if(n.header.length===n.align.length){for(var i=n.align.length,o=0;o<i;o++)/^ *-+: *$/.test(n.align[o])?n.align[o]="right":/^ *:-+: *$/.test(n.align[o])?n.align[o]="center":/^ *:-+ *$/.test(n.align[o])?n.align[o]="left":n.align[o]=null;for(i=n.cells.length,o=0;o<i;o++)n.cells[o]=Qe(n.cells[o],n.header.length);return n}}},e.prototype.hr=function(e){e=this.rules.block.hr.exec(e);if(e)return{type:"hr",raw:e[0]}},e.prototype.blockquote=function(e){var n=this.rules.block.blockquote.exec(e);if(n){e=n[0].replace(/^ *> ?/gm,"");return{type:"blockquote",raw:n[0],text:e}}},e.prototype.list=function(e){e=this.rules.block.list.exec(e);if(e){for(var n,i,o,t,a,r=e[0],c=e[2],u=1<c.length,f={type:"list",raw:r,ordered:u,start:u?+c.slice(0,-1):"",loose:!1,items:[]},p=e[0].match(this.rules.block.item),d=!1,g=p.length,s=this.rules.block.listItemStart.exec(p[0]),l=0;l<g;l++){if(r=n=p[l],l!==g-1){if(o=this.rules.block.listItemStart.exec(p[l+1]),this.options.pedantic?o[1].length>s[1].length:o[1].length>s[0].length||3<o[1].length){p.splice(l,2,p[l]+"\n"+p[l+1]),l--,g--;continue}(!this.options.pedantic||this.options.smartLists?o[2][o[2].length-1]!==c[c.length-1]:u==(1===o[2].length))&&(i=p.slice(l+1).join("\n"),f.raw=f.raw.substring(0,f.raw.length-i.length),l=g-1),s=o}o=n.length,~(n=n.replace(/^ *([*+-]|\d+[.)]) ?/,"")).indexOf("\n ")&&(o-=n.length,n=this.options.pedantic?n.replace(/^ {1,4}/gm,""):n.replace(new RegExp("^ {1,"+o+"}","gm"),"")),o=d||/\n\n(?!\s*$)/.test(n),l!==g-1&&(d="\n"===n.charAt(n.length-1),o=o||d),o&&(f.loose=!0),this.options.gfm&&(a=void 0,(t=/^\[[ xX]\] /.test(n))&&(a=" "!==n[1],n=n.replace(/^\[[ xX]\] +/,""))),f.items.push({type:"list_item",raw:r,task:t,checked:a,loose:o,text:n})}return f}},e.prototype.html=function(e){e=this.rules.block.html.exec(e);if(e)return{type:this.options.sanitize?"paragraph":"html",raw:e[0],pre:!this.options.sanitizer&&("pre"===e[1]||"script"===e[1]||"style"===e[1]),text:this.options.sanitize?this.options.sanitizer?this.options.sanitizer(e[0]):Je(e[0]):e[0]}},e.prototype.def=function(e){e=this.rules.block.def.exec(e);if(e)return e[3]&&(e[3]=e[3].substring(1,e[3].length-1)),{tag:e[1].toLowerCase().replace(/\s+/g," "),raw:e[0],href:e[2],title:e[3]}},e.prototype.table=function(e){e=this.rules.block.table.exec(e);if(e){var n={type:"table",header:Qe(e[1].replace(/^ *| *\| *$/g,"")),align:e[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:e[3]?e[3].replace(/\n$/,"").split("\n"):[]};if(n.header.length===n.align.length){n.raw=e[0];for(var i=n.align.length,o=0;o<i;o++)/^ *-+: *$/.test(n.align[o])?n.align[o]="right":/^ *:-+: *$/.test(n.align[o])?n.align[o]="center":/^ *:-+ *$/.test(n.align[o])?n.align[o]="left":n.align[o]=null;for(i=n.cells.length,o=0;o<i;o++)n.cells[o]=Qe(n.cells[o].replace(/^ *\| *| *\| *$/g,""),n.header.length);return n}}},e.prototype.lheading=function(e){e=this.rules.block.lheading.exec(e);if(e)return{type:"heading",raw:e[0],depth:"="===e[2].charAt(0)?1:2,text:e[1]}},e.prototype.paragraph=function(e){e=this.rules.block.paragraph.exec(e);if(e)return{type:"paragraph",raw:e[0],text:"\n"===e[1].charAt(e[1].length-1)?e[1].slice(0,-1):e[1]}},e.prototype.text=function(e,n){e=this.rules.block.text.exec(e);if(e){n=n[n.length-1];return n&&"text"===n.type?{raw:e[0],text:e[0]}:{type:"text",raw:e[0],text:e[0]}}},e.prototype.escape=function(e){e=this.rules.inline.escape.exec(e);if(e)return{type:"escape",raw:e[0],text:Je(e[1])}},e.prototype.tag=function(e,n,i){e=this.rules.inline.tag.exec(e);if(e)return!n&&/^<a /i.test(e[0])?n=!0:n&&/^<\/a>/i.test(e[0])&&(n=!1),!i&&/^<(pre|code|kbd|script)(\s|>)/i.test(e[0])?i=!0:i&&/^<\/(pre|code|kbd|script)(\s|>)/i.test(e[0])&&(i=!1),{type:this.options.sanitize?"text":"html",raw:e[0],inLink:n,inRawBlock:i,text:this.options.sanitize?this.options.sanitizer?this.options.sanitizer(e[0]):Je(e[0]):e[0]}},e.prototype.link=function(e){var n=this.rules.inline.link.exec(e);if(n){e=n[2].trim();if(!this.options.pedantic&&/^</.test(e)){if(!/>$/.test(e))return;var i=Xe(e.slice(0,-1),"\\");if((e.length-i.length)%2==0)return}else{var o=Ke(n[2],"()");-1<o&&(t=(0===n[0].indexOf("!")?5:4)+n[1].length+o,n[2]=n[2].substring(0,o),n[0]=n[0].substring(0,t).trim(),n[3]="")}var t,i=n[2],o="";return this.options.pedantic?(t=/^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(i))&&(i=t[1],o=t[3]):o=n[3]?n[3].slice(1,-1):"",i=i.trim(),en(n,{href:(i=/^</.test(i)?this.options.pedantic&&!/>$/.test(e)?i.slice(1):i.slice(1,-1):i)&&i.replace(this.rules.inline._escapes,"$1"),title:o&&o.replace(this.rules.inline._escapes,"$1")},n[0])}},e.prototype.reflink=function(e,n){if((i=this.rules.inline.reflink.exec(e))||(i=this.rules.inline.nolink.exec(e))){var e=(i[2]||i[1]).replace(/\s+/g," ");if((e=n[e.toLowerCase()])&&e.href)return en(i,e,i[0]);var i=i[0].charAt(0);return{type:"text",raw:i,text:i}}},e.prototype.strong=function(e,n,i){void 0===i&&(i="");var o=this.rules.inline.strong.start.exec(e);if(o&&(!o[1]||o[1]&&(""===i||this.rules.inline.punctuation.exec(i)))){n=n.slice(-1*e.length);var t,a="**"===o[0]?this.rules.inline.strong.endAst:this.rules.inline.strong.endUnd;for(a.lastIndex=0;null!=(o=a.exec(n));)if(t=this.rules.inline.strong.middle.exec(n.slice(0,o.index+3)))return{type:"strong",raw:e.slice(0,t[0].length),text:e.slice(2,t[0].length-2)}}},e.prototype.em=function(e,n,i){void 0===i&&(i="");var o=this.rules.inline.em.start.exec(e);if(o&&(!o[1]||o[1]&&(""===i||this.rules.inline.punctuation.exec(i)))){n=n.slice(-1*e.length);var t,a="*"===o[0]?this.rules.inline.em.endAst:this.rules.inline.em.endUnd;for(a.lastIndex=0;null!=(o=a.exec(n));)if(t=this.rules.inline.em.middle.exec(n.slice(0,o.index+2)))return{type:"em",raw:e.slice(0,t[0].length),text:e.slice(1,t[0].length-1)}}},e.prototype.codespan=function(e){var n=this.rules.inline.code.exec(e);if(n){var i=n[2].replace(/\n/g," "),o=/[^ ]/.test(i),e=/^ /.test(i)&&/ $/.test(i);return o&&e&&(i=i.substring(1,i.length-1)),i=Je(i,!0),{type:"codespan",raw:n[0],text:i}}},e.prototype.br=function(e){e=this.rules.inline.br.exec(e);if(e)return{type:"br",raw:e[0]}},e.prototype.del=function(e){e=this.rules.inline.del.exec(e);if(e)return{type:"del",raw:e[0],text:e[2]}},e.prototype.autolink=function(e,n){e=this.rules.inline.autolink.exec(e);if(e){var i,n="@"===e[2]?"mailto:"+(i=Je(this.options.mangle?n(e[1]):e[1])):i=Je(e[1]);return{type:"link",raw:e[0],text:i,href:n,tokens:[{type:"text",raw:i,text:i}]}}},e.prototype.url=function(e,n){var i,o,t,a;if(i=this.rules.inline.url.exec(e)){if("@"===i[2])t="mailto:"+(o=Je(this.options.mangle?n(i[0]):i[0]));else{for(;a=i[0],i[0]=this.rules.inline._backpedal.exec(i[0])[0],a!==i[0];);o=Je(i[0]),t="www."===i[1]?"http://"+o:o}return{type:"link",raw:i[0],text:o,href:t,tokens:[{type:"text",raw:o,text:o}]}}},e.prototype.inlineText=function(e,n,i){e=this.rules.inline.text.exec(e);if(e){i=n?this.options.sanitize?this.options.sanitizer?this.options.sanitizer(e[0]):Je(e[0]):e[0]:Je(this.options.smartypants?i(e[0]):e[0]);return{type:"text",raw:e[0],text:i}}},e}(),Ze=De,Ve=Ne,De=Ue,Ne={newline:/^(?: *(?:\n|$))+/,code:/^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,fences:/^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?:\n+|$)|$)/,hr:/^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,heading:/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,blockquote:/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,list:/^( {0,3})(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?! {0,3}bull )\n*|\s*$)/,html:"^ {0,3}(?:<(script|pre|style)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:\\n{2,}|$)|<(?!script|pre|style)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:\\n{2,}|$)|</(?!script|pre|style)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:\\n{2,}|$))",def:/^ {0,3}\[(label)\]: *\n? *<?([^\s>]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,nptable:Ze,table:Ze,lheading:/^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/,_paragraph:/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html| +\n)[^\n]+)*)/,text:/^[^\n]+/,_label:/(?!\s*\])(?:\\[\[\]]|[^\[\]])+/,_title:/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/};Ne.def=Ve(Ne.def).replace("label",Ne._label).replace("title",Ne._title).getRegex(),Ne.bullet=/(?:[*+-]|\d{1,9}[.)])/,Ne.item=/^( *)(bull) ?[^\n]*(?:\n(?! *bull ?)[^\n]*)*/,Ne.item=Ve(Ne.item,"gm").replace(/bull/g,Ne.bullet).getRegex(),Ne.listItemStart=Ve(/^( *)(bull)/).replace("bull",Ne.bullet).getRegex(),Ne.list=Ve(Ne.list).replace(/bull/g,Ne.bullet).replace("hr","\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def","\\n+(?="+Ne.def.source+")").getRegex(),Ne._tag="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",Ne._comment=/<!--(?!-?>)[\s\S]*?(?:-->|$)/,Ne.html=Ve(Ne.html,"i").replace("comment",Ne._comment).replace("tag",Ne._tag).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),Ne.paragraph=Ve(Ne._paragraph).replace("hr",Ne.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|!--)").replace("tag",Ne._tag).getRegex(),Ne.blockquote=Ve(Ne.blockquote).replace("paragraph",Ne.paragraph).getRegex(),Ne.normal=De({},Ne),Ne.gfm=De({},Ne.normal,{nptable:"^ *([^|\\n ].*\\|.*)\\n {0,3}([-:]+ *\\|[-| :]*)(?:\\n((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)",table:"^ *\\|(.+)\\n {0,3}\\|?( *[-:]+[-| :]*)(?:\\n *((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)"}),Ne.gfm.nptable=Ve(Ne.gfm.nptable).replace("hr",Ne.hr).replace("heading"," {0,3}#{1,6} ").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|!--)").replace("tag",Ne._tag).getRegex(),Ne.gfm.table=Ve(Ne.gfm.table).replace("hr",Ne.hr).replace("heading"," {0,3}#{1,6} ").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|!--)").replace("tag",Ne._tag).getRegex(),Ne.pedantic=De({},Ne.normal,{html:Ve("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:\"[^\"]*\"|'[^']*'|\\s[^'\"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",Ne._comment).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:Ze,paragraph:Ve(Ne.normal._paragraph).replace("hr",Ne.hr).replace("heading"," *#{1,6} *[^\n]").replace("lheading",Ne.lheading).replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").getRegex()});Ze={escape:/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,autolink:/^<(scheme:[^\s\x00-\x1f<>]*|email)>/,url:Ze,tag:"^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>",link:/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,reflink:/^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,nolink:/^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,reflinkSearch:"reflink|nolink(?!\\()",strong:{start:/^(?:(\*\*(?=[*punctuation]))|\*\*)(?![\s])|__/,middle:/^\*\*(?:(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)|\*(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)*?\*)+?\*\*$|^__(?![\s])((?:(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)|_(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)*?_)+?)__$/,endAst:/[^punctuation\s]\*\*(?!\*)|[punctuation]\*\*(?!\*)(?:(?=[punctuation_\s]|$))/,endUnd:/[^\s]__(?!_)(?:(?=[punctuation*\s])|$)/},em:{start:/^(?:(\*(?=[punctuation]))|\*)(?![*\s])|_/,middle:/^\*(?:(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)|\*(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)*?\*)+?\*$|^_(?![_\s])(?:(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)|_(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)*?_)+?_$/,endAst:/[^punctuation\s]\*(?!\*)|[punctuation]\*(?!\*)(?:(?=[punctuation_\s]|$))/,endUnd:/[^\s]_(?!_)(?:(?=[punctuation*\s])|$)/},code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,br:/^( {2,}|\\)\n(?!\s*$)/,del:Ze,text:/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*]|\b_|$)|[^ ](?= {2,}\n)))/,punctuation:/^([\s*punctuation])/,_punctuation:"!\"#$%&'()+\\-.,/:;<=>?@\\[\\]`^{|}~"};Ze.punctuation=Ve(Ze.punctuation).replace(/punctuation/g,Ze._punctuation).getRegex(),Ze._blockSkip="\\[[^\\]]*?\\]\\([^\\)]*?\\)|`[^`]*?`|<[^>]*?>",Ze._overlapSkip="__[^_]*?__|\\*\\*\\[^\\*\\]*?\\*\\*",Ze._comment=Ve(Ne._comment).replace("(?:--\x3e|$)","--\x3e").getRegex(),Ze.em.start=Ve(Ze.em.start).replace(/punctuation/g,Ze._punctuation).getRegex(),Ze.em.middle=Ve(Ze.em.middle).replace(/punctuation/g,Ze._punctuation).replace(/overlapSkip/g,Ze._overlapSkip).getRegex(),Ze.em.endAst=Ve(Ze.em.endAst,"g").replace(/punctuation/g,Ze._punctuation).getRegex(),Ze.em.endUnd=Ve(Ze.em.endUnd,"g").replace(/punctuation/g,Ze._punctuation).getRegex(),Ze.strong.start=Ve(Ze.strong.start).replace(/punctuation/g,Ze._punctuation).getRegex(),Ze.strong.middle=Ve(Ze.strong.middle).replace(/punctuation/g,Ze._punctuation).replace(/overlapSkip/g,Ze._overlapSkip).getRegex(),Ze.strong.endAst=Ve(Ze.strong.endAst,"g").replace(/punctuation/g,Ze._punctuation).getRegex(),Ze.strong.endUnd=Ve(Ze.strong.endUnd,"g").replace(/punctuation/g,Ze._punctuation).getRegex(),Ze.blockSkip=Ve(Ze._blockSkip,"g").getRegex(),Ze.overlapSkip=Ve(Ze._overlapSkip,"g").getRegex(),Ze._escapes=/\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g,Ze._scheme=/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/,Ze._email=/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/,Ze.autolink=Ve(Ze.autolink).replace("scheme",Ze._scheme).replace("email",Ze._email).getRegex(),Ze._attribute=/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/,Ze.tag=Ve(Ze.tag).replace("comment",Ze._comment).replace("attribute",Ze._attribute).getRegex(),Ze._label=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,Ze._href=/<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/,Ze._title=/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/,Ze.link=Ve(Ze.link).replace("label",Ze._label).replace("href",Ze._href).replace("title",Ze._title).getRegex(),Ze.reflink=Ve(Ze.reflink).replace("label",Ze._label).getRegex(),Ze.reflinkSearch=Ve(Ze.reflinkSearch,"g").replace("reflink",Ze.reflink).replace("nolink",Ze.nolink).getRegex(),Ze.normal=De({},Ze),Ze.pedantic=De({},Ze.normal,{strong:{start:/^__|\*\*/,middle:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,endAst:/\*\*(?!\*)/g,endUnd:/__(?!_)/g},em:{start:/^_|\*/,middle:/^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,endAst:/\*(?!\*)/g,endUnd:/_(?!_)/g},link:Ve(/^!?\[(label)\]\((.*?)\)/).replace("label",Ze._label).getRegex(),reflink:Ve(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",Ze._label).getRegex()}),Ze.gfm=De({},Ze.normal,{escape:Ve(Ze.escape).replace("])","~|])").getRegex(),_extended_email:/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,url:/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,_backpedal:/(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*~]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))/}),Ze.gfm.url=Ve(Ze.gfm.url,"i").replace("email",Ze.gfm._extended_email).getRegex(),Ze.breaks=De({},Ze.gfm,{br:Ve(Ze.br).replace("{2,}","*").getRegex(),text:Ve(Ze.gfm.text).replace("\\b_","\\b_| {2,}\\n").replace(/\{2,\}/g,"*").getRegex()});var Ze={block:Ne,inline:Ze},on=we.defaults,tn=Ze.block,an=Ze.inline,rn=Ge;function cn(e){return e.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…")}function un(e){for(var n,i="",o=e.length,t=0;t<o;t++)n=e.charCodeAt(t),i+="&#"+(n=.5<Math.random()?"x"+n.toString(16):n)+";";return i}var fn=function(){function i(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||on,this.options.tokenizer=this.options.tokenizer||new nn,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options;e={block:tn.normal,inline:an.normal};this.options.pedantic?(e.block=tn.pedantic,e.inline=an.pedantic):this.options.gfm&&(e.block=tn.gfm,this.options.breaks?e.inline=an.breaks:e.inline=an.gfm),this.tokenizer.rules=e}var e={rules:{configurable:!0}};return e.rules.get=function(){return{block:tn,inline:an}},i.lex=function(e,n){return new i(n).lex(e)},i.lexInline=function(e,n){return new i(n).inlineTokens(e)},i.prototype.lex=function(e){return e=e.replace(/\r\n|\r/g,"\n").replace(/\t/g," "),this.blockTokens(e,this.tokens,!0),this.inline(this.tokens),this.tokens},i.prototype.blockTokens=function(e,n,i){var o,t,a,r;for(void 0===n&&(n=[]),void 0===i&&(i=!0),this.options.pedantic&&(e=e.replace(/^ +$/gm,""));e;)if(o=this.tokenizer.space(e))e=e.substring(o.raw.length),o.type&&n.push(o);else if(o=this.tokenizer.code(e,n))e=e.substring(o.raw.length),o.type?n.push(o):((r=n[n.length-1]).raw+="\n"+o.raw,r.text+="\n"+o.text);else if(o=this.tokenizer.fences(e))e=e.substring(o.raw.length),n.push(o);else if(o=this.tokenizer.heading(e))e=e.substring(o.raw.length),n.push(o);else if(o=this.tokenizer.nptable(e))e=e.substring(o.raw.length),n.push(o);else if(o=this.tokenizer.hr(e))e=e.substring(o.raw.length),n.push(o);else if(o=this.tokenizer.blockquote(e))e=e.substring(o.raw.length),o.tokens=this.blockTokens(o.text,[],i),n.push(o);else if(o=this.tokenizer.list(e)){for(e=e.substring(o.raw.length),a=o.items.length,t=0;t<a;t++)o.items[t].tokens=this.blockTokens(o.items[t].text,[],!1);n.push(o)}else if(o=this.tokenizer.html(e))e=e.substring(o.raw.length),n.push(o);else if(i&&(o=this.tokenizer.def(e)))e=e.substring(o.raw.length),this.tokens.links[o.tag]||(this.tokens.links[o.tag]={href:o.href,title:o.title});else if(o=this.tokenizer.table(e))e=e.substring(o.raw.length),n.push(o);else if(o=this.tokenizer.lheading(e))e=e.substring(o.raw.length),n.push(o);else if(i&&(o=this.tokenizer.paragraph(e)))e=e.substring(o.raw.length),n.push(o);else if(o=this.tokenizer.text(e,n))e=e.substring(o.raw.length),o.type?n.push(o):((r=n[n.length-1]).raw+="\n"+o.raw,r.text+="\n"+o.text);else if(e){var c="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(c);break}throw new Error(c)}return n},i.prototype.inline=function(e){for(var n,i,o,t,a,r=e.length,c=0;c<r;c++)switch((a=e[c]).type){case"paragraph":case"text":case"heading":a.tokens=[],this.inlineTokens(a.text,a.tokens);break;case"table":for(a.tokens={header:[],cells:[]},o=a.header.length,n=0;n<o;n++)a.tokens.header[n]=[],this.inlineTokens(a.header[n],a.tokens.header[n]);for(o=a.cells.length,n=0;n<o;n++)for(t=a.cells[n],a.tokens.cells[n]=[],i=0;i<t.length;i++)a.tokens.cells[n][i]=[],this.inlineTokens(t[i],a.tokens.cells[n][i]);break;case"blockquote":this.inline(a.tokens);break;case"list":for(o=a.items.length,n=0;n<o;n++)this.inline(a.items[n].tokens)}return e},i.prototype.inlineTokens=function(e,n,i,o){var t;void 0===n&&(n=[]),void 0===i&&(i=!1),void 0===o&&(o=!1);var a,r,c,u=e;if(this.tokens.links){var f=Object.keys(this.tokens.links);if(0<f.length)for(;null!=(a=this.tokenizer.rules.inline.reflinkSearch.exec(u));)f.includes(a[0].slice(a[0].lastIndexOf("[")+1,-1))&&(u=u.slice(0,a.index)+"["+rn("a",a[0].length-2)+"]"+u.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;null!=(a=this.tokenizer.rules.inline.blockSkip.exec(u));)u=u.slice(0,a.index)+"["+rn("a",a[0].length-2)+"]"+u.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);for(;e;)if(r||(c=""),r=!1,t=this.tokenizer.escape(e))e=e.substring(t.raw.length),n.push(t);else if(t=this.tokenizer.tag(e,i,o))e=e.substring(t.raw.length),i=t.inLink,o=t.inRawBlock,n.push(t);else if(t=this.tokenizer.link(e))e=e.substring(t.raw.length),"link"===t.type&&(t.tokens=this.inlineTokens(t.text,[],!0,o)),n.push(t);else if(t=this.tokenizer.reflink(e,this.tokens.links))e=e.substring(t.raw.length),"link"===t.type&&(t.tokens=this.inlineTokens(t.text,[],!0,o)),n.push(t);else if(t=this.tokenizer.strong(e,u,c))e=e.substring(t.raw.length),t.tokens=this.inlineTokens(t.text,[],i,o),n.push(t);else if(t=this.tokenizer.em(e,u,c))e=e.substring(t.raw.length),t.tokens=this.inlineTokens(t.text,[],i,o),n.push(t);else if(t=this.tokenizer.codespan(e))e=e.substring(t.raw.length),n.push(t);else if(t=this.tokenizer.br(e))e=e.substring(t.raw.length),n.push(t);else if(t=this.tokenizer.del(e))e=e.substring(t.raw.length),t.tokens=this.inlineTokens(t.text,[],i,o),n.push(t);else if(t=this.tokenizer.autolink(e,un))e=e.substring(t.raw.length),n.push(t);else if(i||!(t=this.tokenizer.url(e,un))){if(t=this.tokenizer.inlineText(e,o,cn))e=e.substring(t.raw.length),c=t.raw.slice(-1),r=!0,n.push(t);else if(e){var p="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(p);break}throw new Error(p)}}else e=e.substring(t.raw.length),n.push(t);return n},Object.defineProperties(i,e),i}(),pn=we.defaults,dn=He,gn=Me,sn=function(){function e(e){this.options=e||pn}return e.prototype.code=function(e,n,i){var o=(n||"").match(/\S*/)[0];return!this.options.highlight||null!=(n=this.options.highlight(e,o))&&n!==e&&(i=!0,e=n),e=e.replace(/\n$/,"")+"\n",o?'<pre><code class="'+this.options.langPrefix+gn(o,!0)+'">'+(i?e:gn(e,!0))+"</code></pre>\n":"<pre><code>"+(i?e:gn(e,!0))+"</code></pre>\n"},e.prototype.blockquote=function(e){return"<blockquote>\n"+e+"</blockquote>\n"},e.prototype.html=function(e){return e},e.prototype.heading=function(e,n,i,o){return this.options.headerIds?"<h"+n+' id="'+this.options.headerPrefix+o.slug(i)+'">'+e+"</h"+n+">\n":"<h"+n+">"+e+"</h"+n+">\n"},e.prototype.hr=function(){return this.options.xhtml?"<hr/>\n":"<hr>\n"},e.prototype.list=function(e,n,i){var o=n?"ol":"ul";return"<"+o+(n&&1!==i?' start="'+i+'"':"")+">\n"+e+"</"+o+">\n"},e.prototype.listitem=function(e){return"<li>"+e+"</li>\n"},e.prototype.checkbox=function(e){return"<input "+(e?'checked="" ':"")+'disabled="" type="checkbox"'+(this.options.xhtml?" /":"")+"> "},e.prototype.paragraph=function(e){return"<p>"+e+"</p>\n"},e.prototype.table=function(e,n){return"<table>\n<thead>\n"+e+"</thead>\n"+(n=n&&"<tbody>"+n+"</tbody>")+"</table>\n"},e.prototype.tablerow=function(e){return"<tr>\n"+e+"</tr>\n"},e.prototype.tablecell=function(e,n){var i=n.header?"th":"td";return(n.align?"<"+i+' align="'+n.align+'">':"<"+i+">")+e+"</"+i+">\n"},e.prototype.strong=function(e){return"<strong>"+e+"</strong>"},e.prototype.em=function(e){return"<em>"+e+"</em>"},e.prototype.codespan=function(e){return"<code>"+e+"</code>"},e.prototype.br=function(){return this.options.xhtml?"<br/>":"<br>"},e.prototype.del=function(e){return"<del>"+e+"</del>"},e.prototype.link=function(e,n,i){if(null===(e=dn(this.options.sanitize,this.options.baseUrl,e)))return i;e='<a href="'+gn(e)+'"';return n&&(e+=' title="'+n+'"'),e+=">"+i+"</a>"},e.prototype.image=function(e,n,i){if(null===(e=dn(this.options.sanitize,this.options.baseUrl,e)))return i;i='<img src="'+e+'" alt="'+i+'"';return n&&(i+=' title="'+n+'"'),i+=this.options.xhtml?"/>":">"},e.prototype.text=function(e){return e},e}(),ln=function(){function e(){}return e.prototype.strong=function(e){return e},e.prototype.em=function(e){return e},e.prototype.codespan=function(e){return e},e.prototype.del=function(e){return e},e.prototype.html=function(e){return e},e.prototype.text=function(e){return e},e.prototype.link=function(e,n,i){return""+i},e.prototype.image=function(e,n,i){return""+i},e.prototype.br=function(){return""},e}(),vn=function(){function e(){this.seen={}}return e.prototype.serialize=function(e){return e.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi,"").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g,"").replace(/\s/g,"-")},e.prototype.getNextSafeSlug=function(e,n){var i=e,o=0;if(this.seen.hasOwnProperty(i))for(o=this.seen[e];i=e+"-"+ ++o,this.seen.hasOwnProperty(i););return n||(this.seen[e]=o,this.seen[i]=0),i},e.prototype.slug=function(e,n){void 0===n&&(n={});e=this.serialize(e);return this.getNextSafeSlug(e,n.dryrun)},e}(),hn=we.defaults,_n=Ie,mn=function(){function i(e){this.options=e||hn,this.options.renderer=this.options.renderer||new sn,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new ln,this.slugger=new vn}return i.parse=function(e,n){return new i(n).parse(e)},i.parseInline=function(e,n){return new i(n).parseInline(e)},i.prototype.parse=function(e,n){void 0===n&&(n=!0);for(var i,o,t,a,r,c,u,f,p,d,g,s,l,v,h,_="",m=e.length,b=0;b<m;b++)switch((f=e[b]).type){case"space":continue;case"hr":_+=this.renderer.hr();continue;case"heading":_+=this.renderer.heading(this.parseInline(f.tokens),f.depth,_n(this.parseInline(f.tokens,this.textRenderer)),this.slugger);continue;case"code":_+=this.renderer.code(f.text,f.lang,f.escaped);continue;case"table":for(c=p="",t=f.header.length,i=0;i<t;i++)c+=this.renderer.tablecell(this.parseInline(f.tokens.header[i]),{header:!0,align:f.align[i]});for(p+=this.renderer.tablerow(c),u="",t=f.cells.length,i=0;i<t;i++){for(c="",a=(r=f.tokens.cells[i]).length,o=0;o<a;o++)c+=this.renderer.tablecell(this.parseInline(r[o]),{header:!1,align:f.align[o]});u+=this.renderer.tablerow(c)}_+=this.renderer.table(p,u);continue;case"blockquote":u=this.parse(f.tokens),_+=this.renderer.blockquote(u);continue;case"list":for(p=f.ordered,k=f.start,d=f.loose,t=f.items.length,u="",i=0;i<t;i++)l=(s=f.items[i]).checked,v=s.task,g="",s.task&&(h=this.renderer.checkbox(l),d?0<s.tokens.length&&"text"===s.tokens[0].type?(s.tokens[0].text=h+" "+s.tokens[0].text,s.tokens[0].tokens&&0<s.tokens[0].tokens.length&&"text"===s.tokens[0].tokens[0].type&&(s.tokens[0].tokens[0].text=h+" "+s.tokens[0].tokens[0].text)):s.tokens.unshift({type:"text",text:h}):g+=h),g+=this.parse(s.tokens,d),u+=this.renderer.listitem(g,v,l);_+=this.renderer.list(u,p,k);continue;case"html":_+=this.renderer.html(f.text);continue;case"paragraph":_+=this.renderer.paragraph(this.parseInline(f.tokens));continue;case"text":for(u=f.tokens?this.parseInline(f.tokens):f.text;b+1<m&&"text"===e[b+1].type;)u+="\n"+((f=e[++b]).tokens?this.parseInline(f.tokens):f.text);_+=n?this.renderer.paragraph(u):u;continue;default:var k='Token with "'+f.type+'" type was not found.';if(this.options.silent)return void console.error(k);throw new Error(k)}return _},i.prototype.parseInline=function(e,n){n=n||this.renderer;for(var i,o="",t=e.length,a=0;a<t;a++)switch((i=e[a]).type){case"escape":o+=n.text(i.text);break;case"html":o+=n.html(i.text);break;case"link":o+=n.link(i.href,i.title,this.parseInline(i.tokens,n));break;case"image":o+=n.image(i.href,i.title,i.text);break;case"strong":o+=n.strong(this.parseInline(i.tokens,n));break;case"em":o+=n.em(this.parseInline(i.tokens,n));break;case"codespan":o+=n.codespan(i.text);break;case"br":o+=n.br();break;case"del":o+=n.del(this.parseInline(i.tokens,n));break;case"text":o+=n.text(i.text);break;default:var r='Token with "'+i.type+'" type was not found.';if(this.options.silent)return void console.error(r);throw new Error(r)}return o},i}(),bn=Ue,kn=Ye,wn=Me,Me=we.getDefaults,yn=we.changeDefaults,we=we.defaults;function xn(e,i,o){if(null==e)throw new Error("marked(): input parameter is undefined or null");if("string"!=typeof e)throw new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected");if("function"==typeof i&&(o=i,i=null),i=bn({},xn.defaults,i||{}),kn(i),o){var t,a=i.highlight;try{t=fn.lex(e,i)}catch(e){return o(e)}function r(n){var e;if(!n)try{e=mn.parse(t,i)}catch(e){n=e}return i.highlight=a,n?o(n):o(null,e)}if(!a||a.length<3)return r();if(delete i.highlight,!t.length)return r();var c=0;return xn.walkTokens(t,function(i){"code"===i.type&&(c++,setTimeout(function(){a(i.text,i.lang,function(e,n){return e?r(e):(null!=n&&n!==i.text&&(i.text=n,i.escaped=!0),void(0===--c&&r()))})},0))}),void(0===c&&r())}try{var n=fn.lex(e,i);return i.walkTokens&&xn.walkTokens(n,i.walkTokens),mn.parse(n,i)}catch(e){if(e.message+="\nPlease report this to https://github.com/markedjs/marked.",i.silent)return"<p>An error occurred:</p><pre>"+wn(e.message+"",!0)+"</pre>";throw e}}xn.options=xn.setOptions=function(e){return bn(xn.defaults,e),yn(xn.defaults),xn},xn.getDefaults=Me,xn.defaults=we,xn.use=function(a){var n,e=bn({},a);if(a.renderer){var i,r=xn.defaults.renderer||new sn;for(i in a.renderer)!function(o){var t=r[o];r[o]=function(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];var i=a.renderer[o].apply(r,e);return i=!1===i?t.apply(r,e):i}}(i);e.renderer=r}if(a.tokenizer){var t,c=xn.defaults.tokenizer||new nn;for(t in a.tokenizer)!function(){var o=c[t];c[t]=function(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];var i=a.tokenizer[t].apply(c,e);return i=!1===i?o.apply(c,e):i}}();e.tokenizer=c}a.walkTokens&&(n=xn.defaults.walkTokens,e.walkTokens=function(e){a.walkTokens(e),n&&n(e)}),xn.setOptions(e)},xn.walkTokens=function(e,n){for(var i=0,o=e;i<o.length;i+=1){var t=o[i];switch(n(t),t.type){case"table":for(var a=0,r=t.tokens.header;a<r.length;a+=1){var c=r[a];xn.walkTokens(c,n)}for(var u=0,f=t.tokens.cells;u<f.length;u+=1)for(var p=0,d=f[u];p<d.length;p+=1){var g=d[p];xn.walkTokens(g,n)}break;case"list":xn.walkTokens(t.items,n);break;default:t.tokens&&xn.walkTokens(t.tokens,n)}}},xn.parseInline=function(e,n){if(null==e)throw new Error("marked.parseInline(): input parameter is undefined or null");if("string"!=typeof e)throw new Error("marked.parseInline(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected");n=bn({},xn.defaults,n||{}),kn(n);try{var i=fn.lexInline(e,n);return n.walkTokens&&xn.walkTokens(i,n.walkTokens),mn.parseInline(i,n)}catch(e){if(e.message+="\nPlease report this to https://github.com/markedjs/marked.",n.silent)return"<p>An error occurred:</p><pre>"+wn(e.message+"",!0)+"</pre>";throw e}},xn.Parser=mn,xn.parser=mn.parse,xn.Renderer=sn,xn.TextRenderer=ln,xn.Lexer=fn,xn.lexer=fn.lex,xn.Tokenizer=nn,xn.Slugger=vn;var Sn=xn.parse=xn;function An(e,i){if(void 0===i&&(i='<ul class="app-sub-sidebar">{inner}</ul>'),!e||!e.length)return"";var o="";return e.forEach(function(e){var n=e.title.replace(/(<([^>]+)>)/g,"");o+='<li><a class="section-link" href="'+e.slug+'" title="'+n+'">'+e.title+"</a></li>",e.children&&(o+=An(e.children,i))}),i.replace("{inner}",o)}function $n(e,n){return'<p class="'+e+'">'+n.slice(5).trim()+"</p>"}function zn(e,o){var t=[],a={};return e.forEach(function(e){var n=e.level||1,i=n-1;o<n||(a[i]?a[i].children=(a[i].children||[]).concat(e):t.push(e),a[n]=e)}),t}var Fn={},En=/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g;function Tn(e){return e.toLowerCase()}function Cn(e){if("string"!=typeof e)return"";var n=e.trim().replace(/[A-Z]+/g,Tn).replace(/<[^>]+>/g,"").replace(En,"").replace(/\s/g,"-").replace(/-+/g,"-").replace(/^(\d)/,"_$1"),e=Fn[n],e=u.call(Fn,n)?e+1:0;return n=(Fn[n]=e)?n+"-"+e:n}Cn.clear=function(){Fn={}};var Rn={baseURL:"https://github.githubassets.com/images/icons/emoji/",data:{100:"unicode/1f4af.png?v8",1234:"unicode/1f522.png?v8","+1":"unicode/1f44d.png?v8","-1":"unicode/1f44e.png?v8","1st_place_medal":"unicode/1f947.png?v8","2nd_place_medal":"unicode/1f948.png?v8","3rd_place_medal":"unicode/1f949.png?v8","8ball":"unicode/1f3b1.png?v8",a:"unicode/1f170.png?v8",ab:"unicode/1f18e.png?v8",abacus:"unicode/1f9ee.png?v8",abc:"unicode/1f524.png?v8",abcd:"unicode/1f521.png?v8",accept:"unicode/1f251.png?v8",accordion:"unicode/1fa97.png?v8",adhesive_bandage:"unicode/1fa79.png?v8",adult:"unicode/1f9d1.png?v8",aerial_tramway:"unicode/1f6a1.png?v8",afghanistan:"unicode/1f1e6-1f1eb.png?v8",airplane:"unicode/2708.png?v8",aland_islands:"unicode/1f1e6-1f1fd.png?v8",alarm_clock:"unicode/23f0.png?v8",albania:"unicode/1f1e6-1f1f1.png?v8",alembic:"unicode/2697.png?v8",algeria:"unicode/1f1e9-1f1ff.png?v8",alien:"unicode/1f47d.png?v8",ambulance:"unicode/1f691.png?v8",american_samoa:"unicode/1f1e6-1f1f8.png?v8",amphora:"unicode/1f3fa.png?v8",anatomical_heart:"unicode/1fac0.png?v8",anchor:"unicode/2693.png?v8",andorra:"unicode/1f1e6-1f1e9.png?v8",angel:"unicode/1f47c.png?v8",anger:"unicode/1f4a2.png?v8",angola:"unicode/1f1e6-1f1f4.png?v8",angry:"unicode/1f620.png?v8",anguilla:"unicode/1f1e6-1f1ee.png?v8",anguished:"unicode/1f627.png?v8",ant:"unicode/1f41c.png?v8",antarctica:"unicode/1f1e6-1f1f6.png?v8",antigua_barbuda:"unicode/1f1e6-1f1ec.png?v8",apple:"unicode/1f34e.png?v8",aquarius:"unicode/2652.png?v8",argentina:"unicode/1f1e6-1f1f7.png?v8",aries:"unicode/2648.png?v8",armenia:"unicode/1f1e6-1f1f2.png?v8",arrow_backward:"unicode/25c0.png?v8",arrow_double_down:"unicode/23ec.png?v8",arrow_double_up:"unicode/23eb.png?v8",arrow_down:"unicode/2b07.png?v8",arrow_down_small:"unicode/1f53d.png?v8",arrow_forward:"unicode/25b6.png?v8",arrow_heading_down:"unicode/2935.png?v8",arrow_heading_up:"unicode/2934.png?v8",arrow_left:"unicode/2b05.png?v8",arrow_lower_left:"unicode/2199.png?v8",arrow_lower_right:"unicode/2198.png?v8",arrow_right:"unicode/27a1.png?v8",arrow_right_hook:"unicode/21aa.png?v8",arrow_up:"unicode/2b06.png?v8",arrow_up_down:"unicode/2195.png?v8",arrow_up_small:"unicode/1f53c.png?v8",arrow_upper_left:"unicode/2196.png?v8",arrow_upper_right:"unicode/2197.png?v8",arrows_clockwise:"unicode/1f503.png?v8",arrows_counterclockwise:"unicode/1f504.png?v8",art:"unicode/1f3a8.png?v8",articulated_lorry:"unicode/1f69b.png?v8",artificial_satellite:"unicode/1f6f0.png?v8",artist:"unicode/1f9d1-1f3a8.png?v8",aruba:"unicode/1f1e6-1f1fc.png?v8",ascension_island:"unicode/1f1e6-1f1e8.png?v8",asterisk:"unicode/002a-20e3.png?v8",astonished:"unicode/1f632.png?v8",astronaut:"unicode/1f9d1-1f680.png?v8",athletic_shoe:"unicode/1f45f.png?v8",atm:"unicode/1f3e7.png?v8",atom:"atom.png?v8",atom_symbol:"unicode/269b.png?v8",australia:"unicode/1f1e6-1f1fa.png?v8",austria:"unicode/1f1e6-1f1f9.png?v8",auto_rickshaw:"unicode/1f6fa.png?v8",avocado:"unicode/1f951.png?v8",axe:"unicode/1fa93.png?v8",azerbaijan:"unicode/1f1e6-1f1ff.png?v8",b:"unicode/1f171.png?v8",baby:"unicode/1f476.png?v8",baby_bottle:"unicode/1f37c.png?v8",baby_chick:"unicode/1f424.png?v8",baby_symbol:"unicode/1f6bc.png?v8",back:"unicode/1f519.png?v8",bacon:"unicode/1f953.png?v8",badger:"unicode/1f9a1.png?v8",badminton:"unicode/1f3f8.png?v8",bagel:"unicode/1f96f.png?v8",baggage_claim:"unicode/1f6c4.png?v8",baguette_bread:"unicode/1f956.png?v8",bahamas:"unicode/1f1e7-1f1f8.png?v8",bahrain:"unicode/1f1e7-1f1ed.png?v8",balance_scale:"unicode/2696.png?v8",bald_man:"unicode/1f468-1f9b2.png?v8",bald_woman:"unicode/1f469-1f9b2.png?v8",ballet_shoes:"unicode/1fa70.png?v8",balloon:"unicode/1f388.png?v8",ballot_box:"unicode/1f5f3.png?v8",ballot_box_with_check:"unicode/2611.png?v8",bamboo:"unicode/1f38d.png?v8",banana:"unicode/1f34c.png?v8",bangbang:"unicode/203c.png?v8",bangladesh:"unicode/1f1e7-1f1e9.png?v8",banjo:"unicode/1fa95.png?v8",bank:"unicode/1f3e6.png?v8",bar_chart:"unicode/1f4ca.png?v8",barbados:"unicode/1f1e7-1f1e7.png?v8",barber:"unicode/1f488.png?v8",baseball:"unicode/26be.png?v8",basecamp:"basecamp.png?v8",basecampy:"basecampy.png?v8",basket:"unicode/1f9fa.png?v8",basketball:"unicode/1f3c0.png?v8",basketball_man:"unicode/26f9-2642.png?v8",basketball_woman:"unicode/26f9-2640.png?v8",bat:"unicode/1f987.png?v8",bath:"unicode/1f6c0.png?v8",bathtub:"unicode/1f6c1.png?v8",battery:"unicode/1f50b.png?v8",beach_umbrella:"unicode/1f3d6.png?v8",bear:"unicode/1f43b.png?v8",bearded_person:"unicode/1f9d4.png?v8",beaver:"unicode/1f9ab.png?v8",bed:"unicode/1f6cf.png?v8",bee:"unicode/1f41d.png?v8",beer:"unicode/1f37a.png?v8",beers:"unicode/1f37b.png?v8",beetle:"unicode/1fab2.png?v8",beginner:"unicode/1f530.png?v8",belarus:"unicode/1f1e7-1f1fe.png?v8",belgium:"unicode/1f1e7-1f1ea.png?v8",belize:"unicode/1f1e7-1f1ff.png?v8",bell:"unicode/1f514.png?v8",bell_pepper:"unicode/1fad1.png?v8",bellhop_bell:"unicode/1f6ce.png?v8",benin:"unicode/1f1e7-1f1ef.png?v8",bento:"unicode/1f371.png?v8",bermuda:"unicode/1f1e7-1f1f2.png?v8",beverage_box:"unicode/1f9c3.png?v8",bhutan:"unicode/1f1e7-1f1f9.png?v8",bicyclist:"unicode/1f6b4.png?v8",bike:"unicode/1f6b2.png?v8",biking_man:"unicode/1f6b4-2642.png?v8",biking_woman:"unicode/1f6b4-2640.png?v8",bikini:"unicode/1f459.png?v8",billed_cap:"unicode/1f9e2.png?v8",biohazard:"unicode/2623.png?v8",bird:"unicode/1f426.png?v8",birthday:"unicode/1f382.png?v8",bison:"unicode/1f9ac.png?v8",black_cat:"unicode/1f408-2b1b.png?v8",black_circle:"unicode/26ab.png?v8",black_flag:"unicode/1f3f4.png?v8",black_heart:"unicode/1f5a4.png?v8",black_joker:"unicode/1f0cf.png?v8",black_large_square:"unicode/2b1b.png?v8",black_medium_small_square:"unicode/25fe.png?v8",black_medium_square:"unicode/25fc.png?v8",black_nib:"unicode/2712.png?v8",black_small_square:"unicode/25aa.png?v8",black_square_button:"unicode/1f532.png?v8",blond_haired_man:"unicode/1f471-2642.png?v8",blond_haired_person:"unicode/1f471.png?v8",blond_haired_woman:"unicode/1f471-2640.png?v8",blonde_woman:"unicode/1f471-2640.png?v8",blossom:"unicode/1f33c.png?v8",blowfish:"unicode/1f421.png?v8",blue_book:"unicode/1f4d8.png?v8",blue_car:"unicode/1f699.png?v8",blue_heart:"unicode/1f499.png?v8",blue_square:"unicode/1f7e6.png?v8",blueberries:"unicode/1fad0.png?v8",blush:"unicode/1f60a.png?v8",boar:"unicode/1f417.png?v8",boat:"unicode/26f5.png?v8",bolivia:"unicode/1f1e7-1f1f4.png?v8",bomb:"unicode/1f4a3.png?v8",bone:"unicode/1f9b4.png?v8",book:"unicode/1f4d6.png?v8",bookmark:"unicode/1f516.png?v8",bookmark_tabs:"unicode/1f4d1.png?v8",books:"unicode/1f4da.png?v8",boom:"unicode/1f4a5.png?v8",boomerang:"unicode/1fa83.png?v8",boot:"unicode/1f462.png?v8",bosnia_herzegovina:"unicode/1f1e7-1f1e6.png?v8",botswana:"unicode/1f1e7-1f1fc.png?v8",bouncing_ball_man:"unicode/26f9-2642.png?v8",bouncing_ball_person:"unicode/26f9.png?v8",bouncing_ball_woman:"unicode/26f9-2640.png?v8",bouquet:"unicode/1f490.png?v8",bouvet_island:"unicode/1f1e7-1f1fb.png?v8",bow:"unicode/1f647.png?v8",bow_and_arrow:"unicode/1f3f9.png?v8",bowing_man:"unicode/1f647-2642.png?v8",bowing_woman:"unicode/1f647-2640.png?v8",bowl_with_spoon:"unicode/1f963.png?v8",bowling:"unicode/1f3b3.png?v8",bowtie:"bowtie.png?v8",boxing_glove:"unicode/1f94a.png?v8",boy:"unicode/1f466.png?v8",brain:"unicode/1f9e0.png?v8",brazil:"unicode/1f1e7-1f1f7.png?v8",bread:"unicode/1f35e.png?v8",breast_feeding:"unicode/1f931.png?v8",bricks:"unicode/1f9f1.png?v8",bride_with_veil:"unicode/1f470-2640.png?v8",bridge_at_night:"unicode/1f309.png?v8",briefcase:"unicode/1f4bc.png?v8",british_indian_ocean_territory:"unicode/1f1ee-1f1f4.png?v8",british_virgin_islands:"unicode/1f1fb-1f1ec.png?v8",broccoli:"unicode/1f966.png?v8",broken_heart:"unicode/1f494.png?v8",broom:"unicode/1f9f9.png?v8",brown_circle:"unicode/1f7e4.png?v8",brown_heart:"unicode/1f90e.png?v8",brown_square:"unicode/1f7eb.png?v8",brunei:"unicode/1f1e7-1f1f3.png?v8",bubble_tea:"unicode/1f9cb.png?v8",bucket:"unicode/1faa3.png?v8",bug:"unicode/1f41b.png?v8",building_construction:"unicode/1f3d7.png?v8",bulb:"unicode/1f4a1.png?v8",bulgaria:"unicode/1f1e7-1f1ec.png?v8",bullettrain_front:"unicode/1f685.png?v8",bullettrain_side:"unicode/1f684.png?v8",burkina_faso:"unicode/1f1e7-1f1eb.png?v8",burrito:"unicode/1f32f.png?v8",burundi:"unicode/1f1e7-1f1ee.png?v8",bus:"unicode/1f68c.png?v8",business_suit_levitating:"unicode/1f574.png?v8",busstop:"unicode/1f68f.png?v8",bust_in_silhouette:"unicode/1f464.png?v8",busts_in_silhouette:"unicode/1f465.png?v8",butter:"unicode/1f9c8.png?v8",butterfly:"unicode/1f98b.png?v8",cactus:"unicode/1f335.png?v8",cake:"unicode/1f370.png?v8",calendar:"unicode/1f4c6.png?v8",call_me_hand:"unicode/1f919.png?v8",calling:"unicode/1f4f2.png?v8",cambodia:"unicode/1f1f0-1f1ed.png?v8",camel:"unicode/1f42b.png?v8",camera:"unicode/1f4f7.png?v8",camera_flash:"unicode/1f4f8.png?v8",cameroon:"unicode/1f1e8-1f1f2.png?v8",camping:"unicode/1f3d5.png?v8",canada:"unicode/1f1e8-1f1e6.png?v8",canary_islands:"unicode/1f1ee-1f1e8.png?v8",cancer:"unicode/264b.png?v8",candle:"unicode/1f56f.png?v8",candy:"unicode/1f36c.png?v8",canned_food:"unicode/1f96b.png?v8",canoe:"unicode/1f6f6.png?v8",cape_verde:"unicode/1f1e8-1f1fb.png?v8",capital_abcd:"unicode/1f520.png?v8",capricorn:"unicode/2651.png?v8",car:"unicode/1f697.png?v8",card_file_box:"unicode/1f5c3.png?v8",card_index:"unicode/1f4c7.png?v8",card_index_dividers:"unicode/1f5c2.png?v8",caribbean_netherlands:"unicode/1f1e7-1f1f6.png?v8",carousel_horse:"unicode/1f3a0.png?v8",carpentry_saw:"unicode/1fa9a.png?v8",carrot:"unicode/1f955.png?v8",cartwheeling:"unicode/1f938.png?v8",cat:"unicode/1f431.png?v8",cat2:"unicode/1f408.png?v8",cayman_islands:"unicode/1f1f0-1f1fe.png?v8",cd:"unicode/1f4bf.png?v8",central_african_republic:"unicode/1f1e8-1f1eb.png?v8",ceuta_melilla:"unicode/1f1ea-1f1e6.png?v8",chad:"unicode/1f1f9-1f1e9.png?v8",chains:"unicode/26d3.png?v8",chair:"unicode/1fa91.png?v8",champagne:"unicode/1f37e.png?v8",chart:"unicode/1f4b9.png?v8",chart_with_downwards_trend:"unicode/1f4c9.png?v8",chart_with_upwards_trend:"unicode/1f4c8.png?v8",checkered_flag:"unicode/1f3c1.png?v8",cheese:"unicode/1f9c0.png?v8",cherries:"unicode/1f352.png?v8",cherry_blossom:"unicode/1f338.png?v8",chess_pawn:"unicode/265f.png?v8",chestnut:"unicode/1f330.png?v8",chicken:"unicode/1f414.png?v8",child:"unicode/1f9d2.png?v8",children_crossing:"unicode/1f6b8.png?v8",chile:"unicode/1f1e8-1f1f1.png?v8",chipmunk:"unicode/1f43f.png?v8",chocolate_bar:"unicode/1f36b.png?v8",chopsticks:"unicode/1f962.png?v8",christmas_island:"unicode/1f1e8-1f1fd.png?v8",christmas_tree:"unicode/1f384.png?v8",church:"unicode/26ea.png?v8",cinema:"unicode/1f3a6.png?v8",circus_tent:"unicode/1f3aa.png?v8",city_sunrise:"unicode/1f307.png?v8",city_sunset:"unicode/1f306.png?v8",cityscape:"unicode/1f3d9.png?v8",cl:"unicode/1f191.png?v8",clamp:"unicode/1f5dc.png?v8",clap:"unicode/1f44f.png?v8",clapper:"unicode/1f3ac.png?v8",classical_building:"unicode/1f3db.png?v8",climbing:"unicode/1f9d7.png?v8",climbing_man:"unicode/1f9d7-2642.png?v8",climbing_woman:"unicode/1f9d7-2640.png?v8",clinking_glasses:"unicode/1f942.png?v8",clipboard:"unicode/1f4cb.png?v8",clipperton_island:"unicode/1f1e8-1f1f5.png?v8",clock1:"unicode/1f550.png?v8",clock10:"unicode/1f559.png?v8",clock1030:"unicode/1f565.png?v8",clock11:"unicode/1f55a.png?v8",clock1130:"unicode/1f566.png?v8",clock12:"unicode/1f55b.png?v8",clock1230:"unicode/1f567.png?v8",clock130:"unicode/1f55c.png?v8",clock2:"unicode/1f551.png?v8",clock230:"unicode/1f55d.png?v8",clock3:"unicode/1f552.png?v8",clock330:"unicode/1f55e.png?v8",clock4:"unicode/1f553.png?v8",clock430:"unicode/1f55f.png?v8",clock5:"unicode/1f554.png?v8",clock530:"unicode/1f560.png?v8",clock6:"unicode/1f555.png?v8",clock630:"unicode/1f561.png?v8",clock7:"unicode/1f556.png?v8",clock730:"unicode/1f562.png?v8",clock8:"unicode/1f557.png?v8",clock830:"unicode/1f563.png?v8",clock9:"unicode/1f558.png?v8",clock930:"unicode/1f564.png?v8",closed_book:"unicode/1f4d5.png?v8",closed_lock_with_key:"unicode/1f510.png?v8",closed_umbrella:"unicode/1f302.png?v8",cloud:"unicode/2601.png?v8",cloud_with_lightning:"unicode/1f329.png?v8",cloud_with_lightning_and_rain:"unicode/26c8.png?v8",cloud_with_rain:"unicode/1f327.png?v8",cloud_with_snow:"unicode/1f328.png?v8",clown_face:"unicode/1f921.png?v8",clubs:"unicode/2663.png?v8",cn:"unicode/1f1e8-1f1f3.png?v8",coat:"unicode/1f9e5.png?v8",cockroach:"unicode/1fab3.png?v8",cocktail:"unicode/1f378.png?v8",coconut:"unicode/1f965.png?v8",cocos_islands:"unicode/1f1e8-1f1e8.png?v8",coffee:"unicode/2615.png?v8",coffin:"unicode/26b0.png?v8",coin:"unicode/1fa99.png?v8",cold_face:"unicode/1f976.png?v8",cold_sweat:"unicode/1f630.png?v8",collision:"unicode/1f4a5.png?v8",colombia:"unicode/1f1e8-1f1f4.png?v8",comet:"unicode/2604.png?v8",comoros:"unicode/1f1f0-1f1f2.png?v8",compass:"unicode/1f9ed.png?v8",computer:"unicode/1f4bb.png?v8",computer_mouse:"unicode/1f5b1.png?v8",confetti_ball:"unicode/1f38a.png?v8",confounded:"unicode/1f616.png?v8",confused:"unicode/1f615.png?v8",congo_brazzaville:"unicode/1f1e8-1f1ec.png?v8",congo_kinshasa:"unicode/1f1e8-1f1e9.png?v8",congratulations:"unicode/3297.png?v8",construction:"unicode/1f6a7.png?v8",construction_worker:"unicode/1f477.png?v8",construction_worker_man:"unicode/1f477-2642.png?v8",construction_worker_woman:"unicode/1f477-2640.png?v8",control_knobs:"unicode/1f39b.png?v8",convenience_store:"unicode/1f3ea.png?v8",cook:"unicode/1f9d1-1f373.png?v8",cook_islands:"unicode/1f1e8-1f1f0.png?v8",cookie:"unicode/1f36a.png?v8",cool:"unicode/1f192.png?v8",cop:"unicode/1f46e.png?v8",copyright:"unicode/00a9.png?v8",corn:"unicode/1f33d.png?v8",costa_rica:"unicode/1f1e8-1f1f7.png?v8",cote_divoire:"unicode/1f1e8-1f1ee.png?v8",couch_and_lamp:"unicode/1f6cb.png?v8",couple:"unicode/1f46b.png?v8",couple_with_heart:"unicode/1f491.png?v8",couple_with_heart_man_man:"unicode/1f468-2764-1f468.png?v8",couple_with_heart_woman_man:"unicode/1f469-2764-1f468.png?v8",couple_with_heart_woman_woman:"unicode/1f469-2764-1f469.png?v8",couplekiss:"unicode/1f48f.png?v8",couplekiss_man_man:"unicode/1f468-2764-1f48b-1f468.png?v8",couplekiss_man_woman:"unicode/1f469-2764-1f48b-1f468.png?v8",couplekiss_woman_woman:"unicode/1f469-2764-1f48b-1f469.png?v8",cow:"unicode/1f42e.png?v8",cow2:"unicode/1f404.png?v8",cowboy_hat_face:"unicode/1f920.png?v8",crab:"unicode/1f980.png?v8",crayon:"unicode/1f58d.png?v8",credit_card:"unicode/1f4b3.png?v8",crescent_moon:"unicode/1f319.png?v8",cricket:"unicode/1f997.png?v8",cricket_game:"unicode/1f3cf.png?v8",croatia:"unicode/1f1ed-1f1f7.png?v8",crocodile:"unicode/1f40a.png?v8",croissant:"unicode/1f950.png?v8",crossed_fingers:"unicode/1f91e.png?v8",crossed_flags:"unicode/1f38c.png?v8",crossed_swords:"unicode/2694.png?v8",crown:"unicode/1f451.png?v8",cry:"unicode/1f622.png?v8",crying_cat_face:"unicode/1f63f.png?v8",crystal_ball:"unicode/1f52e.png?v8",cuba:"unicode/1f1e8-1f1fa.png?v8",cucumber:"unicode/1f952.png?v8",cup_with_straw:"unicode/1f964.png?v8",cupcake:"unicode/1f9c1.png?v8",cupid:"unicode/1f498.png?v8",curacao:"unicode/1f1e8-1f1fc.png?v8",curling_stone:"unicode/1f94c.png?v8",curly_haired_man:"unicode/1f468-1f9b1.png?v8",curly_haired_woman:"unicode/1f469-1f9b1.png?v8",curly_loop:"unicode/27b0.png?v8",currency_exchange:"unicode/1f4b1.png?v8",curry:"unicode/1f35b.png?v8",cursing_face:"unicode/1f92c.png?v8",custard:"unicode/1f36e.png?v8",customs:"unicode/1f6c3.png?v8",cut_of_meat:"unicode/1f969.png?v8",cyclone:"unicode/1f300.png?v8",cyprus:"unicode/1f1e8-1f1fe.png?v8",czech_republic:"unicode/1f1e8-1f1ff.png?v8",dagger:"unicode/1f5e1.png?v8",dancer:"unicode/1f483.png?v8",dancers:"unicode/1f46f.png?v8",dancing_men:"unicode/1f46f-2642.png?v8",dancing_women:"unicode/1f46f-2640.png?v8",dango:"unicode/1f361.png?v8",dark_sunglasses:"unicode/1f576.png?v8",dart:"unicode/1f3af.png?v8",dash:"unicode/1f4a8.png?v8",date:"unicode/1f4c5.png?v8",de:"unicode/1f1e9-1f1ea.png?v8",deaf_man:"unicode/1f9cf-2642.png?v8",deaf_person:"unicode/1f9cf.png?v8",deaf_woman:"unicode/1f9cf-2640.png?v8",deciduous_tree:"unicode/1f333.png?v8",deer:"unicode/1f98c.png?v8",denmark:"unicode/1f1e9-1f1f0.png?v8",department_store:"unicode/1f3ec.png?v8",derelict_house:"unicode/1f3da.png?v8",desert:"unicode/1f3dc.png?v8",desert_island:"unicode/1f3dd.png?v8",desktop_computer:"unicode/1f5a5.png?v8",detective:"unicode/1f575.png?v8",diamond_shape_with_a_dot_inside:"unicode/1f4a0.png?v8",diamonds:"unicode/2666.png?v8",diego_garcia:"unicode/1f1e9-1f1ec.png?v8",disappointed:"unicode/1f61e.png?v8",disappointed_relieved:"unicode/1f625.png?v8",disguised_face:"unicode/1f978.png?v8",diving_mask:"unicode/1f93f.png?v8",diya_lamp:"unicode/1fa94.png?v8",dizzy:"unicode/1f4ab.png?v8",dizzy_face:"unicode/1f635.png?v8",djibouti:"unicode/1f1e9-1f1ef.png?v8",dna:"unicode/1f9ec.png?v8",do_not_litter:"unicode/1f6af.png?v8",dodo:"unicode/1f9a4.png?v8",dog:"unicode/1f436.png?v8",dog2:"unicode/1f415.png?v8",dollar:"unicode/1f4b5.png?v8",dolls:"unicode/1f38e.png?v8",dolphin:"unicode/1f42c.png?v8",dominica:"unicode/1f1e9-1f1f2.png?v8",dominican_republic:"unicode/1f1e9-1f1f4.png?v8",door:"unicode/1f6aa.png?v8",doughnut:"unicode/1f369.png?v8",dove:"unicode/1f54a.png?v8",dragon:"unicode/1f409.png?v8",dragon_face:"unicode/1f432.png?v8",dress:"unicode/1f457.png?v8",dromedary_camel:"unicode/1f42a.png?v8",drooling_face:"unicode/1f924.png?v8",drop_of_blood:"unicode/1fa78.png?v8",droplet:"unicode/1f4a7.png?v8",drum:"unicode/1f941.png?v8",duck:"unicode/1f986.png?v8",dumpling:"unicode/1f95f.png?v8",dvd:"unicode/1f4c0.png?v8","e-mail":"unicode/1f4e7.png?v8",eagle:"unicode/1f985.png?v8",ear:"unicode/1f442.png?v8",ear_of_rice:"unicode/1f33e.png?v8",ear_with_hearing_aid:"unicode/1f9bb.png?v8",earth_africa:"unicode/1f30d.png?v8",earth_americas:"unicode/1f30e.png?v8",earth_asia:"unicode/1f30f.png?v8",ecuador:"unicode/1f1ea-1f1e8.png?v8",egg:"unicode/1f95a.png?v8",eggplant:"unicode/1f346.png?v8",egypt:"unicode/1f1ea-1f1ec.png?v8",eight:"unicode/0038-20e3.png?v8",eight_pointed_black_star:"unicode/2734.png?v8",eight_spoked_asterisk:"unicode/2733.png?v8",eject_button:"unicode/23cf.png?v8",el_salvador:"unicode/1f1f8-1f1fb.png?v8",electric_plug:"unicode/1f50c.png?v8",electron:"electron.png?v8",elephant:"unicode/1f418.png?v8",elevator:"unicode/1f6d7.png?v8",elf:"unicode/1f9dd.png?v8",elf_man:"unicode/1f9dd-2642.png?v8",elf_woman:"unicode/1f9dd-2640.png?v8",email:"unicode/1f4e7.png?v8",end:"unicode/1f51a.png?v8",england:"unicode/1f3f4-e0067-e0062-e0065-e006e-e0067-e007f.png?v8",envelope:"unicode/2709.png?v8",envelope_with_arrow:"unicode/1f4e9.png?v8",equatorial_guinea:"unicode/1f1ec-1f1f6.png?v8",eritrea:"unicode/1f1ea-1f1f7.png?v8",es:"unicode/1f1ea-1f1f8.png?v8",estonia:"unicode/1f1ea-1f1ea.png?v8",ethiopia:"unicode/1f1ea-1f1f9.png?v8",eu:"unicode/1f1ea-1f1fa.png?v8",euro:"unicode/1f4b6.png?v8",european_castle:"unicode/1f3f0.png?v8",european_post_office:"unicode/1f3e4.png?v8",european_union:"unicode/1f1ea-1f1fa.png?v8",evergreen_tree:"unicode/1f332.png?v8",exclamation:"unicode/2757.png?v8",exploding_head:"unicode/1f92f.png?v8",expressionless:"unicode/1f611.png?v8",eye:"unicode/1f441.png?v8",eye_speech_bubble:"unicode/1f441-1f5e8.png?v8",eyeglasses:"unicode/1f453.png?v8",eyes:"unicode/1f440.png?v8",face_exhaling:"unicode/1f62e-1f4a8.png?v8",face_in_clouds:"unicode/1f636-1f32b.png?v8",face_with_head_bandage:"unicode/1f915.png?v8",face_with_spiral_eyes:"unicode/1f635-1f4ab.png?v8",face_with_thermometer:"unicode/1f912.png?v8",facepalm:"unicode/1f926.png?v8",facepunch:"unicode/1f44a.png?v8",factory:"unicode/1f3ed.png?v8",factory_worker:"unicode/1f9d1-1f3ed.png?v8",fairy:"unicode/1f9da.png?v8",fairy_man:"unicode/1f9da-2642.png?v8",fairy_woman:"unicode/1f9da-2640.png?v8",falafel:"unicode/1f9c6.png?v8",falkland_islands:"unicode/1f1eb-1f1f0.png?v8",fallen_leaf:"unicode/1f342.png?v8",family:"unicode/1f46a.png?v8",family_man_boy:"unicode/1f468-1f466.png?v8",family_man_boy_boy:"unicode/1f468-1f466-1f466.png?v8",family_man_girl:"unicode/1f468-1f467.png?v8",family_man_girl_boy:"unicode/1f468-1f467-1f466.png?v8",family_man_girl_girl:"unicode/1f468-1f467-1f467.png?v8",family_man_man_boy:"unicode/1f468-1f468-1f466.png?v8",family_man_man_boy_boy:"unicode/1f468-1f468-1f466-1f466.png?v8",family_man_man_girl:"unicode/1f468-1f468-1f467.png?v8",family_man_man_girl_boy:"unicode/1f468-1f468-1f467-1f466.png?v8",family_man_man_girl_girl:"unicode/1f468-1f468-1f467-1f467.png?v8",family_man_woman_boy:"unicode/1f468-1f469-1f466.png?v8",family_man_woman_boy_boy:"unicode/1f468-1f469-1f466-1f466.png?v8",family_man_woman_girl:"unicode/1f468-1f469-1f467.png?v8",family_man_woman_girl_boy:"unicode/1f468-1f469-1f467-1f466.png?v8",family_man_woman_girl_girl:"unicode/1f468-1f469-1f467-1f467.png?v8",family_woman_boy:"unicode/1f469-1f466.png?v8",family_woman_boy_boy:"unicode/1f469-1f466-1f466.png?v8",family_woman_girl:"unicode/1f469-1f467.png?v8",family_woman_girl_boy:"unicode/1f469-1f467-1f466.png?v8",family_woman_girl_girl:"unicode/1f469-1f467-1f467.png?v8",family_woman_woman_boy:"unicode/1f469-1f469-1f466.png?v8",family_woman_woman_boy_boy:"unicode/1f469-1f469-1f466-1f466.png?v8",family_woman_woman_girl:"unicode/1f469-1f469-1f467.png?v8",family_woman_woman_girl_boy:"unicode/1f469-1f469-1f467-1f466.png?v8",family_woman_woman_girl_girl:"unicode/1f469-1f469-1f467-1f467.png?v8",farmer:"unicode/1f9d1-1f33e.png?v8",faroe_islands:"unicode/1f1eb-1f1f4.png?v8",fast_forward:"unicode/23e9.png?v8",fax:"unicode/1f4e0.png?v8",fearful:"unicode/1f628.png?v8",feather:"unicode/1fab6.png?v8",feelsgood:"feelsgood.png?v8",feet:"unicode/1f43e.png?v8",female_detective:"unicode/1f575-2640.png?v8",female_sign:"unicode/2640.png?v8",ferris_wheel:"unicode/1f3a1.png?v8",ferry:"unicode/26f4.png?v8",field_hockey:"unicode/1f3d1.png?v8",fiji:"unicode/1f1eb-1f1ef.png?v8",file_cabinet:"unicode/1f5c4.png?v8",file_folder:"unicode/1f4c1.png?v8",film_projector:"unicode/1f4fd.png?v8",film_strip:"unicode/1f39e.png?v8",finland:"unicode/1f1eb-1f1ee.png?v8",finnadie:"finnadie.png?v8",fire:"unicode/1f525.png?v8",fire_engine:"unicode/1f692.png?v8",fire_extinguisher:"unicode/1f9ef.png?v8",firecracker:"unicode/1f9e8.png?v8",firefighter:"unicode/1f9d1-1f692.png?v8",fireworks:"unicode/1f386.png?v8",first_quarter_moon:"unicode/1f313.png?v8",first_quarter_moon_with_face:"unicode/1f31b.png?v8",fish:"unicode/1f41f.png?v8",fish_cake:"unicode/1f365.png?v8",fishing_pole_and_fish:"unicode/1f3a3.png?v8",fist:"unicode/270a.png?v8",fist_left:"unicode/1f91b.png?v8",fist_oncoming:"unicode/1f44a.png?v8",fist_raised:"unicode/270a.png?v8",fist_right:"unicode/1f91c.png?v8",five:"unicode/0035-20e3.png?v8",flags:"unicode/1f38f.png?v8",flamingo:"unicode/1f9a9.png?v8",flashlight:"unicode/1f526.png?v8",flat_shoe:"unicode/1f97f.png?v8",flatbread:"unicode/1fad3.png?v8",fleur_de_lis:"unicode/269c.png?v8",flight_arrival:"unicode/1f6ec.png?v8",flight_departure:"unicode/1f6eb.png?v8",flipper:"unicode/1f42c.png?v8",floppy_disk:"unicode/1f4be.png?v8",flower_playing_cards:"unicode/1f3b4.png?v8",flushed:"unicode/1f633.png?v8",fly:"unicode/1fab0.png?v8",flying_disc:"unicode/1f94f.png?v8",flying_saucer:"unicode/1f6f8.png?v8",fog:"unicode/1f32b.png?v8",foggy:"unicode/1f301.png?v8",fondue:"unicode/1fad5.png?v8",foot:"unicode/1f9b6.png?v8",football:"unicode/1f3c8.png?v8",footprints:"unicode/1f463.png?v8",fork_and_knife:"unicode/1f374.png?v8",fortune_cookie:"unicode/1f960.png?v8",fountain:"unicode/26f2.png?v8",fountain_pen:"unicode/1f58b.png?v8",four:"unicode/0034-20e3.png?v8",four_leaf_clover:"unicode/1f340.png?v8",fox_face:"unicode/1f98a.png?v8",fr:"unicode/1f1eb-1f1f7.png?v8",framed_picture:"unicode/1f5bc.png?v8",free:"unicode/1f193.png?v8",french_guiana:"unicode/1f1ec-1f1eb.png?v8",french_polynesia:"unicode/1f1f5-1f1eb.png?v8",french_southern_territories:"unicode/1f1f9-1f1eb.png?v8",fried_egg:"unicode/1f373.png?v8",fried_shrimp:"unicode/1f364.png?v8",fries:"unicode/1f35f.png?v8",frog:"unicode/1f438.png?v8",frowning:"unicode/1f626.png?v8",frowning_face:"unicode/2639.png?v8",frowning_man:"unicode/1f64d-2642.png?v8",frowning_person:"unicode/1f64d.png?v8",frowning_woman:"unicode/1f64d-2640.png?v8",fu:"unicode/1f595.png?v8",fuelpump:"unicode/26fd.png?v8",full_moon:"unicode/1f315.png?v8",full_moon_with_face:"unicode/1f31d.png?v8",funeral_urn:"unicode/26b1.png?v8",gabon:"unicode/1f1ec-1f1e6.png?v8",gambia:"unicode/1f1ec-1f1f2.png?v8",game_die:"unicode/1f3b2.png?v8",garlic:"unicode/1f9c4.png?v8",gb:"unicode/1f1ec-1f1e7.png?v8",gear:"unicode/2699.png?v8",gem:"unicode/1f48e.png?v8",gemini:"unicode/264a.png?v8",genie:"unicode/1f9de.png?v8",genie_man:"unicode/1f9de-2642.png?v8",genie_woman:"unicode/1f9de-2640.png?v8",georgia:"unicode/1f1ec-1f1ea.png?v8",ghana:"unicode/1f1ec-1f1ed.png?v8",ghost:"unicode/1f47b.png?v8",gibraltar:"unicode/1f1ec-1f1ee.png?v8",gift:"unicode/1f381.png?v8",gift_heart:"unicode/1f49d.png?v8",giraffe:"unicode/1f992.png?v8",girl:"unicode/1f467.png?v8",globe_with_meridians:"unicode/1f310.png?v8",gloves:"unicode/1f9e4.png?v8",goal_net:"unicode/1f945.png?v8",goat:"unicode/1f410.png?v8",goberserk:"goberserk.png?v8",godmode:"godmode.png?v8",goggles:"unicode/1f97d.png?v8",golf:"unicode/26f3.png?v8",golfing:"unicode/1f3cc.png?v8",golfing_man:"unicode/1f3cc-2642.png?v8",golfing_woman:"unicode/1f3cc-2640.png?v8",gorilla:"unicode/1f98d.png?v8",grapes:"unicode/1f347.png?v8",greece:"unicode/1f1ec-1f1f7.png?v8",green_apple:"unicode/1f34f.png?v8",green_book:"unicode/1f4d7.png?v8",green_circle:"unicode/1f7e2.png?v8",green_heart:"unicode/1f49a.png?v8",green_salad:"unicode/1f957.png?v8",green_square:"unicode/1f7e9.png?v8",greenland:"unicode/1f1ec-1f1f1.png?v8",grenada:"unicode/1f1ec-1f1e9.png?v8",grey_exclamation:"unicode/2755.png?v8",grey_question:"unicode/2754.png?v8",grimacing:"unicode/1f62c.png?v8",grin:"unicode/1f601.png?v8",grinning:"unicode/1f600.png?v8",guadeloupe:"unicode/1f1ec-1f1f5.png?v8",guam:"unicode/1f1ec-1f1fa.png?v8",guard:"unicode/1f482.png?v8",guardsman:"unicode/1f482-2642.png?v8",guardswoman:"unicode/1f482-2640.png?v8",guatemala:"unicode/1f1ec-1f1f9.png?v8",guernsey:"unicode/1f1ec-1f1ec.png?v8",guide_dog:"unicode/1f9ae.png?v8",guinea:"unicode/1f1ec-1f1f3.png?v8",guinea_bissau:"unicode/1f1ec-1f1fc.png?v8",guitar:"unicode/1f3b8.png?v8",gun:"unicode/1f52b.png?v8",guyana:"unicode/1f1ec-1f1fe.png?v8",haircut:"unicode/1f487.png?v8",haircut_man:"unicode/1f487-2642.png?v8",haircut_woman:"unicode/1f487-2640.png?v8",haiti:"unicode/1f1ed-1f1f9.png?v8",hamburger:"unicode/1f354.png?v8",hammer:"unicode/1f528.png?v8",hammer_and_pick:"unicode/2692.png?v8",hammer_and_wrench:"unicode/1f6e0.png?v8",hamster:"unicode/1f439.png?v8",hand:"unicode/270b.png?v8",hand_over_mouth:"unicode/1f92d.png?v8",handbag:"unicode/1f45c.png?v8",handball_person:"unicode/1f93e.png?v8",handshake:"unicode/1f91d.png?v8",hankey:"unicode/1f4a9.png?v8",hash:"unicode/0023-20e3.png?v8",hatched_chick:"unicode/1f425.png?v8",hatching_chick:"unicode/1f423.png?v8",headphones:"unicode/1f3a7.png?v8",headstone:"unicode/1faa6.png?v8",health_worker:"unicode/1f9d1-2695.png?v8",hear_no_evil:"unicode/1f649.png?v8",heard_mcdonald_islands:"unicode/1f1ed-1f1f2.png?v8",heart:"unicode/2764.png?v8",heart_decoration:"unicode/1f49f.png?v8",heart_eyes:"unicode/1f60d.png?v8",heart_eyes_cat:"unicode/1f63b.png?v8",heart_on_fire:"unicode/2764-1f525.png?v8",heartbeat:"unicode/1f493.png?v8",heartpulse:"unicode/1f497.png?v8",hearts:"unicode/2665.png?v8",heavy_check_mark:"unicode/2714.png?v8",heavy_division_sign:"unicode/2797.png?v8",heavy_dollar_sign:"unicode/1f4b2.png?v8",heavy_exclamation_mark:"unicode/2757.png?v8",heavy_heart_exclamation:"unicode/2763.png?v8",heavy_minus_sign:"unicode/2796.png?v8",heavy_multiplication_x:"unicode/2716.png?v8",heavy_plus_sign:"unicode/2795.png?v8",hedgehog:"unicode/1f994.png?v8",helicopter:"unicode/1f681.png?v8",herb:"unicode/1f33f.png?v8",hibiscus:"unicode/1f33a.png?v8",high_brightness:"unicode/1f506.png?v8",high_heel:"unicode/1f460.png?v8",hiking_boot:"unicode/1f97e.png?v8",hindu_temple:"unicode/1f6d5.png?v8",hippopotamus:"unicode/1f99b.png?v8",hocho:"unicode/1f52a.png?v8",hole:"unicode/1f573.png?v8",honduras:"unicode/1f1ed-1f1f3.png?v8",honey_pot:"unicode/1f36f.png?v8",honeybee:"unicode/1f41d.png?v8",hong_kong:"unicode/1f1ed-1f1f0.png?v8",hook:"unicode/1fa9d.png?v8",horse:"unicode/1f434.png?v8",horse_racing:"unicode/1f3c7.png?v8",hospital:"unicode/1f3e5.png?v8",hot_face:"unicode/1f975.png?v8",hot_pepper:"unicode/1f336.png?v8",hotdog:"unicode/1f32d.png?v8",hotel:"unicode/1f3e8.png?v8",hotsprings:"unicode/2668.png?v8",hourglass:"unicode/231b.png?v8",hourglass_flowing_sand:"unicode/23f3.png?v8",house:"unicode/1f3e0.png?v8",house_with_garden:"unicode/1f3e1.png?v8",houses:"unicode/1f3d8.png?v8",hugs:"unicode/1f917.png?v8",hungary:"unicode/1f1ed-1f1fa.png?v8",hurtrealbad:"hurtrealbad.png?v8",hushed:"unicode/1f62f.png?v8",hut:"unicode/1f6d6.png?v8",ice_cream:"unicode/1f368.png?v8",ice_cube:"unicode/1f9ca.png?v8",ice_hockey:"unicode/1f3d2.png?v8",ice_skate:"unicode/26f8.png?v8",icecream:"unicode/1f366.png?v8",iceland:"unicode/1f1ee-1f1f8.png?v8",id:"unicode/1f194.png?v8",ideograph_advantage:"unicode/1f250.png?v8",imp:"unicode/1f47f.png?v8",inbox_tray:"unicode/1f4e5.png?v8",incoming_envelope:"unicode/1f4e8.png?v8",india:"unicode/1f1ee-1f1f3.png?v8",indonesia:"unicode/1f1ee-1f1e9.png?v8",infinity:"unicode/267e.png?v8",information_desk_person:"unicode/1f481.png?v8",information_source:"unicode/2139.png?v8",innocent:"unicode/1f607.png?v8",interrobang:"unicode/2049.png?v8",iphone:"unicode/1f4f1.png?v8",iran:"unicode/1f1ee-1f1f7.png?v8",iraq:"unicode/1f1ee-1f1f6.png?v8",ireland:"unicode/1f1ee-1f1ea.png?v8",isle_of_man:"unicode/1f1ee-1f1f2.png?v8",israel:"unicode/1f1ee-1f1f1.png?v8",it:"unicode/1f1ee-1f1f9.png?v8",izakaya_lantern:"unicode/1f3ee.png?v8",jack_o_lantern:"unicode/1f383.png?v8",jamaica:"unicode/1f1ef-1f1f2.png?v8",japan:"unicode/1f5fe.png?v8",japanese_castle:"unicode/1f3ef.png?v8",japanese_goblin:"unicode/1f47a.png?v8",japanese_ogre:"unicode/1f479.png?v8",jeans:"unicode/1f456.png?v8",jersey:"unicode/1f1ef-1f1ea.png?v8",jigsaw:"unicode/1f9e9.png?v8",jordan:"unicode/1f1ef-1f1f4.png?v8",joy:"unicode/1f602.png?v8",joy_cat:"unicode/1f639.png?v8",joystick:"unicode/1f579.png?v8",jp:"unicode/1f1ef-1f1f5.png?v8",judge:"unicode/1f9d1-2696.png?v8",juggling_person:"unicode/1f939.png?v8",kaaba:"unicode/1f54b.png?v8",kangaroo:"unicode/1f998.png?v8",kazakhstan:"unicode/1f1f0-1f1ff.png?v8",kenya:"unicode/1f1f0-1f1ea.png?v8",key:"unicode/1f511.png?v8",keyboard:"unicode/2328.png?v8",keycap_ten:"unicode/1f51f.png?v8",kick_scooter:"unicode/1f6f4.png?v8",kimono:"unicode/1f458.png?v8",kiribati:"unicode/1f1f0-1f1ee.png?v8",kiss:"unicode/1f48b.png?v8",kissing:"unicode/1f617.png?v8",kissing_cat:"unicode/1f63d.png?v8",kissing_closed_eyes:"unicode/1f61a.png?v8",kissing_heart:"unicode/1f618.png?v8",kissing_smiling_eyes:"unicode/1f619.png?v8",kite:"unicode/1fa81.png?v8",kiwi_fruit:"unicode/1f95d.png?v8",kneeling_man:"unicode/1f9ce-2642.png?v8",kneeling_person:"unicode/1f9ce.png?v8",kneeling_woman:"unicode/1f9ce-2640.png?v8",knife:"unicode/1f52a.png?v8",knot:"unicode/1faa2.png?v8",koala:"unicode/1f428.png?v8",koko:"unicode/1f201.png?v8",kosovo:"unicode/1f1fd-1f1f0.png?v8",kr:"unicode/1f1f0-1f1f7.png?v8",kuwait:"unicode/1f1f0-1f1fc.png?v8",kyrgyzstan:"unicode/1f1f0-1f1ec.png?v8",lab_coat:"unicode/1f97c.png?v8",label:"unicode/1f3f7.png?v8",lacrosse:"unicode/1f94d.png?v8",ladder:"unicode/1fa9c.png?v8",lady_beetle:"unicode/1f41e.png?v8",lantern:"unicode/1f3ee.png?v8",laos:"unicode/1f1f1-1f1e6.png?v8",large_blue_circle:"unicode/1f535.png?v8",large_blue_diamond:"unicode/1f537.png?v8",large_orange_diamond:"unicode/1f536.png?v8",last_quarter_moon:"unicode/1f317.png?v8",last_quarter_moon_with_face:"unicode/1f31c.png?v8",latin_cross:"unicode/271d.png?v8",latvia:"unicode/1f1f1-1f1fb.png?v8",laughing:"unicode/1f606.png?v8",leafy_green:"unicode/1f96c.png?v8",leaves:"unicode/1f343.png?v8",lebanon:"unicode/1f1f1-1f1e7.png?v8",ledger:"unicode/1f4d2.png?v8",left_luggage:"unicode/1f6c5.png?v8",left_right_arrow:"unicode/2194.png?v8",left_speech_bubble:"unicode/1f5e8.png?v8",leftwards_arrow_with_hook:"unicode/21a9.png?v8",leg:"unicode/1f9b5.png?v8",lemon:"unicode/1f34b.png?v8",leo:"unicode/264c.png?v8",leopard:"unicode/1f406.png?v8",lesotho:"unicode/1f1f1-1f1f8.png?v8",level_slider:"unicode/1f39a.png?v8",liberia:"unicode/1f1f1-1f1f7.png?v8",libra:"unicode/264e.png?v8",libya:"unicode/1f1f1-1f1fe.png?v8",liechtenstein:"unicode/1f1f1-1f1ee.png?v8",light_rail:"unicode/1f688.png?v8",link:"unicode/1f517.png?v8",lion:"unicode/1f981.png?v8",lips:"unicode/1f444.png?v8",lipstick:"unicode/1f484.png?v8",lithuania:"unicode/1f1f1-1f1f9.png?v8",lizard:"unicode/1f98e.png?v8",llama:"unicode/1f999.png?v8",lobster:"unicode/1f99e.png?v8",lock:"unicode/1f512.png?v8",lock_with_ink_pen:"unicode/1f50f.png?v8",lollipop:"unicode/1f36d.png?v8",long_drum:"unicode/1fa98.png?v8",loop:"unicode/27bf.png?v8",lotion_bottle:"unicode/1f9f4.png?v8",lotus_position:"unicode/1f9d8.png?v8",lotus_position_man:"unicode/1f9d8-2642.png?v8",lotus_position_woman:"unicode/1f9d8-2640.png?v8",loud_sound:"unicode/1f50a.png?v8",loudspeaker:"unicode/1f4e2.png?v8",love_hotel:"unicode/1f3e9.png?v8",love_letter:"unicode/1f48c.png?v8",love_you_gesture:"unicode/1f91f.png?v8",low_brightness:"unicode/1f505.png?v8",luggage:"unicode/1f9f3.png?v8",lungs:"unicode/1fac1.png?v8",luxembourg:"unicode/1f1f1-1f1fa.png?v8",lying_face:"unicode/1f925.png?v8",m:"unicode/24c2.png?v8",macau:"unicode/1f1f2-1f1f4.png?v8",macedonia:"unicode/1f1f2-1f1f0.png?v8",madagascar:"unicode/1f1f2-1f1ec.png?v8",mag:"unicode/1f50d.png?v8",mag_right:"unicode/1f50e.png?v8",mage:"unicode/1f9d9.png?v8",mage_man:"unicode/1f9d9-2642.png?v8",mage_woman:"unicode/1f9d9-2640.png?v8",magic_wand:"unicode/1fa84.png?v8",magnet:"unicode/1f9f2.png?v8",mahjong:"unicode/1f004.png?v8",mailbox:"unicode/1f4eb.png?v8",mailbox_closed:"unicode/1f4ea.png?v8",mailbox_with_mail:"unicode/1f4ec.png?v8",mailbox_with_no_mail:"unicode/1f4ed.png?v8",malawi:"unicode/1f1f2-1f1fc.png?v8",malaysia:"unicode/1f1f2-1f1fe.png?v8",maldives:"unicode/1f1f2-1f1fb.png?v8",male_detective:"unicode/1f575-2642.png?v8",male_sign:"unicode/2642.png?v8",mali:"unicode/1f1f2-1f1f1.png?v8",malta:"unicode/1f1f2-1f1f9.png?v8",mammoth:"unicode/1f9a3.png?v8",man:"unicode/1f468.png?v8",man_artist:"unicode/1f468-1f3a8.png?v8",man_astronaut:"unicode/1f468-1f680.png?v8",man_beard:"unicode/1f9d4-2642.png?v8",man_cartwheeling:"unicode/1f938-2642.png?v8",man_cook:"unicode/1f468-1f373.png?v8",man_dancing:"unicode/1f57a.png?v8",man_facepalming:"unicode/1f926-2642.png?v8",man_factory_worker:"unicode/1f468-1f3ed.png?v8",man_farmer:"unicode/1f468-1f33e.png?v8",man_feeding_baby:"unicode/1f468-1f37c.png?v8",man_firefighter:"unicode/1f468-1f692.png?v8",man_health_worker:"unicode/1f468-2695.png?v8",man_in_manual_wheelchair:"unicode/1f468-1f9bd.png?v8",man_in_motorized_wheelchair:"unicode/1f468-1f9bc.png?v8",man_in_tuxedo:"unicode/1f935-2642.png?v8",man_judge:"unicode/1f468-2696.png?v8",man_juggling:"unicode/1f939-2642.png?v8",man_mechanic:"unicode/1f468-1f527.png?v8",man_office_worker:"unicode/1f468-1f4bc.png?v8",man_pilot:"unicode/1f468-2708.png?v8",man_playing_handball:"unicode/1f93e-2642.png?v8",man_playing_water_polo:"unicode/1f93d-2642.png?v8",man_scientist:"unicode/1f468-1f52c.png?v8",man_shrugging:"unicode/1f937-2642.png?v8",man_singer:"unicode/1f468-1f3a4.png?v8",man_student:"unicode/1f468-1f393.png?v8",man_teacher:"unicode/1f468-1f3eb.png?v8",man_technologist:"unicode/1f468-1f4bb.png?v8",man_with_gua_pi_mao:"unicode/1f472.png?v8",man_with_probing_cane:"unicode/1f468-1f9af.png?v8",man_with_turban:"unicode/1f473-2642.png?v8",man_with_veil:"unicode/1f470-2642.png?v8",mandarin:"unicode/1f34a.png?v8",mango:"unicode/1f96d.png?v8",mans_shoe:"unicode/1f45e.png?v8",mantelpiece_clock:"unicode/1f570.png?v8",manual_wheelchair:"unicode/1f9bd.png?v8",maple_leaf:"unicode/1f341.png?v8",marshall_islands:"unicode/1f1f2-1f1ed.png?v8",martial_arts_uniform:"unicode/1f94b.png?v8",martinique:"unicode/1f1f2-1f1f6.png?v8",mask:"unicode/1f637.png?v8",massage:"unicode/1f486.png?v8",massage_man:"unicode/1f486-2642.png?v8",massage_woman:"unicode/1f486-2640.png?v8",mate:"unicode/1f9c9.png?v8",mauritania:"unicode/1f1f2-1f1f7.png?v8",mauritius:"unicode/1f1f2-1f1fa.png?v8",mayotte:"unicode/1f1fe-1f1f9.png?v8",meat_on_bone:"unicode/1f356.png?v8",mechanic:"unicode/1f9d1-1f527.png?v8",mechanical_arm:"unicode/1f9be.png?v8",mechanical_leg:"unicode/1f9bf.png?v8",medal_military:"unicode/1f396.png?v8",medal_sports:"unicode/1f3c5.png?v8",medical_symbol:"unicode/2695.png?v8",mega:"unicode/1f4e3.png?v8",melon:"unicode/1f348.png?v8",memo:"unicode/1f4dd.png?v8",men_wrestling:"unicode/1f93c-2642.png?v8",mending_heart:"unicode/2764-1fa79.png?v8",menorah:"unicode/1f54e.png?v8",mens:"unicode/1f6b9.png?v8",mermaid:"unicode/1f9dc-2640.png?v8",merman:"unicode/1f9dc-2642.png?v8",merperson:"unicode/1f9dc.png?v8",metal:"unicode/1f918.png?v8",metro:"unicode/1f687.png?v8",mexico:"unicode/1f1f2-1f1fd.png?v8",microbe:"unicode/1f9a0.png?v8",micronesia:"unicode/1f1eb-1f1f2.png?v8",microphone:"unicode/1f3a4.png?v8",microscope:"unicode/1f52c.png?v8",middle_finger:"unicode/1f595.png?v8",military_helmet:"unicode/1fa96.png?v8",milk_glass:"unicode/1f95b.png?v8",milky_way:"unicode/1f30c.png?v8",minibus:"unicode/1f690.png?v8",minidisc:"unicode/1f4bd.png?v8",mirror:"unicode/1fa9e.png?v8",mobile_phone_off:"unicode/1f4f4.png?v8",moldova:"unicode/1f1f2-1f1e9.png?v8",monaco:"unicode/1f1f2-1f1e8.png?v8",money_mouth_face:"unicode/1f911.png?v8",money_with_wings:"unicode/1f4b8.png?v8",moneybag:"unicode/1f4b0.png?v8",mongolia:"unicode/1f1f2-1f1f3.png?v8",monkey:"unicode/1f412.png?v8",monkey_face:"unicode/1f435.png?v8",monocle_face:"unicode/1f9d0.png?v8",monorail:"unicode/1f69d.png?v8",montenegro:"unicode/1f1f2-1f1ea.png?v8",montserrat:"unicode/1f1f2-1f1f8.png?v8",moon:"unicode/1f314.png?v8",moon_cake:"unicode/1f96e.png?v8",morocco:"unicode/1f1f2-1f1e6.png?v8",mortar_board:"unicode/1f393.png?v8",mosque:"unicode/1f54c.png?v8",mosquito:"unicode/1f99f.png?v8",motor_boat:"unicode/1f6e5.png?v8",motor_scooter:"unicode/1f6f5.png?v8",motorcycle:"unicode/1f3cd.png?v8",motorized_wheelchair:"unicode/1f9bc.png?v8",motorway:"unicode/1f6e3.png?v8",mount_fuji:"unicode/1f5fb.png?v8",mountain:"unicode/26f0.png?v8",mountain_bicyclist:"unicode/1f6b5.png?v8",mountain_biking_man:"unicode/1f6b5-2642.png?v8",mountain_biking_woman:"unicode/1f6b5-2640.png?v8",mountain_cableway:"unicode/1f6a0.png?v8",mountain_railway:"unicode/1f69e.png?v8",mountain_snow:"unicode/1f3d4.png?v8",mouse:"unicode/1f42d.png?v8",mouse2:"unicode/1f401.png?v8",mouse_trap:"unicode/1faa4.png?v8",movie_camera:"unicode/1f3a5.png?v8",moyai:"unicode/1f5ff.png?v8",mozambique:"unicode/1f1f2-1f1ff.png?v8",mrs_claus:"unicode/1f936.png?v8",muscle:"unicode/1f4aa.png?v8",mushroom:"unicode/1f344.png?v8",musical_keyboard:"unicode/1f3b9.png?v8",musical_note:"unicode/1f3b5.png?v8",musical_score:"unicode/1f3bc.png?v8",mute:"unicode/1f507.png?v8",mx_claus:"unicode/1f9d1-1f384.png?v8",myanmar:"unicode/1f1f2-1f1f2.png?v8",nail_care:"unicode/1f485.png?v8",name_badge:"unicode/1f4db.png?v8",namibia:"unicode/1f1f3-1f1e6.png?v8",national_park:"unicode/1f3de.png?v8",nauru:"unicode/1f1f3-1f1f7.png?v8",nauseated_face:"unicode/1f922.png?v8",nazar_amulet:"unicode/1f9ff.png?v8",neckbeard:"neckbeard.png?v8",necktie:"unicode/1f454.png?v8",negative_squared_cross_mark:"unicode/274e.png?v8",nepal:"unicode/1f1f3-1f1f5.png?v8",nerd_face:"unicode/1f913.png?v8",nesting_dolls:"unicode/1fa86.png?v8",netherlands:"unicode/1f1f3-1f1f1.png?v8",neutral_face:"unicode/1f610.png?v8",new:"unicode/1f195.png?v8",new_caledonia:"unicode/1f1f3-1f1e8.png?v8",new_moon:"unicode/1f311.png?v8",new_moon_with_face:"unicode/1f31a.png?v8",new_zealand:"unicode/1f1f3-1f1ff.png?v8",newspaper:"unicode/1f4f0.png?v8",newspaper_roll:"unicode/1f5de.png?v8",next_track_button:"unicode/23ed.png?v8",ng:"unicode/1f196.png?v8",ng_man:"unicode/1f645-2642.png?v8",ng_woman:"unicode/1f645-2640.png?v8",nicaragua:"unicode/1f1f3-1f1ee.png?v8",niger:"unicode/1f1f3-1f1ea.png?v8",nigeria:"unicode/1f1f3-1f1ec.png?v8",night_with_stars:"unicode/1f303.png?v8",nine:"unicode/0039-20e3.png?v8",ninja:"unicode/1f977.png?v8",niue:"unicode/1f1f3-1f1fa.png?v8",no_bell:"unicode/1f515.png?v8",no_bicycles:"unicode/1f6b3.png?v8",no_entry:"unicode/26d4.png?v8",no_entry_sign:"unicode/1f6ab.png?v8",no_good:"unicode/1f645.png?v8",no_good_man:"unicode/1f645-2642.png?v8",no_good_woman:"unicode/1f645-2640.png?v8",no_mobile_phones:"unicode/1f4f5.png?v8",no_mouth:"unicode/1f636.png?v8",no_pedestrians:"unicode/1f6b7.png?v8",no_smoking:"unicode/1f6ad.png?v8","non-potable_water":"unicode/1f6b1.png?v8",norfolk_island:"unicode/1f1f3-1f1eb.png?v8",north_korea:"unicode/1f1f0-1f1f5.png?v8",northern_mariana_islands:"unicode/1f1f2-1f1f5.png?v8",norway:"unicode/1f1f3-1f1f4.png?v8",nose:"unicode/1f443.png?v8",notebook:"unicode/1f4d3.png?v8",notebook_with_decorative_cover:"unicode/1f4d4.png?v8",notes:"unicode/1f3b6.png?v8",nut_and_bolt:"unicode/1f529.png?v8",o:"unicode/2b55.png?v8",o2:"unicode/1f17e.png?v8",ocean:"unicode/1f30a.png?v8",octocat:"octocat.png?v8",octopus:"unicode/1f419.png?v8",oden:"unicode/1f362.png?v8",office:"unicode/1f3e2.png?v8",office_worker:"unicode/1f9d1-1f4bc.png?v8",oil_drum:"unicode/1f6e2.png?v8",ok:"unicode/1f197.png?v8",ok_hand:"unicode/1f44c.png?v8",ok_man:"unicode/1f646-2642.png?v8",ok_person:"unicode/1f646.png?v8",ok_woman:"unicode/1f646-2640.png?v8",old_key:"unicode/1f5dd.png?v8",older_adult:"unicode/1f9d3.png?v8",older_man:"unicode/1f474.png?v8",older_woman:"unicode/1f475.png?v8",olive:"unicode/1fad2.png?v8",om:"unicode/1f549.png?v8",oman:"unicode/1f1f4-1f1f2.png?v8",on:"unicode/1f51b.png?v8",oncoming_automobile:"unicode/1f698.png?v8",oncoming_bus:"unicode/1f68d.png?v8",oncoming_police_car:"unicode/1f694.png?v8",oncoming_taxi:"unicode/1f696.png?v8",one:"unicode/0031-20e3.png?v8",one_piece_swimsuit:"unicode/1fa71.png?v8",onion:"unicode/1f9c5.png?v8",open_book:"unicode/1f4d6.png?v8",open_file_folder:"unicode/1f4c2.png?v8",open_hands:"unicode/1f450.png?v8",open_mouth:"unicode/1f62e.png?v8",open_umbrella:"unicode/2602.png?v8",ophiuchus:"unicode/26ce.png?v8",orange:"unicode/1f34a.png?v8",orange_book:"unicode/1f4d9.png?v8",orange_circle:"unicode/1f7e0.png?v8",orange_heart:"unicode/1f9e1.png?v8",orange_square:"unicode/1f7e7.png?v8",orangutan:"unicode/1f9a7.png?v8",orthodox_cross:"unicode/2626.png?v8",otter:"unicode/1f9a6.png?v8",outbox_tray:"unicode/1f4e4.png?v8",owl:"unicode/1f989.png?v8",ox:"unicode/1f402.png?v8",oyster:"unicode/1f9aa.png?v8",package:"unicode/1f4e6.png?v8",page_facing_up:"unicode/1f4c4.png?v8",page_with_curl:"unicode/1f4c3.png?v8",pager:"unicode/1f4df.png?v8",paintbrush:"unicode/1f58c.png?v8",pakistan:"unicode/1f1f5-1f1f0.png?v8",palau:"unicode/1f1f5-1f1fc.png?v8",palestinian_territories:"unicode/1f1f5-1f1f8.png?v8",palm_tree:"unicode/1f334.png?v8",palms_up_together:"unicode/1f932.png?v8",panama:"unicode/1f1f5-1f1e6.png?v8",pancakes:"unicode/1f95e.png?v8",panda_face:"unicode/1f43c.png?v8",paperclip:"unicode/1f4ce.png?v8",paperclips:"unicode/1f587.png?v8",papua_new_guinea:"unicode/1f1f5-1f1ec.png?v8",parachute:"unicode/1fa82.png?v8",paraguay:"unicode/1f1f5-1f1fe.png?v8",parasol_on_ground:"unicode/26f1.png?v8",parking:"unicode/1f17f.png?v8",parrot:"unicode/1f99c.png?v8",part_alternation_mark:"unicode/303d.png?v8",partly_sunny:"unicode/26c5.png?v8",partying_face:"unicode/1f973.png?v8",passenger_ship:"unicode/1f6f3.png?v8",passport_control:"unicode/1f6c2.png?v8",pause_button:"unicode/23f8.png?v8",paw_prints:"unicode/1f43e.png?v8",peace_symbol:"unicode/262e.png?v8",peach:"unicode/1f351.png?v8",peacock:"unicode/1f99a.png?v8",peanuts:"unicode/1f95c.png?v8",pear:"unicode/1f350.png?v8",pen:"unicode/1f58a.png?v8",pencil:"unicode/1f4dd.png?v8",pencil2:"unicode/270f.png?v8",penguin:"unicode/1f427.png?v8",pensive:"unicode/1f614.png?v8",people_holding_hands:"unicode/1f9d1-1f91d-1f9d1.png?v8",people_hugging:"unicode/1fac2.png?v8",performing_arts:"unicode/1f3ad.png?v8",persevere:"unicode/1f623.png?v8",person_bald:"unicode/1f9d1-1f9b2.png?v8",person_curly_hair:"unicode/1f9d1-1f9b1.png?v8",person_feeding_baby:"unicode/1f9d1-1f37c.png?v8",person_fencing:"unicode/1f93a.png?v8",person_in_manual_wheelchair:"unicode/1f9d1-1f9bd.png?v8",person_in_motorized_wheelchair:"unicode/1f9d1-1f9bc.png?v8",person_in_tuxedo:"unicode/1f935.png?v8",person_red_hair:"unicode/1f9d1-1f9b0.png?v8",person_white_hair:"unicode/1f9d1-1f9b3.png?v8",person_with_probing_cane:"unicode/1f9d1-1f9af.png?v8",person_with_turban:"unicode/1f473.png?v8",person_with_veil:"unicode/1f470.png?v8",peru:"unicode/1f1f5-1f1ea.png?v8",petri_dish:"unicode/1f9eb.png?v8",philippines:"unicode/1f1f5-1f1ed.png?v8",phone:"unicode/260e.png?v8",pick:"unicode/26cf.png?v8",pickup_truck:"unicode/1f6fb.png?v8",pie:"unicode/1f967.png?v8",pig:"unicode/1f437.png?v8",pig2:"unicode/1f416.png?v8",pig_nose:"unicode/1f43d.png?v8",pill:"unicode/1f48a.png?v8",pilot:"unicode/1f9d1-2708.png?v8",pinata:"unicode/1fa85.png?v8",pinched_fingers:"unicode/1f90c.png?v8",pinching_hand:"unicode/1f90f.png?v8",pineapple:"unicode/1f34d.png?v8",ping_pong:"unicode/1f3d3.png?v8",pirate_flag:"unicode/1f3f4-2620.png?v8",pisces:"unicode/2653.png?v8",pitcairn_islands:"unicode/1f1f5-1f1f3.png?v8",pizza:"unicode/1f355.png?v8",placard:"unicode/1faa7.png?v8",place_of_worship:"unicode/1f6d0.png?v8",plate_with_cutlery:"unicode/1f37d.png?v8",play_or_pause_button:"unicode/23ef.png?v8",pleading_face:"unicode/1f97a.png?v8",plunger:"unicode/1faa0.png?v8",point_down:"unicode/1f447.png?v8",point_left:"unicode/1f448.png?v8",point_right:"unicode/1f449.png?v8",point_up:"unicode/261d.png?v8",point_up_2:"unicode/1f446.png?v8",poland:"unicode/1f1f5-1f1f1.png?v8",polar_bear:"unicode/1f43b-2744.png?v8",police_car:"unicode/1f693.png?v8",police_officer:"unicode/1f46e.png?v8",policeman:"unicode/1f46e-2642.png?v8",policewoman:"unicode/1f46e-2640.png?v8",poodle:"unicode/1f429.png?v8",poop:"unicode/1f4a9.png?v8",popcorn:"unicode/1f37f.png?v8",portugal:"unicode/1f1f5-1f1f9.png?v8",post_office:"unicode/1f3e3.png?v8",postal_horn:"unicode/1f4ef.png?v8",postbox:"unicode/1f4ee.png?v8",potable_water:"unicode/1f6b0.png?v8",potato:"unicode/1f954.png?v8",potted_plant:"unicode/1fab4.png?v8",pouch:"unicode/1f45d.png?v8",poultry_leg:"unicode/1f357.png?v8",pound:"unicode/1f4b7.png?v8",pout:"unicode/1f621.png?v8",pouting_cat:"unicode/1f63e.png?v8",pouting_face:"unicode/1f64e.png?v8",pouting_man:"unicode/1f64e-2642.png?v8",pouting_woman:"unicode/1f64e-2640.png?v8",pray:"unicode/1f64f.png?v8",prayer_beads:"unicode/1f4ff.png?v8",pregnant_woman:"unicode/1f930.png?v8",pretzel:"unicode/1f968.png?v8",previous_track_button:"unicode/23ee.png?v8",prince:"unicode/1f934.png?v8",princess:"unicode/1f478.png?v8",printer:"unicode/1f5a8.png?v8",probing_cane:"unicode/1f9af.png?v8",puerto_rico:"unicode/1f1f5-1f1f7.png?v8",punch:"unicode/1f44a.png?v8",purple_circle:"unicode/1f7e3.png?v8",purple_heart:"unicode/1f49c.png?v8",purple_square:"unicode/1f7ea.png?v8",purse:"unicode/1f45b.png?v8",pushpin:"unicode/1f4cc.png?v8",put_litter_in_its_place:"unicode/1f6ae.png?v8",qatar:"unicode/1f1f6-1f1e6.png?v8",question:"unicode/2753.png?v8",rabbit:"unicode/1f430.png?v8",rabbit2:"unicode/1f407.png?v8",raccoon:"unicode/1f99d.png?v8",racehorse:"unicode/1f40e.png?v8",racing_car:"unicode/1f3ce.png?v8",radio:"unicode/1f4fb.png?v8",radio_button:"unicode/1f518.png?v8",radioactive:"unicode/2622.png?v8",rage:"unicode/1f621.png?v8",rage1:"rage1.png?v8",rage2:"rage2.png?v8",rage3:"rage3.png?v8",rage4:"rage4.png?v8",railway_car:"unicode/1f683.png?v8",railway_track:"unicode/1f6e4.png?v8",rainbow:"unicode/1f308.png?v8",rainbow_flag:"unicode/1f3f3-1f308.png?v8",raised_back_of_hand:"unicode/1f91a.png?v8",raised_eyebrow:"unicode/1f928.png?v8",raised_hand:"unicode/270b.png?v8",raised_hand_with_fingers_splayed:"unicode/1f590.png?v8",raised_hands:"unicode/1f64c.png?v8",raising_hand:"unicode/1f64b.png?v8",raising_hand_man:"unicode/1f64b-2642.png?v8",raising_hand_woman:"unicode/1f64b-2640.png?v8",ram:"unicode/1f40f.png?v8",ramen:"unicode/1f35c.png?v8",rat:"unicode/1f400.png?v8",razor:"unicode/1fa92.png?v8",receipt:"unicode/1f9fe.png?v8",record_button:"unicode/23fa.png?v8",recycle:"unicode/267b.png?v8",red_car:"unicode/1f697.png?v8",red_circle:"unicode/1f534.png?v8",red_envelope:"unicode/1f9e7.png?v8",red_haired_man:"unicode/1f468-1f9b0.png?v8",red_haired_woman:"unicode/1f469-1f9b0.png?v8",red_square:"unicode/1f7e5.png?v8",registered:"unicode/00ae.png?v8",relaxed:"unicode/263a.png?v8",relieved:"unicode/1f60c.png?v8",reminder_ribbon:"unicode/1f397.png?v8",repeat:"unicode/1f501.png?v8",repeat_one:"unicode/1f502.png?v8",rescue_worker_helmet:"unicode/26d1.png?v8",restroom:"unicode/1f6bb.png?v8",reunion:"unicode/1f1f7-1f1ea.png?v8",revolving_hearts:"unicode/1f49e.png?v8",rewind:"unicode/23ea.png?v8",rhinoceros:"unicode/1f98f.png?v8",ribbon:"unicode/1f380.png?v8",rice:"unicode/1f35a.png?v8",rice_ball:"unicode/1f359.png?v8",rice_cracker:"unicode/1f358.png?v8",rice_scene:"unicode/1f391.png?v8",right_anger_bubble:"unicode/1f5ef.png?v8",ring:"unicode/1f48d.png?v8",ringed_planet:"unicode/1fa90.png?v8",robot:"unicode/1f916.png?v8",rock:"unicode/1faa8.png?v8",rocket:"unicode/1f680.png?v8",rofl:"unicode/1f923.png?v8",roll_eyes:"unicode/1f644.png?v8",roll_of_paper:"unicode/1f9fb.png?v8",roller_coaster:"unicode/1f3a2.png?v8",roller_skate:"unicode/1f6fc.png?v8",romania:"unicode/1f1f7-1f1f4.png?v8",rooster:"unicode/1f413.png?v8",rose:"unicode/1f339.png?v8",rosette:"unicode/1f3f5.png?v8",rotating_light:"unicode/1f6a8.png?v8",round_pushpin:"unicode/1f4cd.png?v8",rowboat:"unicode/1f6a3.png?v8",rowing_man:"unicode/1f6a3-2642.png?v8",rowing_woman:"unicode/1f6a3-2640.png?v8",ru:"unicode/1f1f7-1f1fa.png?v8",rugby_football:"unicode/1f3c9.png?v8",runner:"unicode/1f3c3.png?v8",running:"unicode/1f3c3.png?v8",running_man:"unicode/1f3c3-2642.png?v8",running_shirt_with_sash:"unicode/1f3bd.png?v8",running_woman:"unicode/1f3c3-2640.png?v8",rwanda:"unicode/1f1f7-1f1fc.png?v8",sa:"unicode/1f202.png?v8",safety_pin:"unicode/1f9f7.png?v8",safety_vest:"unicode/1f9ba.png?v8",sagittarius:"unicode/2650.png?v8",sailboat:"unicode/26f5.png?v8",sake:"unicode/1f376.png?v8",salt:"unicode/1f9c2.png?v8",samoa:"unicode/1f1fc-1f1f8.png?v8",san_marino:"unicode/1f1f8-1f1f2.png?v8",sandal:"unicode/1f461.png?v8",sandwich:"unicode/1f96a.png?v8",santa:"unicode/1f385.png?v8",sao_tome_principe:"unicode/1f1f8-1f1f9.png?v8",sari:"unicode/1f97b.png?v8",sassy_man:"unicode/1f481-2642.png?v8",sassy_woman:"unicode/1f481-2640.png?v8",satellite:"unicode/1f4e1.png?v8",satisfied:"unicode/1f606.png?v8",saudi_arabia:"unicode/1f1f8-1f1e6.png?v8",sauna_man:"unicode/1f9d6-2642.png?v8",sauna_person:"unicode/1f9d6.png?v8",sauna_woman:"unicode/1f9d6-2640.png?v8",sauropod:"unicode/1f995.png?v8",saxophone:"unicode/1f3b7.png?v8",scarf:"unicode/1f9e3.png?v8",school:"unicode/1f3eb.png?v8",school_satchel:"unicode/1f392.png?v8",scientist:"unicode/1f9d1-1f52c.png?v8",scissors:"unicode/2702.png?v8",scorpion:"unicode/1f982.png?v8",scorpius:"unicode/264f.png?v8",scotland:"unicode/1f3f4-e0067-e0062-e0073-e0063-e0074-e007f.png?v8",scream:"unicode/1f631.png?v8",scream_cat:"unicode/1f640.png?v8",screwdriver:"unicode/1fa9b.png?v8",scroll:"unicode/1f4dc.png?v8",seal:"unicode/1f9ad.png?v8",seat:"unicode/1f4ba.png?v8",secret:"unicode/3299.png?v8",see_no_evil:"unicode/1f648.png?v8",seedling:"unicode/1f331.png?v8",selfie:"unicode/1f933.png?v8",senegal:"unicode/1f1f8-1f1f3.png?v8",serbia:"unicode/1f1f7-1f1f8.png?v8",service_dog:"unicode/1f415-1f9ba.png?v8",seven:"unicode/0037-20e3.png?v8",sewing_needle:"unicode/1faa1.png?v8",seychelles:"unicode/1f1f8-1f1e8.png?v8",shallow_pan_of_food:"unicode/1f958.png?v8",shamrock:"unicode/2618.png?v8",shark:"unicode/1f988.png?v8",shaved_ice:"unicode/1f367.png?v8",sheep:"unicode/1f411.png?v8",shell:"unicode/1f41a.png?v8",shield:"unicode/1f6e1.png?v8",shinto_shrine:"unicode/26e9.png?v8",ship:"unicode/1f6a2.png?v8",shipit:"shipit.png?v8",shirt:"unicode/1f455.png?v8",shit:"unicode/1f4a9.png?v8",shoe:"unicode/1f45e.png?v8",shopping:"unicode/1f6cd.png?v8",shopping_cart:"unicode/1f6d2.png?v8",shorts:"unicode/1fa73.png?v8",shower:"unicode/1f6bf.png?v8",shrimp:"unicode/1f990.png?v8",shrug:"unicode/1f937.png?v8",shushing_face:"unicode/1f92b.png?v8",sierra_leone:"unicode/1f1f8-1f1f1.png?v8",signal_strength:"unicode/1f4f6.png?v8",singapore:"unicode/1f1f8-1f1ec.png?v8",singer:"unicode/1f9d1-1f3a4.png?v8",sint_maarten:"unicode/1f1f8-1f1fd.png?v8",six:"unicode/0036-20e3.png?v8",six_pointed_star:"unicode/1f52f.png?v8",skateboard:"unicode/1f6f9.png?v8",ski:"unicode/1f3bf.png?v8",skier:"unicode/26f7.png?v8",skull:"unicode/1f480.png?v8",skull_and_crossbones:"unicode/2620.png?v8",skunk:"unicode/1f9a8.png?v8",sled:"unicode/1f6f7.png?v8",sleeping:"unicode/1f634.png?v8",sleeping_bed:"unicode/1f6cc.png?v8",sleepy:"unicode/1f62a.png?v8",slightly_frowning_face:"unicode/1f641.png?v8",slightly_smiling_face:"unicode/1f642.png?v8",slot_machine:"unicode/1f3b0.png?v8",sloth:"unicode/1f9a5.png?v8",slovakia:"unicode/1f1f8-1f1f0.png?v8",slovenia:"unicode/1f1f8-1f1ee.png?v8",small_airplane:"unicode/1f6e9.png?v8",small_blue_diamond:"unicode/1f539.png?v8",small_orange_diamond:"unicode/1f538.png?v8",small_red_triangle:"unicode/1f53a.png?v8",small_red_triangle_down:"unicode/1f53b.png?v8",smile:"unicode/1f604.png?v8",smile_cat:"unicode/1f638.png?v8",smiley:"unicode/1f603.png?v8",smiley_cat:"unicode/1f63a.png?v8",smiling_face_with_tear:"unicode/1f972.png?v8",smiling_face_with_three_hearts:"unicode/1f970.png?v8",smiling_imp:"unicode/1f608.png?v8",smirk:"unicode/1f60f.png?v8",smirk_cat:"unicode/1f63c.png?v8",smoking:"unicode/1f6ac.png?v8",snail:"unicode/1f40c.png?v8",snake:"unicode/1f40d.png?v8",sneezing_face:"unicode/1f927.png?v8",snowboarder:"unicode/1f3c2.png?v8",snowflake:"unicode/2744.png?v8",snowman:"unicode/26c4.png?v8",snowman_with_snow:"unicode/2603.png?v8",soap:"unicode/1f9fc.png?v8",sob:"unicode/1f62d.png?v8",soccer:"unicode/26bd.png?v8",socks:"unicode/1f9e6.png?v8",softball:"unicode/1f94e.png?v8",solomon_islands:"unicode/1f1f8-1f1e7.png?v8",somalia:"unicode/1f1f8-1f1f4.png?v8",soon:"unicode/1f51c.png?v8",sos:"unicode/1f198.png?v8",sound:"unicode/1f509.png?v8",south_africa:"unicode/1f1ff-1f1e6.png?v8",south_georgia_south_sandwich_islands:"unicode/1f1ec-1f1f8.png?v8",south_sudan:"unicode/1f1f8-1f1f8.png?v8",space_invader:"unicode/1f47e.png?v8",spades:"unicode/2660.png?v8",spaghetti:"unicode/1f35d.png?v8",sparkle:"unicode/2747.png?v8",sparkler:"unicode/1f387.png?v8",sparkles:"unicode/2728.png?v8",sparkling_heart:"unicode/1f496.png?v8",speak_no_evil:"unicode/1f64a.png?v8",speaker:"unicode/1f508.png?v8",speaking_head:"unicode/1f5e3.png?v8",speech_balloon:"unicode/1f4ac.png?v8",speedboat:"unicode/1f6a4.png?v8",spider:"unicode/1f577.png?v8",spider_web:"unicode/1f578.png?v8",spiral_calendar:"unicode/1f5d3.png?v8",spiral_notepad:"unicode/1f5d2.png?v8",sponge:"unicode/1f9fd.png?v8",spoon:"unicode/1f944.png?v8",squid:"unicode/1f991.png?v8",sri_lanka:"unicode/1f1f1-1f1f0.png?v8",st_barthelemy:"unicode/1f1e7-1f1f1.png?v8",st_helena:"unicode/1f1f8-1f1ed.png?v8",st_kitts_nevis:"unicode/1f1f0-1f1f3.png?v8",st_lucia:"unicode/1f1f1-1f1e8.png?v8",st_martin:"unicode/1f1f2-1f1eb.png?v8",st_pierre_miquelon:"unicode/1f1f5-1f1f2.png?v8",st_vincent_grenadines:"unicode/1f1fb-1f1e8.png?v8",stadium:"unicode/1f3df.png?v8",standing_man:"unicode/1f9cd-2642.png?v8",standing_person:"unicode/1f9cd.png?v8",standing_woman:"unicode/1f9cd-2640.png?v8",star:"unicode/2b50.png?v8",star2:"unicode/1f31f.png?v8",star_and_crescent:"unicode/262a.png?v8",star_of_david:"unicode/2721.png?v8",star_struck:"unicode/1f929.png?v8",stars:"unicode/1f320.png?v8",station:"unicode/1f689.png?v8",statue_of_liberty:"unicode/1f5fd.png?v8",steam_locomotive:"unicode/1f682.png?v8",stethoscope:"unicode/1fa7a.png?v8",stew:"unicode/1f372.png?v8",stop_button:"unicode/23f9.png?v8",stop_sign:"unicode/1f6d1.png?v8",stopwatch:"unicode/23f1.png?v8",straight_ruler:"unicode/1f4cf.png?v8",strawberry:"unicode/1f353.png?v8",stuck_out_tongue:"unicode/1f61b.png?v8",stuck_out_tongue_closed_eyes:"unicode/1f61d.png?v8",stuck_out_tongue_winking_eye:"unicode/1f61c.png?v8",student:"unicode/1f9d1-1f393.png?v8",studio_microphone:"unicode/1f399.png?v8",stuffed_flatbread:"unicode/1f959.png?v8",sudan:"unicode/1f1f8-1f1e9.png?v8",sun_behind_large_cloud:"unicode/1f325.png?v8",sun_behind_rain_cloud:"unicode/1f326.png?v8",sun_behind_small_cloud:"unicode/1f324.png?v8",sun_with_face:"unicode/1f31e.png?v8",sunflower:"unicode/1f33b.png?v8",sunglasses:"unicode/1f60e.png?v8",sunny:"unicode/2600.png?v8",sunrise:"unicode/1f305.png?v8",sunrise_over_mountains:"unicode/1f304.png?v8",superhero:"unicode/1f9b8.png?v8",superhero_man:"unicode/1f9b8-2642.png?v8",superhero_woman:"unicode/1f9b8-2640.png?v8",supervillain:"unicode/1f9b9.png?v8",supervillain_man:"unicode/1f9b9-2642.png?v8",supervillain_woman:"unicode/1f9b9-2640.png?v8",surfer:"unicode/1f3c4.png?v8",surfing_man:"unicode/1f3c4-2642.png?v8",surfing_woman:"unicode/1f3c4-2640.png?v8",suriname:"unicode/1f1f8-1f1f7.png?v8",sushi:"unicode/1f363.png?v8",suspect:"suspect.png?v8",suspension_railway:"unicode/1f69f.png?v8",svalbard_jan_mayen:"unicode/1f1f8-1f1ef.png?v8",swan:"unicode/1f9a2.png?v8",swaziland:"unicode/1f1f8-1f1ff.png?v8",sweat:"unicode/1f613.png?v8",sweat_drops:"unicode/1f4a6.png?v8",sweat_smile:"unicode/1f605.png?v8",sweden:"unicode/1f1f8-1f1ea.png?v8",sweet_potato:"unicode/1f360.png?v8",swim_brief:"unicode/1fa72.png?v8",swimmer:"unicode/1f3ca.png?v8",swimming_man:"unicode/1f3ca-2642.png?v8",swimming_woman:"unicode/1f3ca-2640.png?v8",switzerland:"unicode/1f1e8-1f1ed.png?v8",symbols:"unicode/1f523.png?v8",synagogue:"unicode/1f54d.png?v8",syria:"unicode/1f1f8-1f1fe.png?v8",syringe:"unicode/1f489.png?v8","t-rex":"unicode/1f996.png?v8",taco:"unicode/1f32e.png?v8",tada:"unicode/1f389.png?v8",taiwan:"unicode/1f1f9-1f1fc.png?v8",tajikistan:"unicode/1f1f9-1f1ef.png?v8",takeout_box:"unicode/1f961.png?v8",tamale:"unicode/1fad4.png?v8",tanabata_tree:"unicode/1f38b.png?v8",tangerine:"unicode/1f34a.png?v8",tanzania:"unicode/1f1f9-1f1ff.png?v8",taurus:"unicode/2649.png?v8",taxi:"unicode/1f695.png?v8",tea:"unicode/1f375.png?v8",teacher:"unicode/1f9d1-1f3eb.png?v8",teapot:"unicode/1fad6.png?v8",technologist:"unicode/1f9d1-1f4bb.png?v8",teddy_bear:"unicode/1f9f8.png?v8",telephone:"unicode/260e.png?v8",telephone_receiver:"unicode/1f4de.png?v8",telescope:"unicode/1f52d.png?v8",tennis:"unicode/1f3be.png?v8",tent:"unicode/26fa.png?v8",test_tube:"unicode/1f9ea.png?v8",thailand:"unicode/1f1f9-1f1ed.png?v8",thermometer:"unicode/1f321.png?v8",thinking:"unicode/1f914.png?v8",thong_sandal:"unicode/1fa74.png?v8",thought_balloon:"unicode/1f4ad.png?v8",thread:"unicode/1f9f5.png?v8",three:"unicode/0033-20e3.png?v8",thumbsdown:"unicode/1f44e.png?v8",thumbsup:"unicode/1f44d.png?v8",ticket:"unicode/1f3ab.png?v8",tickets:"unicode/1f39f.png?v8",tiger:"unicode/1f42f.png?v8",tiger2:"unicode/1f405.png?v8",timer_clock:"unicode/23f2.png?v8",timor_leste:"unicode/1f1f9-1f1f1.png?v8",tipping_hand_man:"unicode/1f481-2642.png?v8",tipping_hand_person:"unicode/1f481.png?v8",tipping_hand_woman:"unicode/1f481-2640.png?v8",tired_face:"unicode/1f62b.png?v8",tm:"unicode/2122.png?v8",togo:"unicode/1f1f9-1f1ec.png?v8",toilet:"unicode/1f6bd.png?v8",tokelau:"unicode/1f1f9-1f1f0.png?v8",tokyo_tower:"unicode/1f5fc.png?v8",tomato:"unicode/1f345.png?v8",tonga:"unicode/1f1f9-1f1f4.png?v8",tongue:"unicode/1f445.png?v8",toolbox:"unicode/1f9f0.png?v8",tooth:"unicode/1f9b7.png?v8",toothbrush:"unicode/1faa5.png?v8",top:"unicode/1f51d.png?v8",tophat:"unicode/1f3a9.png?v8",tornado:"unicode/1f32a.png?v8",tr:"unicode/1f1f9-1f1f7.png?v8",trackball:"unicode/1f5b2.png?v8",tractor:"unicode/1f69c.png?v8",traffic_light:"unicode/1f6a5.png?v8",train:"unicode/1f68b.png?v8",train2:"unicode/1f686.png?v8",tram:"unicode/1f68a.png?v8",transgender_flag:"unicode/1f3f3-26a7.png?v8",transgender_symbol:"unicode/26a7.png?v8",triangular_flag_on_post:"unicode/1f6a9.png?v8",triangular_ruler:"unicode/1f4d0.png?v8",trident:"unicode/1f531.png?v8",trinidad_tobago:"unicode/1f1f9-1f1f9.png?v8",tristan_da_cunha:"unicode/1f1f9-1f1e6.png?v8",triumph:"unicode/1f624.png?v8",trolleybus:"unicode/1f68e.png?v8",trollface:"trollface.png?v8",trophy:"unicode/1f3c6.png?v8",tropical_drink:"unicode/1f379.png?v8",tropical_fish:"unicode/1f420.png?v8",truck:"unicode/1f69a.png?v8",trumpet:"unicode/1f3ba.png?v8",tshirt:"unicode/1f455.png?v8",tulip:"unicode/1f337.png?v8",tumbler_glass:"unicode/1f943.png?v8",tunisia:"unicode/1f1f9-1f1f3.png?v8",turkey:"unicode/1f983.png?v8",turkmenistan:"unicode/1f1f9-1f1f2.png?v8",turks_caicos_islands:"unicode/1f1f9-1f1e8.png?v8",turtle:"unicode/1f422.png?v8",tuvalu:"unicode/1f1f9-1f1fb.png?v8",tv:"unicode/1f4fa.png?v8",twisted_rightwards_arrows:"unicode/1f500.png?v8",two:"unicode/0032-20e3.png?v8",two_hearts:"unicode/1f495.png?v8",two_men_holding_hands:"unicode/1f46c.png?v8",two_women_holding_hands:"unicode/1f46d.png?v8",u5272:"unicode/1f239.png?v8",u5408:"unicode/1f234.png?v8",u55b6:"unicode/1f23a.png?v8",u6307:"unicode/1f22f.png?v8",u6708:"unicode/1f237.png?v8",u6709:"unicode/1f236.png?v8",u6e80:"unicode/1f235.png?v8",u7121:"unicode/1f21a.png?v8",u7533:"unicode/1f238.png?v8",u7981:"unicode/1f232.png?v8",u7a7a:"unicode/1f233.png?v8",uganda:"unicode/1f1fa-1f1ec.png?v8",uk:"unicode/1f1ec-1f1e7.png?v8",ukraine:"unicode/1f1fa-1f1e6.png?v8",umbrella:"unicode/2614.png?v8",unamused:"unicode/1f612.png?v8",underage:"unicode/1f51e.png?v8",unicorn:"unicode/1f984.png?v8",united_arab_emirates:"unicode/1f1e6-1f1ea.png?v8",united_nations:"unicode/1f1fa-1f1f3.png?v8",unlock:"unicode/1f513.png?v8",up:"unicode/1f199.png?v8",upside_down_face:"unicode/1f643.png?v8",uruguay:"unicode/1f1fa-1f1fe.png?v8",us:"unicode/1f1fa-1f1f8.png?v8",us_outlying_islands:"unicode/1f1fa-1f1f2.png?v8",us_virgin_islands:"unicode/1f1fb-1f1ee.png?v8",uzbekistan:"unicode/1f1fa-1f1ff.png?v8",v:"unicode/270c.png?v8",vampire:"unicode/1f9db.png?v8",vampire_man:"unicode/1f9db-2642.png?v8",vampire_woman:"unicode/1f9db-2640.png?v8",vanuatu:"unicode/1f1fb-1f1fa.png?v8",vatican_city:"unicode/1f1fb-1f1e6.png?v8",venezuela:"unicode/1f1fb-1f1ea.png?v8",vertical_traffic_light:"unicode/1f6a6.png?v8",vhs:"unicode/1f4fc.png?v8",vibration_mode:"unicode/1f4f3.png?v8",video_camera:"unicode/1f4f9.png?v8",video_game:"unicode/1f3ae.png?v8",vietnam:"unicode/1f1fb-1f1f3.png?v8",violin:"unicode/1f3bb.png?v8",virgo:"unicode/264d.png?v8",volcano:"unicode/1f30b.png?v8",volleyball:"unicode/1f3d0.png?v8",vomiting_face:"unicode/1f92e.png?v8",vs:"unicode/1f19a.png?v8",vulcan_salute:"unicode/1f596.png?v8",waffle:"unicode/1f9c7.png?v8",wales:"unicode/1f3f4-e0067-e0062-e0077-e006c-e0073-e007f.png?v8",walking:"unicode/1f6b6.png?v8",walking_man:"unicode/1f6b6-2642.png?v8",walking_woman:"unicode/1f6b6-2640.png?v8",wallis_futuna:"unicode/1f1fc-1f1eb.png?v8",waning_crescent_moon:"unicode/1f318.png?v8",waning_gibbous_moon:"unicode/1f316.png?v8",warning:"unicode/26a0.png?v8",wastebasket:"unicode/1f5d1.png?v8",watch:"unicode/231a.png?v8",water_buffalo:"unicode/1f403.png?v8",water_polo:"unicode/1f93d.png?v8",watermelon:"unicode/1f349.png?v8",wave:"unicode/1f44b.png?v8",wavy_dash:"unicode/3030.png?v8",waxing_crescent_moon:"unicode/1f312.png?v8",waxing_gibbous_moon:"unicode/1f314.png?v8",wc:"unicode/1f6be.png?v8",weary:"unicode/1f629.png?v8",wedding:"unicode/1f492.png?v8",weight_lifting:"unicode/1f3cb.png?v8",weight_lifting_man:"unicode/1f3cb-2642.png?v8",weight_lifting_woman:"unicode/1f3cb-2640.png?v8",western_sahara:"unicode/1f1ea-1f1ed.png?v8",whale:"unicode/1f433.png?v8",whale2:"unicode/1f40b.png?v8",wheel_of_dharma:"unicode/2638.png?v8",wheelchair:"unicode/267f.png?v8",white_check_mark:"unicode/2705.png?v8",white_circle:"unicode/26aa.png?v8",white_flag:"unicode/1f3f3.png?v8",white_flower:"unicode/1f4ae.png?v8",white_haired_man:"unicode/1f468-1f9b3.png?v8",white_haired_woman:"unicode/1f469-1f9b3.png?v8",white_heart:"unicode/1f90d.png?v8",white_large_square:"unicode/2b1c.png?v8",white_medium_small_square:"unicode/25fd.png?v8",white_medium_square:"unicode/25fb.png?v8",white_small_square:"unicode/25ab.png?v8",white_square_button:"unicode/1f533.png?v8",wilted_flower:"unicode/1f940.png?v8",wind_chime:"unicode/1f390.png?v8",wind_face:"unicode/1f32c.png?v8",window:"unicode/1fa9f.png?v8",wine_glass:"unicode/1f377.png?v8",wink:"unicode/1f609.png?v8",wolf:"unicode/1f43a.png?v8",woman:"unicode/1f469.png?v8",woman_artist:"unicode/1f469-1f3a8.png?v8",woman_astronaut:"unicode/1f469-1f680.png?v8",woman_beard:"unicode/1f9d4-2640.png?v8",woman_cartwheeling:"unicode/1f938-2640.png?v8",woman_cook:"unicode/1f469-1f373.png?v8",woman_dancing:"unicode/1f483.png?v8",woman_facepalming:"unicode/1f926-2640.png?v8",woman_factory_worker:"unicode/1f469-1f3ed.png?v8",woman_farmer:"unicode/1f469-1f33e.png?v8",woman_feeding_baby:"unicode/1f469-1f37c.png?v8",woman_firefighter:"unicode/1f469-1f692.png?v8",woman_health_worker:"unicode/1f469-2695.png?v8",woman_in_manual_wheelchair:"unicode/1f469-1f9bd.png?v8",woman_in_motorized_wheelchair:"unicode/1f469-1f9bc.png?v8",woman_in_tuxedo:"unicode/1f935-2640.png?v8",woman_judge:"unicode/1f469-2696.png?v8",woman_juggling:"unicode/1f939-2640.png?v8",woman_mechanic:"unicode/1f469-1f527.png?v8",woman_office_worker:"unicode/1f469-1f4bc.png?v8",woman_pilot:"unicode/1f469-2708.png?v8",woman_playing_handball:"unicode/1f93e-2640.png?v8",woman_playing_water_polo:"unicode/1f93d-2640.png?v8",woman_scientist:"unicode/1f469-1f52c.png?v8",woman_shrugging:"unicode/1f937-2640.png?v8",woman_singer:"unicode/1f469-1f3a4.png?v8",woman_student:"unicode/1f469-1f393.png?v8",woman_teacher:"unicode/1f469-1f3eb.png?v8",woman_technologist:"unicode/1f469-1f4bb.png?v8",woman_with_headscarf:"unicode/1f9d5.png?v8",woman_with_probing_cane:"unicode/1f469-1f9af.png?v8",woman_with_turban:"unicode/1f473-2640.png?v8",woman_with_veil:"unicode/1f470-2640.png?v8",womans_clothes:"unicode/1f45a.png?v8",womans_hat:"unicode/1f452.png?v8",women_wrestling:"unicode/1f93c-2640.png?v8",womens:"unicode/1f6ba.png?v8",wood:"unicode/1fab5.png?v8",woozy_face:"unicode/1f974.png?v8",world_map:"unicode/1f5fa.png?v8",worm:"unicode/1fab1.png?v8",worried:"unicode/1f61f.png?v8",wrench:"unicode/1f527.png?v8",wrestling:"unicode/1f93c.png?v8",writing_hand:"unicode/270d.png?v8",x:"unicode/274c.png?v8",yarn:"unicode/1f9f6.png?v8",yawning_face:"unicode/1f971.png?v8",yellow_circle:"unicode/1f7e1.png?v8",yellow_heart:"unicode/1f49b.png?v8",yellow_square:"unicode/1f7e8.png?v8",yemen:"unicode/1f1fe-1f1ea.png?v8",yen:"unicode/1f4b4.png?v8",yin_yang:"unicode/262f.png?v8",yo_yo:"unicode/1fa80.png?v8",yum:"unicode/1f60b.png?v8",zambia:"unicode/1f1ff-1f1f2.png?v8",zany_face:"unicode/1f92a.png?v8",zap:"unicode/26a1.png?v8",zebra:"unicode/1f993.png?v8",zero:"unicode/0030-20e3.png?v8",zimbabwe:"unicode/1f1ff-1f1fc.png?v8",zipper_mouth_face:"unicode/1f910.png?v8",zombie:"unicode/1f9df.png?v8",zombie_man:"unicode/1f9df-2642.png?v8",zombie_woman:"unicode/1f9df-2640.png?v8",zzz:"unicode/1f4a4.png?v8"}};function jn(e,t){return e.replace(/<(code|pre|script|template)[^>]*?>[\s\S]+?<\/(code|pre|script|template)>/g,function(e){return e.replace(/:/g,"__colon__")}).replace(/<!--[\s\S]+?-->/g,function(e){return e.replace(/:/g,"__colon__")}).replace(/([a-z]{2,}:)?\/\/[^\s'">)]+/gi,function(e){return e.replace(/:/g,"__colon__")}).replace(/:([a-z0-9_\-+]+?):/g,function(e,n){return i=e,o=n,e=t,n=Rn.data[o],i,i=n?e&&/unicode/.test(n)?'<span class="emoji">'+n.replace("unicode/","").replace(/\.png.*/,"").split("-").map(function(e){return"&#x"+e+";"}).join("&zwj;").concat("&#xFE0E;")+"</span>":'<img src="'+Rn.baseURL+n+'.png" alt="'+o+'" class="emoji" loading="lazy">':i;var i,o}).replace(/__colon__/g,":")}function On(e){var o={};return{str:e=(e=void 0===e?"":e)&&e.replace(/^('|")/,"").replace(/('|")$/,"").replace(/(?:^|\s):([\w-]+:?)=?([\w-%]+)?/g,function(e,n,i){return-1===n.indexOf(":")?(o[n]=i&&i.replace(/&quot;/g,"")||!0,""):e}).trim(),config:o}}function Ln(e){return(e=void 0===e?"":e).replace(/(<\/?a.*?>)/gi,"")}var qn,Pn=be(function(e){var u,f,p,d,n,g=function(u){var i=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,n=0,e={},T={manual:u.Prism&&u.Prism.manual,disableWorkerMessageHandler:u.Prism&&u.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof C?new C(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++n}),e.__id},clone:function i(e,o){var t,n;switch(o=o||{},T.util.type(e)){case"Object":if(n=T.util.objId(e),o[n])return o[n];for(var a in t={},o[n]=t,e)e.hasOwnProperty(a)&&(t[a]=i(e[a],o));return t;case"Array":return(n=T.util.objId(e),o[n])?o[n]:(t=[],o[n]=t,e.forEach(function(e,n){t[n]=i(e,o)}),t);default:return e}},getLanguage:function(e){for(;e;){var n=i.exec(e.className);if(n)return n[1].toLowerCase();e=e.parentElement}return"none"},setLanguage:function(e,n){e.className=e.className.replace(RegExp(i,"gi"),""),e.classList.add("language-"+n)},currentScript:function(){if("undefined"==typeof document)return null;if("currentScript"in document)return document.currentScript;try{throw new Error}catch(e){var n=(/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(e.stack)||[])[1];if(n){var i,o=document.getElementsByTagName("script");for(i in o)if(o[i].src==n)return o[i]}return null}},isActive:function(e,n,i){for(var o="no-"+n;e;){var t=e.classList;if(t.contains(n))return!0;if(t.contains(o))return!1;e=e.parentElement}return!!i}},languages:{plain:e,plaintext:e,text:e,txt:e,extend:function(e,n){var i,o=T.util.clone(T.languages[e]);for(i in n)o[i]=n[i];return o},insertBefore:function(i,e,n,o){var t,a=(o=o||T.languages)[i],r={};for(t in a)if(a.hasOwnProperty(t)){if(t==e)for(var c in n)n.hasOwnProperty(c)&&(r[c]=n[c]);n.hasOwnProperty(t)||(r[t]=a[t])}var u=o[i];return o[i]=r,T.languages.DFS(T.languages,function(e,n){n===u&&e!=i&&(this[e]=r)}),r},DFS:function e(n,i,o,t){t=t||{};var a,r,c,u=T.util.objId;for(a in n)n.hasOwnProperty(a)&&(i.call(n,a,n[a],o||a),r=n[a],"Object"!==(c=T.util.type(r))||t[u(r)]?"Array"!==c||t[u(r)]||(t[u(r)]=!0,e(r,i,a,t)):(t[u(r)]=!0,e(r,i,null,t)))}},plugins:{},highlightAll:function(e,n){T.highlightAllUnder(document,e,n)},highlightAllUnder:function(e,n,i){var o={callback:i,container:e,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};T.hooks.run("before-highlightall",o),o.elements=Array.prototype.slice.apply(o.container.querySelectorAll(o.selector)),T.hooks.run("before-all-elements-highlight",o);for(var t,a=0;t=o.elements[a++];)T.highlightElement(t,!0===n,o.callback)},highlightElement:function(e,n,i){var o=T.util.getLanguage(e),t=T.languages[o];T.util.setLanguage(e,o);var a=e.parentElement;a&&"pre"===a.nodeName.toLowerCase()&&T.util.setLanguage(a,o);var r={element:e,language:o,grammar:t,code:e.textContent};function c(e){r.highlightedCode=e,T.hooks.run("before-insert",r),r.element.innerHTML=r.highlightedCode,T.hooks.run("after-highlight",r),T.hooks.run("complete",r),i&&i.call(r.element)}if(T.hooks.run("before-sanity-check",r),(a=r.element.parentElement)&&"pre"===a.nodeName.toLowerCase()&&!a.hasAttribute("tabindex")&&a.setAttribute("tabindex","0"),!r.code)return T.hooks.run("complete",r),void(i&&i.call(r.element));T.hooks.run("before-highlight",r),r.grammar?n&&u.Worker?((n=new Worker(T.filename)).onmessage=function(e){c(e.data)},n.postMessage(JSON.stringify({language:r.language,code:r.code,immediateClose:!0}))):c(T.highlight(r.code,r.grammar,r.language)):c(T.util.encode(r.code))},highlight:function(e,n,i){i={code:e,grammar:n,language:i};if(T.hooks.run("before-tokenize",i),!i.grammar)throw new Error('The language "'+i.language+'" has no grammar.');return i.tokens=T.tokenize(i.code,i.grammar),T.hooks.run("after-tokenize",i),C.stringify(T.util.encode(i.tokens),i.language)},tokenize:function(e,n){var i=n.rest;if(i){for(var o in i)n[o]=i[o];delete n.rest}var t=new a;return j(t,t.head,e),function e(n,i,o,t,a,r){for(var c in o)if(o.hasOwnProperty(c)&&o[c]){var u=o[c];u=Array.isArray(u)?u:[u];for(var f=0;f<u.length;++f){if(r&&r.cause==c+","+f)return;var p,d=u[f],g=d.inside,s=!!d.lookbehind,l=!!d.greedy,v=d.alias;l&&!d.pattern.global&&(p=d.pattern.toString().match(/[imsuy]*$/)[0],d.pattern=RegExp(d.pattern.source,p+"g"));for(var h=d.pattern||d,_=t.next,m=a;_!==i.tail&&!(r&&m>=r.reach);m+=_.value.length,_=_.next){var b=_.value;if(i.length>n.length)return;if(!(b instanceof C)){var k,w=1;if(l){if(!(k=R(h,m,n,s))||k.index>=n.length)break;var y=k.index,x=k.index+k[0].length,S=m;for(S+=_.value.length;S<=y;)_=_.next,S+=_.value.length;if(S-=_.value.length,m=S,_.value instanceof C)continue;for(var A=_;A!==i.tail&&(S<x||"string"==typeof A.value);A=A.next)w++,S+=A.value.length;w--,b=n.slice(m,S),k.index-=m}else if(!(k=R(h,0,b,s)))continue;var y=k.index,$=k[0],z=b.slice(0,y),F=b.slice(y+$.length),E=m+b.length;r&&E>r.reach&&(r.reach=E);b=_.prev;z&&(b=j(i,b,z),m+=z.length),O(i,b,w);$=new C(c,g?T.tokenize($,g):$,v,$);_=j(i,b,$),F&&j(i,_,F),1<w&&(E={cause:c+","+f,reach:E},e(n,i,o,_.prev,m,E),r&&E.reach>r.reach&&(r.reach=E.reach))}}}}}(e,t,n,t.head,0),function(e){var n=[],i=e.head.next;for(;i!==e.tail;)n.push(i.value),i=i.next;return n}(t)},hooks:{all:{},add:function(e,n){var i=T.hooks.all;i[e]=i[e]||[],i[e].push(n)},run:function(e,n){var i=T.hooks.all[e];if(i&&i.length)for(var o,t=0;o=i[t++];)o(n)}},Token:C};function C(e,n,i,o){this.type=e,this.content=n,this.alias=i,this.length=0|(o||"").length}function R(e,n,i,o){e.lastIndex=n;i=e.exec(i);return i&&o&&i[1]&&(o=i[1].length,i.index+=o,i[0]=i[0].slice(o)),i}function a(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function j(e,n,i){var o=n.next,i={value:i,prev:n,next:o};return n.next=i,o.prev=i,e.length++,i}function O(e,n,i){for(var o=n.next,t=0;t<i&&o!==e.tail;t++)o=o.next;(n.next=o).prev=n,e.length-=t}if(u.Prism=T,C.stringify=function n(e,i){if("string"==typeof e)return e;if(Array.isArray(e)){var o="";return e.forEach(function(e){o+=n(e,i)}),o}var t={type:e.type,content:n(e.content,i),tag:"span",classes:["token",e.type],attributes:{},language:i},e=e.alias;e&&(Array.isArray(e)?Array.prototype.push.apply(t.classes,e):t.classes.push(e)),T.hooks.run("wrap",t);var a,r="";for(a in t.attributes)r+=" "+a+'="'+(t.attributes[a]||"").replace(/"/g,"&quot;")+'"';return"<"+t.tag+' class="'+t.classes.join(" ")+'"'+r+">"+t.content+"</"+t.tag+">"},!u.document)return u.addEventListener&&(T.disableWorkerMessageHandler||u.addEventListener("message",function(e){var n=JSON.parse(e.data),i=n.language,e=n.code,n=n.immediateClose;u.postMessage(T.highlight(e,T.languages[i],i)),n&&u.close()},!1)),T;var o=T.util.currentScript();function t(){T.manual||T.highlightAll()}return o&&(T.filename=o.src,o.hasAttribute("data-manual")&&(T.manual=!0)),T.manual||("loading"===(e=document.readyState)||"interactive"===e&&o&&o.defer?document.addEventListener("DOMContentLoaded",t):window.requestAnimationFrame?window.requestAnimationFrame(t):window.setTimeout(t,16)),T}("undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{});e.exports&&(e.exports=g),void 0!==me&&(me.Prism=g),g.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},g.languages.markup.tag.inside["attr-value"].inside.entity=g.languages.markup.entity,g.languages.markup.doctype.inside["internal-subset"].inside=g.languages.markup,g.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&amp;/,"&"))}),Object.defineProperty(g.languages.markup.tag,"addInlined",{value:function(e,n){var i={};i["language-"+n]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:g.languages[n]},i.cdata=/^<!\[CDATA\[|\]\]>$/i;i={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:i}};i["language-"+n]={pattern:/[\s\S]+/,inside:g.languages[n]};n={};n[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,function(){return e}),"i"),lookbehind:!0,greedy:!0,inside:i},g.languages.insertBefore("markup","cdata",n)}}),Object.defineProperty(g.languages.markup.tag,"addAttribute",{value:function(e,n){g.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[n,"language-"+n],inside:g.languages[n]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),g.languages.html=g.languages.markup,g.languages.mathml=g.languages.markup,g.languages.svg=g.languages.markup,g.languages.xml=g.languages.extend("markup",{}),g.languages.ssml=g.languages.xml,g.languages.atom=g.languages.xml,g.languages.rss=g.languages.xml,function(e){var n=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+n.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+n.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+n.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:n,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;e=e.languages.markup;e&&(e.tag.addInlined("style","css"),e.tag.addAttribute("style","css"))}(g),g.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},g.languages.javascript=g.languages.extend("clike",{"class-name":[g.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),g.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,g.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:g.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:g.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:g.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:g.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:g.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),g.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:g.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),g.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),g.languages.markup&&(g.languages.markup.tag.addInlined("script","javascript"),g.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),g.languages.js=g.languages.javascript,void 0!==g&&"undefined"!=typeof document&&(Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector),u={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"},d="pre[data-src]:not(["+(f="data-src-status")+'="loaded"]):not(['+f+'="'+(p="loading")+'"])',g.hooks.add("before-highlightall",function(e){e.selector+=", "+d}),g.hooks.add("before-sanity-check",function(e){var t,n,i,o,a,r,c=e.element;c.matches(d)&&(e.code="",c.setAttribute(f,p),(t=c.appendChild(document.createElement("CODE"))).textContent="Loading…",i=c.getAttribute("data-src"),"none"===(e=e.language)&&(n=(/\.(\w+)$/.exec(i)||[,"none"])[1],e=u[n]||n),g.util.setLanguage(t,e),g.util.setLanguage(c,e),(n=g.plugins.autoloader)&&n.loadLanguages(e),i=i,o=function(e){c.setAttribute(f,"loaded");var n,i,o=function(e){if(i=/^\s*(\d+)\s*(?:(,)\s*(?:(\d+)\s*)?)?$/.exec(e||"")){var n=Number(i[1]),e=i[2],i=i[3];return e?i?[n,Number(i)]:[n,void 0]:[n,n]}}(c.getAttribute("data-range"));o&&(n=e.split(/\r\n?|\n/g),i=o[0],o=null==o[1]?n.length:o[1],i<0&&(i+=n.length),i=Math.max(0,Math.min(i-1,n.length)),o<0&&(o+=n.length),o=Math.max(0,Math.min(o,n.length)),e=n.slice(i,o).join("\n"),c.hasAttribute("data-start")||c.setAttribute("data-start",String(i+1))),t.textContent=e,g.highlightElement(t)},a=function(e){c.setAttribute(f,"failed"),t.textContent=e},(r=new XMLHttpRequest).open("GET",i,!0),r.onreadystatechange=function(){4==r.readyState&&(r.status<400&&r.responseText?o(r.responseText):400<=r.status?a("✖ Error "+r.status+" while fetching file: "+r.statusText):a("✖ Error: File does not exist or is empty"))},r.send(null))}),n=!(g.plugins.fileHighlight={highlight:function(e){for(var n,i=(e||document).querySelectorAll(d),o=0;n=i[o++];)g.highlightElement(n)}}),g.fileHighlight=function(){n||(console.warn("Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead."),n=!0),g.plugins.fileHighlight.highlight.apply(this,arguments)})});function Mn(e,n){return"___"+e.toUpperCase()+n+"___"}qn=Prism,Object.defineProperties(qn.languages["markup-templating"]={},{buildPlaceholders:{value:function(o,t,e,a){var r;o.language===t&&(r=o.tokenStack=[],o.code=o.code.replace(e,function(e){if("function"==typeof a&&!a(e))return e;for(var n,i=r.length;-1!==o.code.indexOf(n=Mn(t,i));)++i;return r[i]=e,n}),o.grammar=qn.languages.markup)}},tokenizePlaceholders:{value:function(f,p){var d,g;f.language===p&&f.tokenStack&&(f.grammar=qn.languages[p],d=0,g=Object.keys(f.tokenStack),function e(n){for(var i=0;i<n.length&&!(d>=g.length);i++){var o,t,a,r,c,u=n[i];"string"==typeof u||u.content&&"string"==typeof u.content?(t=g[d],a=f.tokenStack[t],o="string"==typeof u?u:u.content,c=Mn(p,t),-1<(r=o.indexOf(c))&&(++d,t=o.substring(0,r),a=new qn.Token(p,qn.tokenize(a,f.grammar),"language-"+p,a),r=o.substring(r+c.length),c=[],t&&c.push.apply(c,e([t])),c.push(a),r&&c.push.apply(c,e([r])),"string"==typeof u?n.splice.apply(n,[i,1].concat(c)):u.content=c)):u.content&&e(u.content)}return n}(f.tokens))}}});function In(t,e){var a=this;this.config=t,this.router=e,this.cacheTree={},this.toc=[],this.cacheTOC={},this.linkTarget=t.externalLinkTarget||"_blank",this.linkRel="_blank"===this.linkTarget?t.externalLinkRel||"noopener":"",this.contentBase=e.getBasePath();var n=this._initRenderer();this.heading=n.heading;var r=o(e=t.markdown||{})?e(Sn,n):(Sn.setOptions(m(e,{renderer:m(n,e.renderer)})),Sn);this._marked=r,this.compile=function(i){var o=!0,e=c(function(e){o=!1;var n="";return i&&(n=f(i)?r(i):r.parser(i),n=t.noEmoji?n:jn(n,t.nativeEmoji),Cn.clear(),n)})(i),n=a.router.parse().file;return o?a.toc=a.cacheTOC[n]:a.cacheTOC[n]=[].concat(a.toc),e}}var Nn={},Hn={markdown:function(e){return{url:e}},mermaid:function(e){return{url:e}},iframe:function(e,n){return{html:'<iframe src="'+e+'" '+(n||"width=100% height=400")+"></iframe>"}},video:function(e,n){return{html:'<video src="'+e+'" '+(n||"controls")+">Not Support</video>"}},audio:function(e,n){return{html:'<audio src="'+e+'" '+(n||"controls")+">Not Support</audio>"}},code:function(e,n){var i=e.match(/\.(\w+)$/);return{url:e,lang:i="md"===(i=n||i&&i[1])?"markdown":i}}};In.prototype.compileEmbed=function(e,n){var i,o,t=On(n),a=t.str,t=t.config;if(n=a,t.include)return T(e)||(e=q(this.contentBase,R(this.router.getCurrentPath()),e)),t.type&&(o=Hn[t.type])?(i=o.call(this,e,n)).type=t.type:(o="code",/\.(md|markdown)/.test(e)?o="markdown":/\.mmd/.test(e)?o="mermaid":/\.html?/.test(e)?o="iframe":/\.(mp4|ogg)/.test(e)?o="video":/\.mp3/.test(e)&&(o="audio"),(i=Hn[o].call(this,e,n)).type=o),i.fragment=t.fragment,i},In.prototype._matchNotCompileLink=function(e){for(var n=this.config.noCompileLinks||[],i=0;i<n.length;i++){var o=n[i];if((Nn[o]||(Nn[o]=new RegExp("^"+o+"$"))).test(e))return e}},In.prototype._initRenderer=function(){var r,c,u,f,p,d,e=new Sn.Renderer,n=this.linkTarget,i=this.linkRel,a=this.router,o=this.contentBase,g=this,t={};return t.heading=e.heading=function(e,n){var i=On(e),o=i.str,t=i.config,e={level:n,title:Ln(o)};/<!-- {docsify-ignore} -->/g.test(o)&&(o=o.replace("\x3c!-- {docsify-ignore} --\x3e",""),e.title=Ln(o),e.ignoreSubHeading=!0),/{docsify-ignore}/g.test(o)&&(o=o.replace("{docsify-ignore}",""),e.title=Ln(o),e.ignoreSubHeading=!0),/<!-- {docsify-ignore-all} -->/g.test(o)&&(o=o.replace("\x3c!-- {docsify-ignore-all} --\x3e",""),e.title=Ln(o),e.ignoreAllSubs=!0),/{docsify-ignore-all}/g.test(o)&&(o=o.replace("{docsify-ignore-all}",""),e.title=Ln(o),e.ignoreAllSubs=!0);i=Cn(t.id||o),t=a.toURL(a.getCurrentPath(),{id:i});return e.slug=t,g.toc.push(e),"<h"+n+' id="'+i+'"><a href="'+t+'" data-id="'+i+'" class="anchor"><span>'+o+"</span></a></h"+n+">"},t.code={renderer:e}.renderer.code=function(e,n){var i=Pn.languages[n=void 0===n?"markup":n]||Pn.languages.markup;return'<pre v-pre data-lang="'+n+'"><code class="lang-'+n+'">'+Pn.highlight(e.replace(/@DOCSIFY_QM@/g,"`"),i,n)+"</code></pre>"},t.link=(i=(n={renderer:e,router:a,linkTarget:n,linkRel:i,compilerClass:g}).renderer,c=n.router,u=n.linkTarget,n.linkRel,f=n.compilerClass,i.link=function(e,n,i){var o=[],t=On(n=void 0===n?"":n),a=t.str,t=t.config;return u=t.target||u,r="_blank"===u?f.config.externalLinkRel||"noopener":"",n=a,T(e)||f._matchNotCompileLink(e)||t.ignore?(T(e)||"./"!==e.slice(0,2)||(e=document.URL.replace(/\/(?!.*\/).*/,"/").replace("#/./","")+e),o.push(0===e.indexOf("mailto:")?"":'target="'+u+'"'),o.push(0!==e.indexOf("mailto:")&&""!==r?' rel="'+r+'"':"")):(e===f.config.homepage&&(e="README"),e=c.toURL(e,null,c.getCurrentPath())),t.crossorgin&&"_self"===u&&"history"===f.config.routerMode&&-1===f.config.crossOriginLinks.indexOf(e)&&f.config.crossOriginLinks.push(e),t.disabled&&(o.push("disabled"),e="javascript:void(0)"),t.class&&o.push('class="'+t.class+'"'),t.id&&o.push('id="'+t.id+'"'),n&&o.push('title="'+n+'"'),'<a href="'+e+'" '+o.join(" ")+">"+i+"</a>"}),t.paragraph={renderer:e}.renderer.paragraph=function(e){e=/^!&gt;/.test(e)?$n("tip",e):/^\?&gt;/.test(e)?$n("warn",e):"<p>"+e+"</p>";return e},t.image=(o=(i={renderer:e,contentBase:o,router:a}).renderer,p=i.contentBase,d=i.router,o.image=function(e,n,i){var o=e,t=[],a=On(n),r=a.str,a=a.config;return n=r,a["no-zoom"]&&t.push("data-no-zoom"),n&&t.push('title="'+n+'"'),a.size&&(n=(r=a.size.split("x"))[0],(r=r[1])?t.push('width="'+n+'" height="'+r+'"'):t.push('width="'+n+'"')),a.class&&t.push('class="'+a.class+'"'),a.id&&t.push('id="'+a.id+'"'),T(e)||(o=q(p,R(d.getCurrentPath()),e)),0<t.length?'<img src="'+o+'" data-origin="'+e+'" alt="'+i+'" '+t.join(" ")+" />":'<img src="'+o+'" data-origin="'+e+'" alt="'+i+'"'+t+">"}),t.list={renderer:e}.renderer.list=function(e,n,i){n=n?"ol":"ul";return"<"+n+" "+[/<li class="task-list-item">/.test(e.split('class="task-list"')[0])?'class="task-list"':"",i&&1<i?'start="'+i+'"':""].join(" ").trim()+">"+e+"</"+n+">"},t.listitem={renderer:e}.renderer.listitem=function(e){return/^(<input.*type="checkbox"[^>]*>)/.test(e)?'<li class="task-list-item"><label>'+e+"</label></li>":"<li>"+e+"</li>"},e.origin=t,e},In.prototype.sidebar=function(e,n){var i=this.toc,o=this.router.getCurrentPath(),t="";if(e)t=this.compile(e);else{for(var a=0;a<i.length;a++)if(i[a].ignoreSubHeading){var r=i[a].level;i.splice(a,1);for(var c=a;c<i.length&&r<i[c].level;c++)i.splice(c,1)&&c--&&a++;a--}n=this.cacheTree[o]||zn(i,n),t=An(n,"<ul>{inner}</ul>");this.cacheTree[o]=n}return t},In.prototype.subSidebar=function(e){if(e){var n=this.router.getCurrentPath(),i=this.cacheTree,o=this.toc;o[0]&&o[0].ignoreAllSubs&&o.splice(0),o[0]&&1===o[0].level&&o.shift();for(var t=0;t<o.length;t++)o[t].ignoreSubHeading&&o.splice(t,1)&&t--;e=i[n]||zn(o,e);return i[n]=e,this.toc=[],An(e)}this.toc=[]},In.prototype.header=function(e,n){return this.heading(e,n)},In.prototype.article=function(e){return this.compile(e)},In.prototype.cover=function(e){var n=this.toc.slice(),e=this.compile(e);return this.toc=n.slice(),e};function Dn(e){var n=Zn(e);return 0===n?e:(n=new RegExp("^[ \\t]{"+n+"}","gm"),e.replace(n,""))}var Un,Zn=function(e){e=e.match(/^[ \t]*(?=\S)/gm);return e?e.reduce(function(e,n){return Math.min(e,n.length)},1/0):0},Bn={};function Vn(e,o){var a=e.compiler,t=e.raw;void 0===t&&(t="");var n=e.fetch,e=Bn[t];if(e){var i=e.slice();return i.links=e.links,o(i)}var i=a._marked,r=i.lexer(t),c=[],u=i.Lexer.rules.inline.link,f=r.links;r.forEach(function(e,t){"paragraph"===e.type&&(e.text=e.text.replace(new RegExp(u.source,"g"),function(e,n,i,o){o=a.compileEmbed(i,o);return o&&c.push({index:t,embed:o}),e}))});var p=[];!function(e,a){var n,i=e.embedTokens,r=e.compile,c=(e.fetch,0),u=1;if(!i.length)return a({});for(;n=i[c++];){var o=function(t){return function(e){var n,i,o;e&&("markdown"===t.embed.type?((i=t.embed.url.split("/")).pop(),i=i.join("/"),e=e.replace(/\[([^[\]]+)\]\(([^)]+)\)/g,function(e){var n=e.indexOf("(");return"(."===e.slice(n,n+2)?e.substring(0,n)+"("+window.location.protocol+"//"+window.location.host+i+"/"+e.substring(n+1,e.length-1)+")":e}),!0===(($docsify.frontMatter||{}).installed||!1)&&(e=$docsify.frontMatter.parseMarkdown(e)),n=r.lexer(e)):"code"===t.embed.type?(t.embed.fragment&&(o=t.embed.fragment,o=new RegExp("(?:###|\\/\\/\\/)\\s*\\["+o+"\\]([\\s\\S]*)(?:###|\\/\\/\\/)\\s*\\["+o+"\\]"),e=Dn((e.match(o)||[])[1]||"").trim()),n=r.lexer("```"+t.embed.lang+"\n"+e.replace(/`/g,"@DOCSIFY_QM@")+"\n```\n")):"mermaid"===t.embed.type?(n=[{type:"html",text:'<div class="mermaid">\n'+e+"\n</div>"}]).links={}:(n=[{type:"html",text:e}]).links={}),a({token:t,embedToken:n}),++u>=c&&a({})}}(n);n.embed.url?X(n.embed.url).then(o):o(n.embed.html)}}({compile:i,embedTokens:c,fetch:n},function(e){var n,i=e.embedToken,e=e.token;e?(n=e.index,p.forEach(function(e){n>e.start&&(n+=e.length)}),m(f,i.links),r=r.slice(0,n).concat(i,r.slice(n+1)),p.push({start:n,length:i.length-1})):(Bn[t]=r.concat(),r.links=Bn[t].links=f,o(r))})}function Yn(e,n,i){var o,t,a,r;return n="function"==typeof i?i(n):"string"==typeof i?(a=[],r=0,(o=i).replace(V,function(n,e,i){a.push(o.substring(r,i-1)),r=i+=n.length+1,a.push(t&&t[n]||function(e){return("00"+("string"==typeof Y[n]?e[Y[n]]():Y[n](e))).slice(-n.length)})}),r!==o.length&&a.push(o.substring(r)),function(e){for(var n="",i=0,o=e||new Date;i<a.length;i++)n+="string"==typeof a[i]?a[i]:a[i](o);return n}(new Date(n))):n,e.replace(/{docsify-updated}/g,n)}function Gn(e){function n(e){var n=Boolean(e.__vue__&&e.__vue__._isVue),e=Boolean(e._vnode&&e._vnode.__v_skip);return n||e}var i=this.config,o=b(".markdown-section"),t="Vue"in window&&window.Vue.version&&Number(window.Vue.version.charAt(0));if(e=e||"<h1>404 - Not found</h1>","Vue"in window)for(var a=0,r=k(".markdown-section > *").filter(n);a<r.length;a+=1){var c=r[a];2===t?c.__vue__.$destroy():3===t&&c.__vue_app__.unmount()}if(this._renderTo(o,e),i.loadSidebar||this._renderSidebar(),(i.executeScript||"Vue"in window&&!1!==i.executeScript)&&(!(e=k(".markdown-section>script").filter(function(e){return!/template/.test(e.type)})[0])||(e=e.innerText.trim())&&new Function(e)()),"Vue"in window){var u,f,p=[],d=Object.keys(i.vueComponents||{});2===t&&d.length&&d.forEach(function(e){window.Vue.options.components[e]||window.Vue.component(e,i.vueComponents[e])}),!Un&&i.vueGlobalOptions&&"function"==typeof i.vueGlobalOptions.data&&(Un=i.vueGlobalOptions.data()),p.push.apply(p,Object.keys(i.vueMounts||{}).map(function(e){return[b(o,e),i.vueMounts[e]]}).filter(function(e){var n=e[0];e[1];return n})),(i.vueGlobalOptions||d.length)&&(u=/{{2}[^{}]*}{2}/,f=/<[^>/]+\s([@:]|v-)[\w-:.[\]]+[=>\s]/,p.push.apply(p,k(".markdown-section > *").filter(function(i){return!p.some(function(e){var n=e[0];e[1];return n===i})}).filter(function(e){return e.tagName.toLowerCase()in(i.vueComponents||{})||e.querySelector(d.join(",")||null)||u.test(e.outerHTML)||f.test(e.outerHTML)}).map(function(e){var n=m({},i.vueGlobalOptions||{});return Un&&(n.data=function(){return Un}),[e,n]})));for(var g=0,s=p;g<s.length;g+=1){var l,v=s[g],h=v[0],_=v[1],v="data-isvue";h.matches("pre, script")||n(h)||h.querySelector("["+v+"]")||(h.setAttribute(v,""),2===t?(_.el=void 0,new window.Vue(_).$mount(h)):3===t&&(l=window.Vue.createApp(_),d.forEach(function(e){var n=i.vueComponents[e];l.component(e,n)}),l.mount(h)))}}}function Wn(n,i,o,t,a,e){n=e?n:n.replace(/\/$/,""),(n=R(n))&&X(a.router.getFile(n+o)+i,!1,a.config.requestHeaders).then(t,function(e){return Wn(n,i,o,t,a)})}function Xn(){var n=function(){return null};return[function(e){n(e)},function(e){n=e}]}Me=Object.freeze({__proto__:null,cached:c,hyphenate:a,hasOwn:u,merge:m,isPrimitive:f,noop:d,isFn:o,isExternal:g,inBrowser:!0,isMobile:s,supportsPushState:t,parseQuery:F,stringifyQuery:E,isAbsolutePath:T,removeParams:C,getParentPath:R,cleanPath:j,resolvePath:O,getPath:q,replaceSlug:P});var Qn,Jn=function(e){function n(){e.call(this),this.config=ue(this),this.initLifecycle(),this.initPlugin(),this.callHook("init"),this.initRouter(),this.initRender(),this.initEvent(),this.initFetch(),this.callHook("mounted")}return e&&(n.__proto__=e),((n.prototype=Object.create(e&&e.prototype)).constructor=n).prototype.initPlugin=function(){var n=this;[].concat(this.config.plugins).forEach(function(e){try{o(e)&&e(n._lifecycle,n)}catch(e){if(!n.config.catchPluginErrors)throw e;console.error("Docsify plugin error",e)}})},n}((we=Object,function(e){function n(){e.apply(this,arguments)}return e&&(n.__proto__=e),((n.prototype=Object.create(e&&e.prototype)).constructor=n).prototype._loadSideAndNav=function(e,n,i,o){var t=this;return function(){if(!i)return o();Wn(e,n,i,function(e){t._renderSidebar(e),o()},t,!0)}},n.prototype._fetch=function(i){var o=this;void 0===i&&(i=d);var t,e,n,a,r,c,u,f=this.route.query,p=this.route.path;g(p)?(history.replaceState(null,"","#"),this.router.normalize()):(t=E(f,["id"]),f=(e=this.config).loadNavbar,n=e.requestHeaders,a=e.loadSidebar,r=this.router.getFile(p),this.isRemoteUrl=g(r),this.isHTML=/\.html$/g.test(r),c=function(e,n){o._renderMain(e,n,o._loadSideAndNav(p,t,a,i))},u=function(e){o._fetchFallbackPage(p,t,i)||o._fetch404(r,t,i)},this.isRemoteUrl?Kn(r+t,0,n).then(c,u):this.matchVirtualRoute(p).then(function(e){"string"==typeof e?c(e):Kn(r+t,0,n).then(c,u)}),f&&Wn(p,t,f,function(e){return o._renderNav(e)},this,!0))},n.prototype._fetchCover=function(){var n=this,e=this.config,i=e.coverpage,o=e.requestHeaders,t=this.route.query,a=R(this.route.path);if(i){var r=null,e=this.route.path;"string"==typeof i?"/"===e&&(r=i):r=Array.isArray(i)?-1<i.indexOf(e)&&"_coverpage":!0===(e=i[e])?"_coverpage":e;var c=Boolean(r)&&this.config.onlyCover;return r?(r=this.router.getFile(a+r),this.coverIsHTML=/\.html$/g.test(r),X(r+E(t,["id"]),!1,o).then(function(e){return n._renderCover(e,c)})):this._renderCover(null,c),c}},n.prototype.$fetch=function(e,n){var i=this;void 0===e&&(e=d),void 0===n&&(n=this.$resetEvents.bind(this));function o(){i.callHook("doneEach"),e()}this._fetchCover()?o():this._fetch(function(){n(),o()})},n.prototype._fetchFallbackPage=function(i,o,t){var a=this;void 0===t&&(t=d);var e=this.config,n=e.requestHeaders,r=e.fallbackLanguages,c=e.loadSidebar;if(!r)return!1;e=i.split("/")[1];if(-1===r.indexOf(e))return!1;e=this.router.getFile(i.replace(new RegExp("^/"+e),""));return Kn(e+o,0,n).then(function(e,n){return a._renderMain(e,n,a._loadSideAndNav(i,o,c,t))},function(){return a._fetch404(i,o,t)}),!0},n.prototype._fetch404=function(e,n,i){var o=this,t=this.config,a=t.loadSidebar,r=t.requestHeaders,t=t.notFoundPage,c=this._loadSideAndNav(e,n,a,i=void 0===i?d:i);if(t){e=function(n,e){var i,o,t=e.notFoundPage,a="_404"+(e.ext||".md");switch(typeof t){case"boolean":o=a;break;case"string":o=t;break;case"object":o=(i=Object.keys(t).sort(function(e,n){return n.length-e.length}).filter(function(e){return n.match(new RegExp("^"+e))})[0])&&t[i]||a}return o}(e,this.config);return Kn(this.router.getFile(e),0,r).then(function(e,n){return o._renderMain(e,n,c)},function(){return o._renderMain(null,{},c)}),!0}return this._renderMain(null,{},c),!1},n.prototype.initFetch=function(){var e,n=this,i=this.config.loadSidebar;this.rendered?(e=ee(this.router,".sidebar-nav",!0,!0),i&&e&&(e.parentNode.innerHTML+=window.__SUB_SIDEBAR__),this._bindEventOnRendered(e),this.$resetEvents(),this.callHook("doneEach"),this.callHook("ready")):this.$fetch(function(e){return n.callHook("ready")})},n}(function(e){function n(){e.apply(this,arguments)}return e&&(n.__proto__=e),((n.prototype=Object.create(e&&e.prototype)).constructor=n).prototype.$resetEvents=function(e){var n=this,i=this.config.auto2top;"history"!==e&&(n.route.query.id&&he(n.route.path,n.route.query.id),"navigate"===e&&i&&(i=i,_e.scrollTop=!0===(i=void 0===i?0:i)?0:Number(i))),this.config.loadNavbar&&ee(this.router,"nav")},n.prototype.initEvent=function(){function n(e){return h.classList.toggle("close")}var e;e="button.sidebar-toggle",this.router,null!=(e=l(e))&&(p(e,"click",function(e){e.stopPropagation(),n()}),s&&p(h,"click",function(e){return h.classList.contains("close")&&n()})),e=".sidebar",this.router,null!=(e=l(e))&&p(e,"click",function(e){e=e.target;"A"===e.nodeName&&e.nextSibling&&e.nextSibling.classList&&e.nextSibling.classList.contains("app-sub-sidebar")&&S(e.parentNode,"collapse")}),this.config.coverpage?s||p("scroll",K):h.classList.add("sticky")},n}(function(e){function n(){e.apply(this,arguments)}return e&&(n.__proto__=e),((n.prototype=Object.create(e&&e.prototype)).constructor=n).prototype._renderTo=function(e,n,i){e=l(e);e&&(e[i?"outerHTML":"innerHTML"]=n)},n.prototype._renderSidebar=function(e){var n=this.config,i=n.maxLevel,o=n.subMaxLevel,t=n.loadSidebar;if(n.hideSidebar)return[document.querySelector("aside.sidebar"),document.querySelector("button.sidebar-toggle")].filter(function(e){return!!e}).forEach(function(e){return e.parentNode.removeChild(e)}),document.querySelector("section.content").style.right="unset",document.querySelector("section.content").style.left="unset",document.querySelector("section.content").style.position="relative",document.querySelector("section.content").style.width="100%",null;this._renderTo(".sidebar-nav",this.compiler.sidebar(e,i));i=ee(this.router,".sidebar-nav",!0,!0);t&&i?i.parentNode.innerHTML+=this.compiler.subSidebar(o)||"":this.compiler.subSidebar(),this._bindEventOnRendered(i)},n.prototype._bindEventOnRendered=function(e){var n,i=this.config.autoHeader;!function(e){var n=b(".cover.show");se=n?n.offsetHeight:0;for(var i,n=l(".sidebar"),o=[],t=0,a=(o=null!=n?k(n,"li"):o).length;t<a;t+=1){var r,c,u=o[t],f=u.querySelector("a");f&&("/"!==(r=f.getAttribute("href"))&&(f=(c=e.parse(r)).query.id,c=c.path,f&&(r=ve(c,f))),r&&(fe[decodeURIComponent(r)]=u))}s||(i=C(e.getCurrentPath()),x("scroll",function(){return le(i)}),p("scroll",function(){return le(i)}),p(n,"mouseover",function(){pe=!0}),p(n,"mouseleave",function(){pe=!1}))}(this.router),i&&e&&((i=(n=l("#main")).children[0])&&"H1"!==i.tagName&&y(n,w("div",this.compiler.header(e.innerText,1)).children[0]))},n.prototype._renderNav=function(e){e&&this._renderTo("nav",this.compiler.compile(e)),this.config.loadNavbar&&ee(this.router,"nav")},n.prototype._renderMain=function(o,t,a){var r=this;if(void 0===t&&(t={}),!o)return Gn.call(this,o);this.callHook("beforeEach",o,function(e){function n(){t.updatedAt&&(i=Yn(i,t.updatedAt,r.config.formatUpdated)),r.callHook("afterEach",i,function(e){Gn.call(r,e),a()})}var i;r.isHTML?(i=r.result=o,n()):Vn({compiler:r.compiler,raw:e},function(e){i=r.compiler.compile(e),n()})})},n.prototype._renderCover=function(e,n){var i,o=l(".cover");S(l("main"),n?"add":"remove","hidden"),e?(S(o,"add","show"),(n=(i=this.coverIsHTML?e:this.compiler.cover(e)).trim().match('<p><img.*?data-origin="(.*?)"[^a]+alt="(.*?)">([^<]*?)</p>$'))&&("color"===n[2]?o.style.background=n[1]+(n[3]||""):(e=n[1],S(o,"add","has-mask"),T(n[1])||(e=q(this.router.getBasePath(),n[1])),o.style.backgroundImage="url("+e+")",o.style.backgroundSize="cover",o.style.backgroundPosition="center center"),i=i.replace(n[0],"")),this._renderTo(".cover-main",i),K()):S(o,"remove","show")},n.prototype._updateRender=function(){var e,n,i,o;e=this,n=l(".app-name-link"),i=e.config.nameLink,o=e.route.path,n&&(f(e.config.nameLink)?n.setAttribute("href",i):"object"==typeof i&&(e=Object.keys(i).filter(function(e){return-1<o.indexOf(e)})[0],n.setAttribute("href",i[e])))},n.prototype.initRender=function(){var e=this.config;this.compiler=new In(e,this.router),window.__current_docsify_compiler__=this.compiler;var n,i,o,t,a,r=e.el||"#app",c=b("nav")||w("nav"),u=b(r),f="",p=h;u?(e.repo&&(f+=(t=e.repo,r=e.cornerExternalLinkTarget,t?'<a href="'+(t=(t=!/\/\//.test(t)?"https://github.com/"+t:t).replace(/^git\+/,""))+'" target="'+(r=r||"_blank")+'" class="github-corner" aria-label="View source on Github"><svg viewBox="0 0 250 250" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a>':"")),e.coverpage&&(f+=(o=", 100%, 85%",'<section class="cover show" style="background: '+("linear-gradient(to left bottom, hsl("+Math.floor(255*Math.random())+o+") 0%,hsl("+Math.floor(255*Math.random())+o+") 100%)")+'"><div class="mask"></div><div class="cover-main">\x3c!--cover--\x3e</div></section>')),e.logo&&(o=/^data:image/.test(e.logo),n=/(?:http[s]?:)?\/\//.test(e.logo),i=/^\./.test(e.logo),o||n||i||(e.logo=q(this.router.getBasePath(),e.logo))),f+=(i=(n=e).name||"","<main>"+('<button class="sidebar-toggle" aria-label="Menu"><div class="sidebar-toggle-button"><span></span><span></span><span></span></div></button><aside class="sidebar">'+(n.name?'<h1 class="app-name"><a class="app-name-link" data-nosearch>'+(n.logo?'<img alt="'+i+'" src='+n.logo+">":i)+"</a></h1>":"")+'<div class="sidebar-nav">\x3c!--sidebar--\x3e</div></aside>')+'<section class="content"><article class="markdown-section" id="main">\x3c!--main--\x3e</article></section></main>'),this._renderTo(u,f,!0)):this.rendered=!0,e.mergeNavbar&&s?p=b(".sidebar"):(c.classList.add("app-nav"),e.repo||c.classList.add("no-badge")),e.loadNavbar&&y(p,c),e.themeColor&&(v.head.appendChild(w("div","<style>:root{--theme-color: "+e.themeColor+";}</style>").firstElementChild),a=e.themeColor,window.CSS&&window.CSS.supports&&window.CSS.supports("(--v:red)")||(e=k("style:not(.inserted),link"),[].forEach.call(e,function(e){"STYLE"===e.nodeName?Q(e,a):"LINK"===e.nodeName&&(e=e.getAttribute("href"),/\.css$/.test(e)&&X(e).then(function(e){e=w("style",e);_.appendChild(e),Q(e,a)}))}))),this._updateRender(),S(h,"ready")},n}(function(e){function n(){e.apply(this,arguments)}return e&&(n.__proto__=e),((n.prototype=Object.create(e&&e.prototype)).constructor=n).prototype.routes=function(){return this.config.routes||{}},n.prototype.matchVirtualRoute=function(t){var a=this.routes(),r=Object.keys(a),c=function(){return null};function u(){var e=r.shift();if(!e)return c(null);var n=A(o=(i="^",0===(o=e).indexOf(i)?o:"^"+o),"$")?o:o+"$",i=t.match(n);if(!i)return u();var o=a[e];if("string"==typeof o)return c(o);if("function"!=typeof o)return u();n=o,e=Xn(),o=e[0];return(0,e[1])(function(e){return"string"==typeof e?c(e):!1===e?c(null):u()}),n.length<=2?o(n(t,i)):n(t,i,o)}return{then:function(e){c=e,u()}}},n}(function(i){function e(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];i.apply(this,e),this.route={}}return i&&(e.__proto__=i),((e.prototype=Object.create(i&&i.prototype)).constructor=e).prototype.updateRender=function(){this.router.normalize(),this.route=this.router.parse(),h.setAttribute("data-page",this.route.file)},e.prototype.initRouter=function(){var n=this,e=this.config,e=new("history"===(e.routerMode||"hash")&&t?D:H)(e);this.router=e,this.updateRender(),U=this.route,e.onchange(function(e){n.updateRender(),n._updateRender(),U.path!==n.route.path?(n.$fetch(d,n.$resetEvents.bind(n,e.source)),U=n.route):n.$resetEvents(e.source)})},e}(function(e){function n(){e.apply(this,arguments)}return e&&(n.__proto__=e),((n.prototype=Object.create(e&&e.prototype)).constructor=n).prototype.initLifecycle=function(){var i=this;this._hooks={},this._lifecycle={},["init","mounted","beforeEach","afterEach","doneEach","ready"].forEach(function(e){var n=i._hooks[e]=[];i._lifecycle[e]=function(e){return n.push(e)}})},n.prototype.callHook=function(e,t,a){void 0===a&&(a=d);var r=this._hooks[e],c=this.config.catchPluginErrors,u=function(n){var e=r[n];if(n>=r.length)a(t);else if("function"==typeof e){var i="Docsify plugin error";if(2===e.length)try{e(t,function(e){t=e,u(n+1)})}catch(e){if(!c)throw e;console.error(i,e),u(n+1)}else try{var o=e(t);t=void 0===o?t:o,u(n+1)}catch(e){if(!c)throw e;console.error(i,e),u(n+1)}}else u(n+1)};u(0)},n}(we))))))));function Kn(e,n,i){return Qn&&Qn.abort&&Qn.abort(),Qn=X(e,!0,i)}window.Docsify={util:Me,dom:n,get:X,slugify:Cn,version:"4.13.0"},window.DocsifyCompiler=In,window.marked=Sn,window.Prism=Pn,e(function(e){return new Jn})}();
doc/lib/js/search.min.js 0 → 100644
  1 +!function(){function u(e){return e.replace(/<!-- {docsify-ignore} -->/,"").replace(/{docsify-ignore}/,"").replace(/<!-- {docsify-ignore-all} -->/,"").replace(/{docsify-ignore-all}/,"").trim()}var f={},m={EXPIRE_KEY:"docsify.search.expires",INDEX_KEY:"docsify.search.index"};function g(e){var n={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};return String(e).replace(/[&<>"']/g,function(e){return n[e]})}function y(e){return e.text||"table"!==e.type||(e.cells.unshift(e.header),e.text=e.cells.map(function(e){return e.join(" | ")}).join(" |\n ")),e.text}function v(e){return e.text||"list"!==e.type||(e.text=e.raw),e.text}function b(o,e,s,c){void 0===e&&(e="");var d,e=window.marked.lexer(e),l=window.Docsify.slugify,p={},h="";return e.forEach(function(e,n){var t,a,i,r;"heading"===e.type&&e.depth<=c?(t=(a=(i=e.text,r={},{str:i=(i=void 0===i?"":i)&&i.replace(/^('|")/,"").replace(/('|")$/,"").replace(/(?:^|\s):([\w-]+:?)=?([\w-%]+)?/g,function(e,n,t){return-1===n.indexOf(":")?(r[n]=t&&t.replace(/&quot;/g,"")||!0,""):e}).trim(),config:r})).str,i=a.config,a=u(e.text),d=i.id?s.toURL(o,{id:l(i.id)}):s.toURL(o,{id:l(g(a))}),t&&(h=u(t)),p[d]={slug:d,title:h,body:""}):(0===n&&(d=s.toURL(o),p[d]={slug:d,title:"/"!==o?o.slice(1):"Home Page",body:e.text||""}),d&&(p[d]?p[d].body?(e.text=y(e),e.text=v(e),p[d].body+="\n"+(e.text||"")):(e.text=y(e),e.text=v(e),p[d].body=p[d].body?p[d].body+e.text:e.text):p[d]={slug:d,title:"",body:""}))}),l.clear(),p}function p(e){return e&&e.normalize?e.normalize("NFD").replace(/[\u0300-\u036f]/g,""):e}function o(e){var n=[],t=[];Object.keys(f).forEach(function(n){t=t.concat(Object.keys(f[n]).map(function(e){return f[n][e]}))});var a=(e=e.trim()).split(/[\s\-,\\/]+/);1!==a.length&&(a=[].concat(e,a));for(var i=0;i<t.length;i++)!function(e){var e=t[e],r=0,o="",s="",c="",d=e.title&&e.title.trim(),l=e.body&&e.body.trim(),e=e.slug||"";d&&(a.forEach(function(e){var n,t,a=new RegExp(g(p(e)).replace(/[|\\{}()[\]^$+*?.]/g,"\\$&"),"gi"),i=-1;s=d&&g(p(d)),c=l&&g(p(l)),t=d?s.search(a):-1,i=l?c.search(a):-1,(0<=t||0<=i)&&(r+=0<=t?3:0<=i?2:0,t=(t=n=0)==(n=(i=i<0?0:i)<11?0:i-10)?70:i+e.length+60,l&&t>l.length&&(t=l.length),a=c&&"..."+c.substring(n,t).replace(a,function(e){return'<em class="search-keyword">'+e+"</em>"})+"...",o+=a)}),0<r&&(e={title:s,content:l?o:"",url:e,score:r},n.push(e)))}(i);return n.sort(function(e,n){return n.score-e.score})}function r(a,i){var t,r,n,e,o="auto"===a.paths,s=o?(t=i.router,r=[],Docsify.dom.findAll(".sidebar-nav a:not(.section-link):not([data-nosearch])").forEach(function(e){var n=e.href,e=e.getAttribute("href"),n=t.parse(n).path;n&&-1===r.indexOf(n)&&!Docsify.util.isAbsolutePath(e)&&r.push(n)}),r):a.paths,c="";s.length&&o&&a.pathNamespaces?(n=s[0],Array.isArray(a.pathNamespaces)?c=a.pathNamespaces.filter(function(e){return n.slice(0,e.length)===e})[0]||c:a.pathNamespaces instanceof RegExp&&((d=n.match(a.pathNamespaces))&&(c=d[0])),e=-1===s.indexOf(c+"/"),d=-1===s.indexOf(c+"/README"),e&&d&&s.unshift(c+"/")):-1===s.indexOf("/")&&-1===s.indexOf("/README")&&s.unshift("/");var d,l=((d=a.namespace)?m.EXPIRE_KEY+"/"+d:m.EXPIRE_KEY)+c,p=((d=a.namespace)?m.INDEX_KEY+"/"+d:m.INDEX_KEY)+c,c=localStorage.getItem(l)<Date.now();if(f=JSON.parse(localStorage.getItem(p)),c)f={};else if(!o)return;var h=s.length,u=0;s.forEach(function(t){return f[t]?u++:void Docsify.get(i.router.getFile(t),!1,i.config.requestHeaders).then(function(e){var n;f[t]=b(t,e,i.router,a.depth),h===++u&&(n=a.maxAge,e=p,localStorage.setItem(l,Date.now()+n),localStorage.setItem(e,JSON.stringify(f)))})})}var s,c="";function d(e){var n=Docsify.dom.find("div.search"),t=Docsify.dom.find(n,".results-panel"),a=Docsify.dom.find(n,".clear-button"),i=Docsify.dom.find(".sidebar-nav"),n=Docsify.dom.find(".app-name");if(!e)return t.classList.remove("show"),a.classList.remove("show"),t.innerHTML="",void(s.hideOtherSidebarContent&&(i&&i.classList.remove("hide"),n&&n.classList.remove("hide")));var e=o(e),r="";e.forEach(function(e){r+='<div class="matching-post">\n<a href="'+e.url+'">\n<h2>'+e.title+"</h2>\n<p>"+e.content+"</p>\n</a>\n</div>"}),t.classList.add("show"),a.classList.add("show"),t.innerHTML=r||'<p class="empty">'+c+"</p>",s.hideOtherSidebarContent&&(i&&i.classList.add("hide"),n&&n.classList.add("hide"))}function l(e){s=e}function h(e,n){var t,a,i=n.router.parse().query.s;l(e),Docsify.dom.style("\n.sidebar {\n padding-top: 0;\n}\n\n.search {\n margin-bottom: 20px;\n padding: 6px;\n border-bottom: 1px solid #eee;\n}\n\n.search .input-wrap {\n display: flex;\n align-items: center;\n}\n\n.search .results-panel {\n display: none;\n}\n\n.search .results-panel.show {\n display: block;\n}\n\n.search input {\n outline: none;\n border: none;\n width: 100%;\n padding: 0.6em 7px;\n font-size: inherit;\n border: 1px solid transparent;\n}\n\n.search input:focus {\n box-shadow: 0 0 5px var(--theme-color, #42b983);\n border: 1px solid var(--theme-color, #42b983);\n}\n\n.search input::-webkit-search-decoration,\n.search input::-webkit-search-cancel-button,\n.search input {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n\n.search input::-ms-clear {\n display: none;\n height: 0;\n width: 0;\n}\n\n.search .clear-button {\n cursor: pointer;\n width: 36px;\n text-align: right;\n display: none;\n}\n\n.search .clear-button.show {\n display: block;\n}\n\n.search .clear-button svg {\n transform: scale(.5);\n}\n\n.search h2 {\n font-size: 17px;\n margin: 10px 0;\n}\n\n.search a {\n text-decoration: none;\n color: inherit;\n}\n\n.search .matching-post {\n border-bottom: 1px solid #eee;\n}\n\n.search .matching-post:last-child {\n border-bottom: 0;\n}\n\n.search p {\n font-size: 14px;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n.search p.empty {\n text-align: center;\n}\n\n.app-name.hide, .sidebar-nav.hide {\n display: none;\n}"),function(e){void 0===e&&(e="");var n=Docsify.dom.create("div",'<div class="input-wrap">\n <input type="search" value="'+e+'" aria-label="Search text" />\n <div class="clear-button">\n <svg width="26" height="24">\n <circle cx="12" cy="12" r="11" fill="#ccc" />\n <path stroke="white" stroke-width="2" d="M8.25,8.25,15.75,15.75" />\n <path stroke="white" stroke-width="2"d="M8.25,15.75,15.75,8.25" />\n </svg>\n </div>\n </div>\n <div class="results-panel"></div>\n </div>'),e=Docsify.dom.find("aside");Docsify.dom.toggleClass(n,"search"),Docsify.dom.before(e,n)}(i),n=Docsify.dom.find("div.search"),a=Docsify.dom.find(n,"input"),e=Docsify.dom.find(n,".input-wrap"),Docsify.dom.on(n,"click",function(e){return-1===["A","H2","P","EM"].indexOf(e.target.tagName)&&e.stopPropagation()}),Docsify.dom.on(a,"input",function(n){clearTimeout(t),t=setTimeout(function(e){return d(n.target.value.trim())},100)}),Docsify.dom.on(e,"click",function(e){"INPUT"!==e.target.tagName&&(a.value="",d())}),i&&setTimeout(function(e){return d(i)},500)}function x(e,n){var t,a,i,r,o;l(e),t=e.placeholder,a=n.route.path,(r=Docsify.dom.getNode('.search input[type="search"]'))&&("string"==typeof t?r.placeholder=t:(i=Object.keys(t).filter(function(e){return-1<a.indexOf(e)})[0],r.placeholder=t[i])),e=e.noData,o=n.route.path,c="string"==typeof e?e:e[Object.keys(e).filter(function(e){return-1<o.indexOf(e)})[0]]}var w={placeholder:"Type to search",noData:"No Results!",paths:"auto",depth:2,maxAge:864e5,hideOtherSidebarContent:!1,namespace:void 0,pathNamespaces:void 0};$docsify.plugins=[].concat(function(e,n){var t=Docsify.util,a=n.config.search||w;Array.isArray(a)?w.paths=a:"object"==typeof a&&(w.paths=Array.isArray(a.paths)?a.paths:"auto",w.maxAge=(t.isPrimitive(a.maxAge)?a:w).maxAge,w.placeholder=a.placeholder||w.placeholder,w.noData=a.noData||w.noData,w.depth=a.depth||w.depth,w.hideOtherSidebarContent=a.hideOtherSidebarContent||w.hideOtherSidebarContent,w.namespace=a.namespace||w.namespace,w.pathNamespaces=a.pathNamespaces||w.pathNamespaces);var i="auto"===w.paths;e.mounted(function(e){h(w,n),i||r(w,n)}),e.doneEach(function(e){x(w,n),i&&r(w,n)})},$docsify.plugins)}();
doc/lib/js/zoom-image.min.js 0 → 100644
  1 +!function(){function t(e){return"IMG"===e.tagName}function d(e){function t(){for(var e=arguments,t=arguments.length,o=Array(t),n=0;n<t;n++)o[n]=e[n];var i=o.reduce(function(e,t){return[].concat(e,z(t))},[]);return i.filter(function(e){return-1===m.indexOf(e)}).forEach(function(e){m.push(e),e.classList.add("medium-zoom-image")}),r.forEach(function(e){var t=e.type,o=e.listener,n=e.options;i.forEach(function(e){e.addEventListener(t,o,n)})}),f}function o(){var e=(0<arguments.length&&void 0!==arguments[0]?arguments[0]:{}).target;return s.original?a():i({target:e})}var n=window.Promise||function(e){function t(){}e(t,t)},i=function(){function r(){var e={width:document.documentElement.clientWidth,height:document.documentElement.clientHeight,left:0,top:0,right:0,bottom:0},t=void 0,o=void 0;u.container&&(u.container instanceof Object?(t=(e=g({},e,u.container)).width-e.left-e.right-2*u.margin,o=e.height-e.top-e.bottom-2*u.margin):(r=(i=(h(u.container)?u.container:document.querySelector(u.container)).getBoundingClientRect()).width,m=i.height,d=i.left,a=i.top,e=g({},e,{width:r,height:m,left:d,top:a})));var t=t||e.width-2*u.margin,o=o||e.height-2*u.margin,n=s.zoomedHd||s.original,i=!v(n)&&n.naturalWidth||t,r=!v(n)&&n.naturalHeight||o,d=(m=n.getBoundingClientRect()).top,a=m.left,n=m.width,m=m.height,i=Math.min(i,t)/n,r=Math.min(r,o)/m,r="scale("+(r=Math.min(i,r))+") translate3d("+((t-n)/2-a+u.margin+e.left)/r+"px, "+((o-m)/2-d+u.margin+e.top)/r+"px, 0)";s.zoomed.style.transform=r,s.zoomedHd&&(s.zoomedHd.style.transform=r)}var d=(0<arguments.length&&void 0!==arguments[0]?arguments[0]:{}).target;return new n(function(e){if(d&&-1===m.indexOf(d))e(f);else{function t(){c=!1,s.zoomed.removeEventListener("transitionend",t),s.original.dispatchEvent(E("medium-zoom:opened",{detail:{zoom:f}})),e(f)}var o,n;if(s.zoomed)e(f);else{if(d)s.original=d;else{if(!(0<m.length))return void e(f);var i=m;s.original=i[0]}s.original.dispatchEvent(E("medium-zoom:open",{detail:{zoom:f}})),l=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,c=!0,s.zoomed=b(s.original),document.body.appendChild(p),u.template&&(i=h(u.template)?u.template:document.querySelector(u.template),s.template=document.createElement("div"),s.template.appendChild(i.content.cloneNode(!0)),document.body.appendChild(s.template)),document.body.appendChild(s.zoomed),window.requestAnimationFrame(function(){document.body.classList.add("medium-zoom--opened")}),s.original.classList.add("medium-zoom-image--hidden"),s.zoomed.classList.add("medium-zoom-image--opened"),s.zoomed.addEventListener("click",a),s.zoomed.addEventListener("transitionend",t),s.original.getAttribute("data-zoom-src")?(s.zoomedHd=s.zoomed.cloneNode(),s.zoomedHd.removeAttribute("srcset"),s.zoomedHd.removeAttribute("sizes"),s.zoomedHd.src=s.zoomed.getAttribute("data-zoom-src"),s.zoomedHd.onerror=function(){clearInterval(o),console.warn("Unable to reach the zoom image target "+s.zoomedHd.src),s.zoomedHd=null,r()},o=setInterval(function(){s.zoomedHd.complete&&(clearInterval(o),s.zoomedHd.classList.add("medium-zoom-image--opened"),s.zoomedHd.addEventListener("click",a),document.body.appendChild(s.zoomedHd),r())},10)):s.original.hasAttribute("srcset")?(s.zoomedHd=s.zoomed.cloneNode(),s.zoomedHd.removeAttribute("sizes"),s.zoomedHd.removeAttribute("loading"),n=s.zoomedHd.addEventListener("load",function(){s.zoomedHd.removeEventListener("load",n),s.zoomedHd.classList.add("medium-zoom-image--opened"),s.zoomedHd.addEventListener("click",a),document.body.appendChild(s.zoomedHd),r()})):r()}}})},a=function(){return new n(function(t){var e;!c&&s.original?(e=function e(){s.original.classList.remove("medium-zoom-image--hidden"),document.body.removeChild(s.zoomed),s.zoomedHd&&document.body.removeChild(s.zoomedHd),document.body.removeChild(p),s.zoomed.classList.remove("medium-zoom-image--opened"),s.template&&document.body.removeChild(s.template),c=!1,s.zoomed.removeEventListener("transitionend",e),s.original.dispatchEvent(E("medium-zoom:closed",{detail:{zoom:f}})),s.original=null,s.zoomed=null,s.zoomedHd=null,s.template=null,t(f)},c=!0,document.body.classList.remove("medium-zoom--opened"),s.zoomed.style.transform="",s.zoomedHd&&(s.zoomedHd.style.transform=""),s.template&&(s.template.style.transition="opacity 150ms",s.template.style.opacity=0),s.original.dispatchEvent(E("medium-zoom:close",{detail:{zoom:f}})),s.zoomed.addEventListener("transitionend",e)):t(f)})},m=[],r=[],c=!1,l=0,u=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},s={original:null,zoomed:null,zoomedHd:null,template:null};"[object Object]"===Object.prototype.toString.call(e)?u=e:!e&&"string"!=typeof e||t(e);var u=g({margin:0,background:"#fff",scrollOffset:40,container:null,template:null},u),p=y(u.background);document.addEventListener("click",function(e){e=e.target;e!==p?-1!==m.indexOf(e)&&o({target:e}):a()}),document.addEventListener("keyup",function(e){e=e.key||e.keyCode;"Escape"!==e&&"Esc"!==e&&27!==e||a()}),document.addEventListener("scroll",function(){var e;!c&&s.original&&(e=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,Math.abs(l-e)>u.scrollOffset&&setTimeout(a,150))}),window.addEventListener("resize",a);var f={open:i,close:a,toggle:o,update:function(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{},t=e;return e.background&&(p.style.background=e.background),e.container&&e.container instanceof Object&&(t.container=g({},u.container,e.container)),e.template&&(e=h(e.template)?e.template:document.querySelector(e.template),t.template=e),u=g({},u,t),m.forEach(function(e){e.dispatchEvent(E("medium-zoom:update",{detail:{zoom:f}}))}),f},clone:function(){return d(g({},u,0<arguments.length&&void 0!==arguments[0]?arguments[0]:{}))},attach:t,detach:function(){for(var e=arguments,t=arguments.length,o=Array(t),n=0;n<t;n++)o[n]=e[n];s.zoomed&&a();var i=0<o.length?o.reduce(function(e,t){return[].concat(e,z(t))},[]):m;return i.forEach(function(e){e.classList.remove("medium-zoom-image"),e.dispatchEvent(E("medium-zoom:detach",{detail:{zoom:f}}))}),m=m.filter(function(e){return-1===i.indexOf(e)}),f},on:function(t,o){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};return m.forEach(function(e){e.addEventListener("medium-zoom:"+t,o,n)}),r.push({type:"medium-zoom:"+t,listener:o,options:n}),f},off:function(t,o){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};return m.forEach(function(e){e.removeEventListener("medium-zoom:"+t,o,n)}),r=r.filter(function(e){return!(e.type==="medium-zoom:"+t&&e.listener.toString()===o.toString())}),f},getOptions:function(){return u},getImages:function(){return m},getZoomedImage:function(){return s.original}};return f}var g=Object.assign||function(e){for(var t=arguments,o=1;o<arguments.length;o++){var n,i=t[o];for(n in i)Object.prototype.hasOwnProperty.call(i,n)&&(e[n]=i[n])}return e},h=function(e){return e&&1===e.nodeType},v=function(e){return".svg"===(e.currentSrc||e.src).substr(-4).toLowerCase()},z=function(e){try{return Array.isArray(e)?e.filter(t):NodeList.prototype.isPrototypeOf(e)?[].slice.call(e).filter(t):h(e)?[e].filter(t):"string"==typeof e?[].slice.call(document.querySelectorAll(e)).filter(t):[]}catch(e){throw new TypeError("The provided selector is invalid.\nExpects a CSS selector, a Node element, a NodeList or an array.\nSee: https://github.com/francoischalifour/medium-zoom")}},y=function(e){var t=document.createElement("div");return t.classList.add("medium-zoom-overlay"),t.style.background=e,t},b=function(e){var t=e.getBoundingClientRect(),o=t.top,n=t.left,i=t.width,r=t.height,d=e.cloneNode(),t=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,e=window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft||0;return d.removeAttribute("id"),d.style.position="absolute",d.style.top=o+t+"px",d.style.left=n+e+"px",d.style.width=i+"px",d.style.height=r+"px",d.style.transform="",d},E=function(e,t){var o=g({bubbles:!1,cancelable:!1,detail:void 0},t);if("function"==typeof window.CustomEvent)return new CustomEvent(e,o);t=document.createEvent("CustomEvent");return t.initCustomEvent(e,o.bubbles,o.cancelable,o.detail),t};var e,o,n,i;e=".medium-zoom-overlay{position:fixed;top:0;right:0;bottom:0;left:0;opacity:0;transition:opacity .3s;will-change:opacity}.medium-zoom--opened .medium-zoom-overlay{cursor:pointer;cursor:zoom-out;opacity:1}.medium-zoom-image{cursor:pointer;cursor:zoom-in;transition:transform .3s cubic-bezier(.2,0,.2,1)!important}.medium-zoom-image--hidden{visibility:hidden}.medium-zoom-image--opened{position:relative;cursor:pointer;cursor:zoom-out;will-change:transform}",i=(o=void 0===o?{}:o).insertAt,e&&"undefined"!=typeof document&&(n=document.head||document.getElementsByTagName("head")[0],(o=document.createElement("style")).type="text/css","top"===i&&n.firstChild?n.insertBefore(o,n.firstChild):n.appendChild(o),o.styleSheet?o.styleSheet.cssText=e:o.appendChild(document.createTextNode(e)));var r=Element.prototype.matches||Element.prototype.webkitMatchesSelector||Element.prototype.msMatchesSelector;$docsify.plugins=[].concat(function(e){var o;e.doneEach(function(e){var t=(t=Array.apply(null,document.querySelectorAll(".markdown-section img:not(.emoji):not([data-no-zoom])"))).filter(function(e){return!1===r.call(e,"a img")});o&&o.detach(),o=d(t)})},$docsify.plugins)}();
libs/jdbc-aarch/kingbase8-8.6.0.jar 0 → 100644
No preview for this file type
libs/jdbc-aarch/kingbase8-8.6.0.jre7.jar 0 → 100644
No preview for this file type
libs/jdbc-aarch/postgresql-42.2.9.jar 0 → 100644
No preview for this file type
libs/jdbc-aarch/postgresql-42.2.9.jre7.jar 0 → 100644
No preview for this file type
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 11
12 <groupId>com.genersoft</groupId> 12 <groupId>com.genersoft</groupId>
13 <artifactId>wvp-pro</artifactId> 13 <artifactId>wvp-pro</artifactId>
14 - <version>2.6.8</version> 14 + <version>2.6.9</version>
15 <name>web video platform</name> 15 <name>web video platform</name>
16 <description>国标28181视频平台</description> 16 <description>国标28181视频平台</description>
17 <packaging>${project.packaging}</packaging> 17 <packaging>${project.packaging}</packaging>
@@ -135,11 +135,30 @@ @@ -135,11 +135,30 @@
135 <version>8.0.30</version> 135 <version>8.0.30</version>
136 </dependency> 136 </dependency>
137 137
  138 + <!--postgresql-->
  139 + <dependency>
  140 + <groupId>org.postgresql</groupId>
  141 + <artifactId>postgresql</artifactId>
  142 + <version>42.5.1</version>
  143 + </dependency>
  144 +
  145 + <!-- kingbase人大金仓 -->
  146 + <!-- 手动下载驱动后安装 -->
  147 + <!-- mvn install:install-file -Dfile=/home/lin/soft/kingbase/jdbc-aarch/kingbase8-8.6.0.jar -DgroupId=com.kingbase -DartifactId=kingbase8 -Dversion=8.6.0 -Dpackaging=jar
  148 + -->
  149 + <dependency>
  150 + <groupId>com.kingbase</groupId>
  151 + <artifactId>kingbase8</artifactId>
  152 + <version>8.6.0</version>
  153 + <scope>system</scope>
  154 + <systemPath>${basedir}/libs/jdbc-aarch/kingbase8-8.6.0.jar</systemPath>
  155 + </dependency>
  156 +
138 <!--Mybatis分页插件 --> 157 <!--Mybatis分页插件 -->
139 <dependency> 158 <dependency>
140 <groupId>com.github.pagehelper</groupId> 159 <groupId>com.github.pagehelper</groupId>
141 <artifactId>pagehelper-spring-boot-starter</artifactId> 160 <artifactId>pagehelper-spring-boot-starter</artifactId>
142 - <version>1.4.3</version> 161 + <version>1.4.6</version>
143 </dependency> 162 </dependency>
144 163
145 <!--在线文档 --> 164 <!--在线文档 -->
sql/2.6.6-2.6.7更新.sql
@@ -7,6 +7,7 @@ alter table parent_platform @@ -7,6 +7,7 @@ alter table parent_platform
7 alter table device 7 alter table device
8 add mediaServerId varchar(50) default null; 8 add mediaServerId varchar(50) default null;
9 9
10 - 10 +ALTER TABLE device
  11 + ADD COLUMN `switchPrimarySubStream` bit(1) NOT NULL DEFAULT b'0' COMMENT '开启主子码流切换的开关(0-不开启,1-开启)现在已知支持设备为 大华、TP——LINK全系设备' AFTER `keepalive_interval_time`
11 12
12 13
sql/2.6.8升级2.6.9.sql 0 → 100644
  1 +alter table device
  2 + change deviceId device_id varchar(50) not null;
  3 +
  4 +alter table device
  5 + change streamMode stream_mode varchar(50) null;
  6 +
  7 +alter table device
  8 + change registerTime register_time varchar(50) null;
  9 +
  10 +alter table device
  11 + change keepaliveTime keepalive_time varchar(50) null;
  12 +
  13 +alter table device
  14 + change createTime create_time varchar(50) not null;
  15 +
  16 +alter table device
  17 + change updateTime update_time varchar(50) not null;
  18 +
  19 +alter table device
  20 + change subscribeCycleForCatalog subscribe_cycle_for_catalog bool default false;
  21 +
  22 +alter table device
  23 + change subscribeCycleForMobilePosition subscribe_cycle_for_mobile_position bool default false;
  24 +
  25 +alter table device
  26 + change mobilePositionSubmissionInterval mobile_position_submission_interval int default 5 not null;
  27 +
  28 +alter table device
  29 + change subscribeCycleForAlarm subscribe_cycle_for_alarm bool default false;
  30 +
  31 +alter table device
  32 + change hostAddress host_address varchar(50) null;
  33 +
  34 +alter table device
  35 + change ssrcCheck ssrc_check bool default false;
  36 +
  37 +alter table device
  38 + change geoCoordSys geo_coord_sys varchar(50) not null;
  39 +
  40 +alter table device
  41 + drop column treeType;
  42 +
  43 +alter table device
  44 + change mediaServerId media_server_id varchar(50) default 'auto' null;
  45 +
  46 +alter table device
  47 + change sdpIp sdp_ip varchar(50) null;
  48 +
  49 +alter table device
  50 + change localIp local_ip varchar(50) null;
  51 +
  52 +alter table device
  53 + change asMessageChannel as_message_channel bool default false;
  54 +
  55 +alter table device
  56 + change keepaliveIntervalTime keepalive_interval_time int null;
  57 +
  58 +alter table device
  59 + change online on_line varchar(50) null;
  60 +
  61 +alter table device
  62 + add COLUMN switch_primary_sub_stream bool default false comment '开启主子码流切换的开关(0-不开启,1-开启)现在已知支持设备为 大华、TP——LINK全系设备'
  63 +
  64 +
  65 +alter table device_alarm
  66 + change deviceId device_id varchar(50) not null;
  67 +
  68 +alter table device_alarm
  69 + change channelId channel_id varchar(50) not null;
  70 +
  71 +alter table device_alarm
  72 + change alarmPriority alarm_priority varchar(50) not null;
  73 +
  74 +alter table device_alarm
  75 + change alarmMethod alarm_method varchar(50) null;
  76 +
  77 +alter table device_alarm
  78 + change alarmTime alarm_time varchar(50) not null;
  79 +
  80 +alter table device_alarm
  81 + change alarmDescription alarm_description varchar(255) null;
  82 +
  83 +alter table device_alarm
  84 + change alarmType alarm_type varchar(50) null;
  85 +
  86 +alter table device_alarm
  87 + change createTime create_time varchar(50) null;
  88 +
  89 +alter table device_channel
  90 + change channelId channel_id varchar(50) not null;
  91 +
  92 +alter table device_channel
  93 + change civilCode civil_code varchar(50) null;
  94 +
  95 +alter table device_channel
  96 + change parentId parent_id varchar(50) null;
  97 +
  98 +alter table device_channel
  99 + change safetyWay safety_way int null;
  100 +
  101 +alter table device_channel
  102 + change registerWay register_way int null;
  103 +
  104 +alter table device_channel
  105 + change certNum cert_num varchar(50) null;
  106 +
  107 +alter table device_channel
  108 + change errCode err_code int null;
  109 +
  110 +alter table device_channel
  111 + change endTime end_time varchar(50) null;
  112 +
  113 +alter table device_channel
  114 + change ipAddress ip_address varchar(50) null;
  115 +
  116 +alter table device_channel
  117 + change PTZType ptz_type int null;
  118 +
  119 +alter table device_channel
  120 + change status status bool default false;
  121 +
  122 +alter table device_channel
  123 + change streamId stream_id varchar(50) null;
  124 +
  125 +alter table device_channel
  126 + change deviceId device_id varchar(50) not null;
  127 +
  128 +
  129 +alter table device_channel
  130 + change hasAudio has_audio bool default false;
  131 +
  132 +alter table device_channel
  133 + change createTime create_time varchar(50) not null;
  134 +
  135 +alter table device_channel
  136 + change updateTime update_time varchar(50) not null;
  137 +
  138 +alter table device_channel
  139 + change subCount sub_count int default 0 null;
  140 +
  141 +alter table device_channel
  142 + change longitudeGcj02 longitude_gcj02 double null;
  143 +
  144 +alter table device_channel
  145 + change latitudeGcj02 latitude_gcj02 double null;
  146 +
  147 +alter table device_channel
  148 + change longitudeWgs84 longitude_wgs84 double null;
  149 +
  150 +alter table device_channel
  151 + change latitudeWgs84 latitude_wgs84 double null;
  152 +
  153 +alter table device_channel
  154 + change businessGroupId business_group_id varchar(50) null;
  155 +
  156 +alter table device_channel
  157 + change gpsTime gps_time varchar(50) null;
  158 +
  159 +alter table device_mobile_position
  160 + change deviceId device_id varchar(50) not null;
  161 +
  162 +alter table device_mobile_position
  163 + change channelId channel_id varchar(50) not null;
  164 +
  165 +alter table device_mobile_position
  166 + change deviceName device_name varchar(255) null;
  167 +
  168 +alter table device_mobile_position
  169 + change reportSource report_source varchar(50) null;
  170 +
  171 +alter table device_mobile_position
  172 + change longitudeGcj02 longitude_gcj02 double null;
  173 +
  174 +alter table device_mobile_position
  175 + change latitudeGcj02 latitude_gcj02 double null;
  176 +
  177 +alter table device_mobile_position
  178 + change longitudeWgs84 longitude_wgs84 double null;
  179 +
  180 +alter table device_mobile_position
  181 + change latitudeWgs84 latitude_wgs84 double null;
  182 +
  183 +alter table device_mobile_position
  184 + change createTime create_time varchar(50) null;
  185 +
  186 +alter table gb_stream
  187 + change gbStreamId gb_stream_id int auto_increment;
  188 +
  189 +alter table gb_stream
  190 + change gbId gb_id varchar(50) not null;
  191 +
  192 +alter table gb_stream
  193 + change streamType stream_type varchar(50) null;
  194 +
  195 +alter table gb_stream
  196 + change mediaServerId media_server_id varchar(50) null;
  197 +
  198 +alter table gb_stream
  199 + change createTime create_time varchar(50) null;
  200 +
  201 +alter table log
  202 + change createTime create_time varchar(50) not null;
  203 +
  204 +alter table media_server
  205 + change hookIp hook_ip varchar(50) not null;
  206 +
  207 +alter table media_server
  208 + change sdpIp sdp_ip varchar(50) not null;
  209 +
  210 +alter table media_server
  211 + change streamIp stream_ip varchar(50) not null;
  212 +
  213 +alter table media_server
  214 + change httpPort http_port int not null;
  215 +
  216 +alter table media_server
  217 + change httpSSlPort http_ssl_port int not null;
  218 +
  219 +alter table media_server
  220 + change rtmpPort rtmp_port int not null;
  221 +
  222 +alter table media_server
  223 + change rtmpSSlPort rtmp_ssl_port int not null;
  224 +
  225 +alter table media_server
  226 + change rtpProxyPort rtp_proxy_port int not null;
  227 +
  228 +alter table media_server
  229 + change rtspPort rtsp_port int not null;
  230 +
  231 +alter table media_server
  232 + change rtspSSLPort rtsp_ssl_port int not null;
  233 +
  234 +alter table media_server
  235 + change autoConfig auto_config bool default true;
  236 +
  237 +alter table media_server
  238 + change rtpEnable rtp_enable bool default false;
  239 +
  240 +alter table media_server
  241 + change rtpPortRange rtp_port_range varchar(50) not null;
  242 +
  243 +alter table media_server
  244 + change recordAssistPort record_assist_port int not null;
  245 +
  246 +alter table media_server
  247 + change defaultServer default_server bool default false;
  248 +
  249 +alter table media_server
  250 + change createTime create_time varchar(50) not null;
  251 +
  252 +alter table media_server
  253 + change updateTime update_time varchar(50) not null;
  254 +
  255 +alter table media_server
  256 + change hookAliveInterval hook_alive_interval int not null;
  257 +
  258 +alter table parent_platform
  259 + change serverGBId server_gb_id varchar(50) not null;
  260 +
  261 +alter table parent_platform
  262 + change serverGBDomain server_gb_domain varchar(50) null;
  263 +
  264 +alter table parent_platform
  265 + change serverIP server_ip varchar(50) null;
  266 +
  267 +alter table parent_platform
  268 + change serverPort server_port int null;
  269 +
  270 +alter table parent_platform
  271 + change deviceGBId device_gb_id varchar(50) not null;
  272 +
  273 +alter table parent_platform
  274 + change deviceIp device_ip varchar(50) null;
  275 +
  276 +alter table parent_platform
  277 + change devicePort device_port varchar(50) null;
  278 +
  279 +alter table parent_platform
  280 + change keepTimeout keep_timeout varchar(50) null;
  281 +
  282 +alter table parent_platform
  283 + change characterSet character_set varchar(50) null;
  284 +
  285 +alter table parent_platform
  286 + change catalogId catalog_id varchar(50) not null;
  287 +
  288 +alter table parent_platform
  289 + change startOfflinePush start_offline_push bool default false;
  290 +
  291 +alter table parent_platform
  292 + change administrativeDivision administrative_division varchar(50) not null;
  293 +
  294 +alter table parent_platform
  295 + change catalogGroup catalog_group int default 1 null;
  296 +
  297 +alter table parent_platform
  298 + change createTime create_time varchar(50) null;
  299 +
  300 +alter table parent_platform
  301 + change updateTime update_time varchar(50) null;
  302 +
  303 +alter table parent_platform
  304 + drop column treeType;
  305 +
  306 +alter table parent_platform
  307 + change asMessageChannel as_message_channel bool default false;
  308 +
  309 +alter table parent_platform
  310 + change enable enable bool default false;
  311 +
  312 +alter table parent_platform
  313 + change ptz ptz bool default false;
  314 +
  315 +alter table parent_platform
  316 + change rtcp rtcp bool default false;
  317 +
  318 +alter table parent_platform
  319 + change status status bool default false;
  320 +
  321 +alter table parent_platform
  322 + change status status bool default false;
  323 +
  324 +alter table platform_catalog
  325 + change platformId platform_id varchar(50) not null;
  326 +
  327 +alter table platform_catalog
  328 + change parentId parent_id varchar(50) null;
  329 +
  330 +alter table platform_catalog
  331 + change civilCode civil_code varchar(50) null;
  332 +
  333 +alter table platform_catalog
  334 + change businessGroupId business_group_id varchar(50) null;
  335 +
  336 +alter table platform_gb_channel
  337 + change platformId platform_id varchar(50) not null;
  338 +
  339 +alter table platform_gb_channel
  340 + change catalogId catalog_id varchar(50) not null;
  341 +
  342 +alter table platform_gb_channel
  343 + change deviceChannelId device_channel_id int not null;
  344 +
  345 +alter table platform_gb_stream
  346 + change platformId platform_id varchar(50) not null;
  347 +
  348 +alter table platform_gb_stream
  349 + change catalogId catalog_id varchar(50) not null;
  350 +
  351 +alter table platform_gb_stream
  352 + change gbStreamId gb_stream_id int not null;
  353 +
  354 +alter table stream_proxy
  355 + change mediaServerId media_server_id varchar(50) null;
  356 +
  357 +alter table stream_proxy
  358 + change createTime create_time varchar(50) not null;
  359 +
  360 +alter table stream_proxy
  361 + change updateTime update_time varchar(50) null;
  362 +
  363 +alter table stream_proxy
  364 + change enable_remove_none_reader enable_remove_none_reader bool default false;
  365 +
  366 +alter table stream_proxy
  367 + change enable_disable_none_reader enable_disable_none_reader bool default false;
  368 +
  369 +alter table stream_proxy
  370 + change enable_audio enable_audio bool default false;
  371 +
  372 +alter table stream_proxy
  373 + change enable_mp4 enable_mp4 bool default false;
  374 +
  375 +alter table stream_proxy
  376 + change enable enable bool default false;
  377 +
  378 +alter table stream_push
  379 + change totalReaderCount total_reader_count varchar(50) null;
  380 +
  381 +alter table stream_push
  382 + change originType origin_type int null;
  383 +
  384 +alter table stream_push
  385 + change originTypeStr origin_type_str varchar(50) null;
  386 +
  387 +alter table stream_push
  388 + change createTime create_time varchar(50) null;
  389 +
  390 +alter table stream_push
  391 + change aliveSecond alive_second int null;
  392 +
  393 +alter table stream_push
  394 + change mediaServerId media_server_id varchar(50) null;
  395 +
  396 +alter table stream_push
  397 + change status status bool default false;
  398 +
  399 +alter table stream_push
  400 + change pushTime push_time varchar(50) null;
  401 +
  402 +alter table stream_push
  403 + change updateTime update_time varchar(50) null;
  404 +
  405 +alter table stream_push
  406 + change pushIng push_ing bool default false;
  407 +
  408 +alter table stream_push
  409 + change status status bool default false;
  410 +
  411 +alter table stream_push
  412 + change self self bool default false;
  413 +
  414 +alter table stream_push
  415 + drop column serverId;
  416 +
  417 +
  418 +alter table user
  419 + change roleId role_id int not null;
  420 +
  421 +alter table user
  422 + change createTime create_time varchar(50) not null;
  423 +
  424 +alter table user
  425 + change updateTime update_time varchar(50) not null;
  426 +
  427 +alter table user
  428 + change pushKey push_key varchar(50) null;
  429 +
  430 +alter table user_role
  431 + change createTime create_time varchar(50) not null;
  432 +
  433 +alter table user_role
  434 + change updateTime update_time varchar(50) not null;
  435 +
  436 +rename table device to wvp_device;
  437 +rename table device_alarm to wvp_device_alarm;
  438 +rename table device_channel to wvp_device_channel;
  439 +rename table device_mobile_position to wvp_device_mobile_position;
  440 +rename table gb_stream to wvp_gb_stream;
  441 +rename table log to wvp_log;
  442 +rename table media_server to wvp_media_server;
  443 +rename table parent_platform to wvp_platform;
  444 +rename table platform_catalog to wvp_platform_catalog;
  445 +rename table platform_gb_channel to wvp_platform_gb_channel;
  446 +rename table platform_gb_stream to wvp_platform_gb_stream;
  447 +rename table stream_proxy to wvp_stream_proxy;
  448 +rename table stream_push to wvp_stream_push;
  449 +rename table user to wvp_user;
  450 +rename table user_role to wvp_user_role;
  451 +
  452 +
  453 +
  454 +
  455 +
  456 +
  457 +
  458 +
  459 +
  460 +
  461 +
  462 +
  463 +
  464 +
  465 +
  466 +
  467 +
  468 +
  469 +
  470 +
  471 +
  472 +
  473 +
  474 +
  475 +
  476 +
  477 +
  478 +
  479 +
sql/clean.sql
1 -delete from device;  
2 -delete from device_alarm;  
3 -delete from device_channel;  
4 -delete from device_mobile_position;  
5 -delete from gb_stream;  
6 -delete from log;  
7 -delete from media_server;  
8 -delete from parent_platform;  
9 -delete from platform_catalog;  
10 -delete from platform_gb_channel;  
11 -delete from platform_gb_stream;  
12 -delete from stream_proxy;  
13 -delete from stream_push;  
14 \ No newline at end of file 1 \ No newline at end of file
  2 +delete from wvp-device;
  3 +delete from wvp-device_alarm;
  4 +delete from wvp-device_channel;
  5 +delete from wvp-device_mobile_position;
  6 +delete from wvp-gb_stream;
  7 +delete from wvp-log;
  8 +delete from wvp-media_server;
  9 +delete from wvp-parent_platform;
  10 +delete from wvp-platform_catalog;
  11 +delete from wvp-platform_gb_channel;
  12 +delete from wvp-platform_gb_stream;
  13 +delete from wvp-stream_proxy;
  14 +delete from wvp-stream_push;
15 \ No newline at end of file 15 \ No newline at end of file
sql/初始化.sql
1 --- MySQL dump 10.13 Distrib 8.0.31, for Linux (x86_64)  
2 ---  
3 --- Host: 127.0.0.1 Database: wvp  
4 --- ------------------------------------------------------  
5 --- Server version 8.0.30 1 +/*建表*/
  2 +create table wvp_device (
  3 + id serial primary key ,
  4 + device_id character varying(50) not null ,
  5 + name character varying(255),
  6 + manufacturer character varying(255),
  7 + model character varying(255),
  8 + firmware character varying(255),
  9 + transport character varying(50),
  10 + stream_mode character varying(50),
  11 + on_line bool default false,
  12 + register_time character varying(50),
  13 + keepalive_time character varying(50),
  14 + ip character varying(50),
  15 + create_time character varying(50),
  16 + update_time character varying(50),
  17 + port integer,
  18 + expires integer,
  19 + subscribe_cycle_for_catalog integer DEFAULT 0,
  20 + subscribe_cycle_for_mobile_position integer DEFAULT 0,
  21 + mobile_position_submission_interval integer DEFAULT 5,
  22 + subscribe_cycle_for_alarm integer DEFAULT 0,
  23 + host_address character varying(50),
  24 + charset character varying(50),
  25 + ssrc_check bool default false,
  26 + geo_coord_sys character varying(50),
  27 + media_server_id character varying(50),
  28 + custom_name character varying(255),
  29 + sdp_ip character varying(50),
  30 + local_ip character varying(50),
  31 + password character varying(255),
  32 + as_message_channel bool default false,
  33 + keepalive_interval_time integer,
  34 + switch_primary_sub_stream bool default false,
  35 + constraint uk_device_device unique (device_id)
  36 +);
  37 +
  38 +create table wvp_device_alarm (
  39 + id serial primary key ,
  40 + device_id character varying(50) not null,
  41 + channel_id character varying(50) not null,
  42 + alarm_priority character varying(50),
  43 + alarm_method character varying(50),
  44 + alarm_time character varying(50),
  45 + alarm_description character varying(255),
  46 + longitude double precision,
  47 + latitude double precision,
  48 + alarm_type character varying(50),
  49 + create_time character varying(50) not null
  50 +);
  51 +
  52 +create table wvp_device_channel (
  53 + id serial primary key ,
  54 + channel_id character varying(50) not null,
  55 + name character varying(255),
  56 + manufacture character varying(50),
  57 + model character varying(50),
  58 + owner character varying(50),
  59 + civil_code character varying(50),
  60 + block character varying(50),
  61 + address character varying(50),
  62 + parent_id character varying(50),
  63 + safety_way integer,
  64 + register_way integer,
  65 + cert_num character varying(50),
  66 + certifiable integer,
  67 + err_code integer,
  68 + end_time character varying(50),
  69 + secrecy character varying(50),
  70 + ip_address character varying(50),
  71 + port integer,
  72 + password character varying(255),
  73 + ptz_type integer,
  74 + status bool default false,
  75 + longitude double precision,
  76 + latitude double precision,
  77 + stream_id character varying(50),
  78 + device_id character varying(50) not null,
  79 + parental character varying(50),
  80 + has_audio bool default false,
  81 + create_time character varying(50) not null,
  82 + update_time character varying(50) not null,
  83 + sub_count integer,
  84 + longitude_gcj02 double precision,
  85 + latitude_gcj02 double precision,
  86 + longitude_wgs84 double precision,
  87 + latitude_wgs84 double precision,
  88 + business_group_id character varying(50),
  89 + gps_time character varying(50),
  90 + constraint uk_wvp_device_channel_unique_device_channel unique (device_id, channel_id)
  91 +);
  92 +
  93 +create table wvp_device_mobile_position (
  94 + id serial primary key,
  95 + device_id character varying(50) not null,
  96 + channel_id character varying(50) not null,
  97 + device_name character varying(255),
  98 + time character varying(50),
  99 + longitude double precision,
  100 + latitude double precision,
  101 + altitude double precision,
  102 + speed double precision,
  103 + direction double precision,
  104 + report_source character varying(50),
  105 + longitude_gcj02 double precision,
  106 + latitude_gcj02 double precision,
  107 + longitude_wgs84 double precision,
  108 + latitude_wgs84 double precision,
  109 + create_time character varying(50)
  110 +);
  111 +
  112 +create table wvp_gb_stream (
  113 + gb_stream_id serial primary key,
  114 + app character varying(255) not null,
  115 + stream character varying(255) not null,
  116 + gb_id character varying(50) not null,
  117 + name character varying(255),
  118 + longitude double precision,
  119 + latitude double precision,
  120 + stream_type character varying(50),
  121 + media_server_id character varying(50),
  122 + create_time character varying(50),
  123 + constraint uk_gb_stream_unique_gb_id unique (gb_id),
  124 + constraint uk_gb_stream_unique_app_stream unique (app, stream)
  125 +);
  126 +
  127 +create table wvp_log (
  128 + id serial primary key ,
  129 + name character varying(50),
  130 + type character varying(50),
  131 + uri character varying(200),
  132 + address character varying(50),
  133 + result character varying(50),
  134 + timing bigint,
  135 + username character varying(50),
  136 + create_time character varying(50)
  137 +);
  138 +
  139 +create table wvp_media_server (
  140 + id character varying(255) primary key ,
  141 + ip character varying(50),
  142 + hook_ip character varying(50),
  143 + sdp_ip character varying(50),
  144 + stream_ip character varying(50),
  145 + http_port integer,
  146 + http_ssl_port integer,
  147 + rtmp_port integer,
  148 + rtmp_ssl_port integer,
  149 + rtp_proxy_port integer,
  150 + rtsp_port integer,
  151 + rtsp_ssl_port integer,
  152 + auto_config bool default false,
  153 + secret character varying(50),
  154 + rtp_enable bool default false,
  155 + rtp_port_range character varying(50),
  156 + record_assist_port integer,
  157 + default_server bool default false,
  158 + create_time character varying(50),
  159 + update_time character varying(50),
  160 + hook_alive_interval integer,
  161 + constraint uk_media_server_unique_ip_http_port unique (ip, http_port)
  162 +);
  163 +
  164 +create table wvp_platform (
  165 + id serial primary key ,
  166 + enable bool default false,
  167 + name character varying(255),
  168 + server_gb_id character varying(50),
  169 + server_gb_domain character varying(50),
  170 + server_ip character varying(50),
  171 + server_port integer,
  172 + device_gb_id character varying(50),
  173 + device_ip character varying(50),
  174 + device_port character varying(50),
  175 + username character varying(255),
  176 + password character varying(50),
  177 + expires character varying(50),
  178 + keep_timeout character varying(50),
  179 + transport character varying(50),
  180 + character_set character varying(50),
  181 + catalog_id character varying(50),
  182 + ptz bool default false,
  183 + rtcp bool default false,
  184 + status bool default false,
  185 + start_offline_push bool default false,
  186 + administrative_division character varying(50),
  187 + catalog_group integer,
  188 + create_time character varying(50),
  189 + update_time character varying(50),
  190 + as_message_channel bool default false,
  191 + constraint uk_platform_unique_server_gb_id unique (server_gb_id)
  192 +);
  193 +
  194 +create table wvp_platform_catalog (
  195 + id character varying(50),
  196 + platform_id character varying(50),
  197 + name character varying(255),
  198 + parent_id character varying(50),
  199 + civil_code character varying(50),
  200 + business_group_id character varying(50),
  201 + constraint uk_platform_catalog_id_platform_id unique (id, platform_id)
  202 +);
  203 +
  204 +create table wvp_platform_gb_channel (
  205 + id serial primary key ,
  206 + platform_id character varying(50),
  207 + catalog_id character varying(50),
  208 + device_channel_id integer,
  209 + constraint uk_platform_gb_channel_platform_id_catalog_id_device_channel_id unique (platform_id, catalog_id, device_channel_id)
  210 +);
  211 +
  212 +create table wvp_platform_gb_stream (
  213 + id serial primary key,
  214 + platform_id character varying(50),
  215 + catalog_id character varying(50),
  216 + gb_stream_id integer,
  217 + constraint uk_platform_gb_stream_platform_id_catalog_id_gb_stream_id unique (platform_id, catalog_id, gb_stream_id)
  218 +);
  219 +
  220 +create table wvp_stream_proxy (
  221 + id serial primary key,
  222 + type character varying(50),
  223 + app character varying(255),
  224 + stream character varying(255),
  225 + url character varying(255),
  226 + src_url character varying(255),
  227 + dst_url character varying(255),
  228 + timeout_ms integer,
  229 + ffmpeg_cmd_key character varying(255),
  230 + rtp_type character varying(50),
  231 + media_server_id character varying(50),
  232 + enable_audio bool default false,
  233 + enable_mp4 bool default false,
  234 + enable bool default false,
  235 + status boolean,
  236 + enable_remove_none_reader bool default false,
  237 + create_time character varying(50),
  238 + name character varying(255),
  239 + update_time character varying(50),
  240 + enable_disable_none_reader bool default false,
  241 + constraint uk_stream_proxy_app_stream unique (app, stream)
  242 +);
  243 +
  244 +create table wvp_stream_push (
  245 + id serial primary key,
  246 + app character varying(255),
  247 + stream character varying(255),
  248 + total_reader_count character varying(50),
  249 + origin_type integer,
  250 + origin_type_str character varying(50),
  251 + create_time character varying(50),
  252 + alive_second integer,
  253 + media_server_id character varying(50),
  254 + push_time character varying(50),
  255 + status bool default false,
  256 + update_time character varying(50),
  257 + push_ing bool default false,
  258 + self bool default false,
  259 + constraint uk_stream_push_app_stream unique (app, stream)
  260 +);
  261 +
  262 +create table wvp_user (
  263 + id serial primary key,
  264 + username character varying(255),
  265 + password character varying(255),
  266 + role_id integer,
  267 + create_time character varying(50),
  268 + update_time character varying(50),
  269 + push_key character varying(50),
  270 + constraint uk_user_username unique (username)
  271 +);
  272 +
  273 +create table wvp_user_role (
  274 + id serial primary key,
  275 + name character varying(50),
  276 + authority character varying(50),
  277 + create_time character varying(50),
  278 + update_time character varying(50)
  279 +);
  280 +
  281 +/*初始数据*/
  282 +INSERT INTO wvp_user VALUES (1, 'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57','3e80d1762a324d5b0ff636e0bd16f1e3');
  283 +INSERT INTO wvp_user_role VALUES (1, 'admin','0','2021-04-13 14:14:57','2021-04-13 14:14:57');
6 284
7 -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;  
8 -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;  
9 -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;  
10 -/*!50503 SET NAMES utf8mb4 */;  
11 -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;  
12 -/*!40103 SET TIME_ZONE='+00:00' */;  
13 -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;  
14 -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;  
15 -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;  
16 -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;  
17 285
18 ---  
19 --- Table structure for table `device`  
20 ---  
21 286
22 -DROP TABLE IF EXISTS `device`;  
23 -/*!40101 SET @saved_cs_client = @@character_set_client */;  
24 -/*!50503 SET character_set_client = utf8mb4 */;  
25 -CREATE TABLE `device` (  
26 - `id` int NOT NULL AUTO_INCREMENT,  
27 - `deviceId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
28 - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
29 - `manufacturer` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
30 - `model` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
31 - `firmware` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
32 - `transport` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
33 - `streamMode` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
34 - `online` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
35 - `mediaServerId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
36 - `registerTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
37 - `keepaliveTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
38 - `ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
39 - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
40 - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
41 - `port` int DEFAULT NULL,  
42 - `expires` int DEFAULT NULL,  
43 - `keepaliveIntervalTime` int DEFAULT NULL,  
44 - `subscribeCycleForCatalog` int DEFAULT NULL,  
45 - `hostAddress` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
46 - `charset` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
47 - `subscribeCycleForMobilePosition` int DEFAULT NULL,  
48 - `mobilePositionSubmissionInterval` int DEFAULT '5',  
49 - `subscribeCycleForAlarm` int DEFAULT NULL,  
50 - `ssrcCheck` int DEFAULT '0',  
51 - `asMessageChannel` int DEFAULT '0',  
52 - `geoCoordSys` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
53 - `treeType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
54 - `custom_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
55 - `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
56 - `sdpIp` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,  
57 - `localIp` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,  
58 - PRIMARY KEY (`id`),  
59 - UNIQUE KEY `device_deviceId_uindex` (`deviceId`)  
60 -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;  
61 -/*!40101 SET character_set_client = @saved_cs_client */;  
62 -  
63 ---  
64 --- Dumping data for table `device`  
65 ---  
66 -  
67 -LOCK TABLES `device` WRITE;  
68 -/*!40000 ALTER TABLE `device` DISABLE KEYS */;  
69 -/*!40000 ALTER TABLE `device` ENABLE KEYS */;  
70 -UNLOCK TABLES;  
71 -  
72 ---  
73 --- Table structure for table `device_alarm`  
74 ---  
75 -  
76 -DROP TABLE IF EXISTS `device_alarm`;  
77 -/*!40101 SET @saved_cs_client = @@character_set_client */;  
78 -/*!50503 SET character_set_client = utf8mb4 */;  
79 -CREATE TABLE `device_alarm` (  
80 - `id` int NOT NULL AUTO_INCREMENT,  
81 - `deviceId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
82 - `channelId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
83 - `alarmPriority` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
84 - `alarmMethod` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
85 - `alarmTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
86 - `alarmDescription` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
87 - `longitude` double DEFAULT NULL,  
88 - `latitude` double DEFAULT NULL,  
89 - `alarmType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
90 - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
91 - PRIMARY KEY (`id`) USING BTREE  
92 -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;  
93 -/*!40101 SET character_set_client = @saved_cs_client */;  
94 -  
95 ---  
96 --- Dumping data for table `device_alarm`  
97 ---  
98 -  
99 -LOCK TABLES `device_alarm` WRITE;  
100 -/*!40000 ALTER TABLE `device_alarm` DISABLE KEYS */;  
101 -/*!40000 ALTER TABLE `device_alarm` ENABLE KEYS */;  
102 -UNLOCK TABLES;  
103 -  
104 ---  
105 --- Table structure for table `device_channel`  
106 ---  
107 -  
108 -DROP TABLE IF EXISTS `device_channel`;  
109 -/*!40101 SET @saved_cs_client = @@character_set_client */;  
110 -/*!50503 SET character_set_client = utf8mb4 */;  
111 -CREATE TABLE `device_channel` (  
112 - `id` int NOT NULL AUTO_INCREMENT,  
113 - `channelId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
114 - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
115 - `manufacture` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
116 - `model` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
117 - `owner` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
118 - `civilCode` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
119 - `block` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
120 - `address` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
121 - `parentId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
122 - `safetyWay` int DEFAULT NULL,  
123 - `registerWay` int DEFAULT NULL,  
124 - `certNum` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
125 - `certifiable` int DEFAULT NULL,  
126 - `errCode` int DEFAULT NULL,  
127 - `endTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
128 - `secrecy` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
129 - `ipAddress` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
130 - `port` int DEFAULT NULL,  
131 - `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
132 - `PTZType` int DEFAULT NULL,  
133 - `status` int DEFAULT NULL,  
134 - `longitude` double DEFAULT NULL,  
135 - `latitude` double DEFAULT NULL,  
136 - `streamId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
137 - `deviceId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
138 - `parental` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
139 - `hasAudio` bit(1) DEFAULT NULL,  
140 - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
141 - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
142 - `subCount` int DEFAULT '0',  
143 - `longitudeGcj02` double DEFAULT NULL,  
144 - `latitudeGcj02` double DEFAULT NULL,  
145 - `longitudeWgs84` double DEFAULT NULL,  
146 - `latitudeWgs84` double DEFAULT NULL,  
147 - `businessGroupId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
148 - `gpsTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
149 - PRIMARY KEY (`id`),  
150 - UNIQUE KEY `device_channel_id_uindex` (`id`),  
151 - UNIQUE KEY `device_channel_pk` (`channelId`,`deviceId`)  
152 -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;  
153 -/*!40101 SET character_set_client = @saved_cs_client */;  
154 -  
155 ---  
156 --- Dumping data for table `device_channel`  
157 ---  
158 -  
159 -LOCK TABLES `device_channel` WRITE;  
160 -/*!40000 ALTER TABLE `device_channel` DISABLE KEYS */;  
161 -/*!40000 ALTER TABLE `device_channel` ENABLE KEYS */;  
162 -UNLOCK TABLES;  
163 -  
164 ---  
165 --- Table structure for table `device_mobile_position`  
166 ---  
167 -  
168 -DROP TABLE IF EXISTS `device_mobile_position`;  
169 -/*!40101 SET @saved_cs_client = @@character_set_client */;  
170 -/*!50503 SET character_set_client = utf8mb4 */;  
171 -CREATE TABLE `device_mobile_position` (  
172 - `id` int NOT NULL AUTO_INCREMENT,  
173 - `deviceId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
174 - `channelId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
175 - `deviceName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
176 - `time` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
177 - `longitude` double NOT NULL,  
178 - `latitude` double NOT NULL,  
179 - `altitude` double DEFAULT NULL,  
180 - `speed` double DEFAULT NULL,  
181 - `direction` double DEFAULT NULL,  
182 - `reportSource` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
183 - `longitudeGcj02` double DEFAULT NULL,  
184 - `latitudeGcj02` double DEFAULT NULL,  
185 - `longitudeWgs84` double DEFAULT NULL,  
186 - `latitudeWgs84` double DEFAULT NULL,  
187 - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
188 - PRIMARY KEY (`id`)  
189 -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;  
190 -/*!40101 SET character_set_client = @saved_cs_client */;  
191 -  
192 ---  
193 --- Dumping data for table `device_mobile_position`  
194 ---  
195 -  
196 -LOCK TABLES `device_mobile_position` WRITE;  
197 -/*!40000 ALTER TABLE `device_mobile_position` DISABLE KEYS */;  
198 -/*!40000 ALTER TABLE `device_mobile_position` ENABLE KEYS */;  
199 -UNLOCK TABLES;  
200 -  
201 ---  
202 --- Table structure for table `gb_stream`  
203 ---  
204 -  
205 -DROP TABLE IF EXISTS `gb_stream`;  
206 -/*!40101 SET @saved_cs_client = @@character_set_client */;  
207 -/*!50503 SET character_set_client = utf8mb4 */;  
208 -CREATE TABLE `gb_stream` (  
209 - `gbStreamId` int NOT NULL AUTO_INCREMENT,  
210 - `app` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
211 - `stream` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
212 - `gbId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
213 - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
214 - `longitude` double DEFAULT NULL,  
215 - `latitude` double DEFAULT NULL,  
216 - `streamType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
217 - `mediaServerId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
218 - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
219 - PRIMARY KEY (`gbStreamId`) USING BTREE,  
220 - UNIQUE KEY `app` (`app`,`stream`) USING BTREE,  
221 - UNIQUE KEY `gbId` (`gbId`) USING BTREE  
222 -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;  
223 -/*!40101 SET character_set_client = @saved_cs_client */;  
224 -  
225 ---  
226 --- Dumping data for table `gb_stream`  
227 ---  
228 -  
229 -LOCK TABLES `gb_stream` WRITE;  
230 -/*!40000 ALTER TABLE `gb_stream` DISABLE KEYS */;  
231 -/*!40000 ALTER TABLE `gb_stream` ENABLE KEYS */;  
232 -UNLOCK TABLES;  
233 -  
234 ---  
235 --- Table structure for table `log`  
236 ---  
237 -  
238 -DROP TABLE IF EXISTS `log`;  
239 -/*!40101 SET @saved_cs_client = @@character_set_client */;  
240 -/*!50503 SET character_set_client = utf8mb4 */;  
241 -CREATE TABLE `log` (  
242 - `id` int NOT NULL AUTO_INCREMENT,  
243 - `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
244 - `type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
245 - `uri` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
246 - `address` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
247 - `result` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
248 - `timing` bigint NOT NULL,  
249 - `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
250 - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
251 - PRIMARY KEY (`id`) USING BTREE  
252 -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;  
253 -/*!40101 SET character_set_client = @saved_cs_client */;  
254 -  
255 ---  
256 --- Dumping data for table `log`  
257 ---  
258 -  
259 -LOCK TABLES `log` WRITE;  
260 -/*!40000 ALTER TABLE `log` DISABLE KEYS */;  
261 -/*!40000 ALTER TABLE `log` ENABLE KEYS */;  
262 -UNLOCK TABLES;  
263 -  
264 ---  
265 --- Table structure for table `media_server`  
266 ---  
267 -  
268 -DROP TABLE IF EXISTS `media_server`;  
269 -/*!40101 SET @saved_cs_client = @@character_set_client */;  
270 -/*!50503 SET character_set_client = utf8mb4 */;  
271 -CREATE TABLE `media_server` (  
272 - `id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
273 - `ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
274 - `hookIp` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
275 - `sdpIp` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
276 - `streamIp` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
277 - `httpPort` int NOT NULL,  
278 - `httpSSlPort` int NOT NULL,  
279 - `rtmpPort` int NOT NULL,  
280 - `rtmpSSlPort` int NOT NULL,  
281 - `rtpProxyPort` int NOT NULL,  
282 - `rtspPort` int NOT NULL,  
283 - `rtspSSLPort` int NOT NULL,  
284 - `autoConfig` int NOT NULL,  
285 - `secret` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
286 - `rtpEnable` int NOT NULL,  
287 - `rtpPortRange` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
288 - `recordAssistPort` int NOT NULL,  
289 - `defaultServer` int NOT NULL,  
290 - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
291 - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
292 - `hookAliveInterval` int NOT NULL,  
293 - PRIMARY KEY (`id`) USING BTREE,  
294 - UNIQUE KEY `media_server_i` (`ip`,`httpPort`) USING BTREE  
295 -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;  
296 -/*!40101 SET character_set_client = @saved_cs_client */;  
297 -  
298 ---  
299 --- Dumping data for table `media_server`  
300 ---  
301 -  
302 -LOCK TABLES `media_server` WRITE;  
303 -/*!40000 ALTER TABLE `media_server` DISABLE KEYS */;  
304 -/*!40000 ALTER TABLE `media_server` ENABLE KEYS */;  
305 -UNLOCK TABLES;  
306 -  
307 ---  
308 --- Table structure for table `parent_platform`  
309 ---  
310 -  
311 -DROP TABLE IF EXISTS `parent_platform`;  
312 -/*!40101 SET @saved_cs_client = @@character_set_client */;  
313 -/*!50503 SET character_set_client = utf8mb4 */;  
314 -CREATE TABLE `parent_platform` (  
315 - `id` int NOT NULL AUTO_INCREMENT,  
316 - `enable` int DEFAULT NULL,  
317 - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
318 - `serverGBId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
319 - `serverGBDomain` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
320 - `serverIP` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
321 - `serverPort` int DEFAULT NULL,  
322 - `deviceGBId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
323 - `deviceIp` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
324 - `devicePort` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
325 - `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
326 - `password` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
327 - `expires` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
328 - `keepTimeout` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
329 - `transport` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
330 - `characterSet` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
331 - `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
332 - `ptz` int DEFAULT NULL,  
333 - `rtcp` int DEFAULT NULL,  
334 - `asMessageChannel` int DEFAULT '0',  
335 - `status` bit(1) DEFAULT NULL,  
336 - `startOfflinePush` int DEFAULT '0',  
337 - `administrativeDivision` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
338 - `catalogGroup` int DEFAULT '1',  
339 - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
340 - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
341 - `treeType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
342 - PRIMARY KEY (`id`),  
343 - UNIQUE KEY `parent_platform_id_uindex` (`id`),  
344 - UNIQUE KEY `parent_platform_pk` (`serverGBId`)  
345 -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;  
346 -/*!40101 SET character_set_client = @saved_cs_client */;  
347 -  
348 ---  
349 --- Dumping data for table `parent_platform`  
350 ---  
351 -  
352 -LOCK TABLES `parent_platform` WRITE;  
353 -/*!40000 ALTER TABLE `parent_platform` DISABLE KEYS */;  
354 -/*!40000 ALTER TABLE `parent_platform` ENABLE KEYS */;  
355 -UNLOCK TABLES;  
356 -  
357 ---  
358 --- Table structure for table `platform_catalog`  
359 ---  
360 -  
361 -DROP TABLE IF EXISTS `platform_catalog`;  
362 -/*!40101 SET @saved_cs_client = @@character_set_client */;  
363 -/*!50503 SET character_set_client = utf8mb4 */;  
364 -CREATE TABLE `platform_catalog` (  
365 - `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
366 - `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
367 - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
368 - `parentId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
369 - `civilCode` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
370 - `businessGroupId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
371 - PRIMARY KEY (`id`) USING BTREE  
372 -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;  
373 -/*!40101 SET character_set_client = @saved_cs_client */;  
374 -  
375 ---  
376 --- Dumping data for table `platform_catalog`  
377 ---  
378 -  
379 -LOCK TABLES `platform_catalog` WRITE;  
380 -/*!40000 ALTER TABLE `platform_catalog` DISABLE KEYS */;  
381 -/*!40000 ALTER TABLE `platform_catalog` ENABLE KEYS */;  
382 -UNLOCK TABLES;  
383 -  
384 ---  
385 --- Table structure for table `platform_gb_channel`  
386 ---  
387 -  
388 -DROP TABLE IF EXISTS `platform_gb_channel`;  
389 -/*!40101 SET @saved_cs_client = @@character_set_client */;  
390 -/*!50503 SET character_set_client = utf8mb4 */;  
391 -CREATE TABLE `platform_gb_channel` (  
392 - `id` int NOT NULL AUTO_INCREMENT,  
393 - `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
394 - `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
395 - `deviceChannelId` int NOT NULL,  
396 - PRIMARY KEY (`id`)  
397 -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;  
398 -/*!40101 SET character_set_client = @saved_cs_client */;  
399 -  
400 ---  
401 --- Dumping data for table `platform_gb_channel`  
402 ---  
403 -  
404 -LOCK TABLES `platform_gb_channel` WRITE;  
405 -/*!40000 ALTER TABLE `platform_gb_channel` DISABLE KEYS */;  
406 -/*!40000 ALTER TABLE `platform_gb_channel` ENABLE KEYS */;  
407 -UNLOCK TABLES;  
408 -  
409 ---  
410 --- Table structure for table `platform_gb_stream`  
411 ---  
412 -  
413 -DROP TABLE IF EXISTS `platform_gb_stream`;  
414 -/*!40101 SET @saved_cs_client = @@character_set_client */;  
415 -/*!50503 SET character_set_client = utf8mb4 */;  
416 -CREATE TABLE `platform_gb_stream` (  
417 - `id` int NOT NULL AUTO_INCREMENT,  
418 - `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
419 - `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
420 - `gbStreamId` int NOT NULL,  
421 - PRIMARY KEY (`id`),  
422 - UNIQUE KEY `platform_gb_stream_pk` (`platformId`,`catalogId`,`gbStreamId`)  
423 -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;  
424 -/*!40101 SET character_set_client = @saved_cs_client */;  
425 -  
426 ---  
427 --- Dumping data for table `platform_gb_stream`  
428 ---  
429 -  
430 -LOCK TABLES `platform_gb_stream` WRITE;  
431 -/*!40000 ALTER TABLE `platform_gb_stream` DISABLE KEYS */;  
432 -/*!40000 ALTER TABLE `platform_gb_stream` ENABLE KEYS */;  
433 -UNLOCK TABLES;  
434 -  
435 ---  
436 --- Table structure for table `stream_proxy`  
437 ---  
438 -  
439 -DROP TABLE IF EXISTS `stream_proxy`;  
440 -/*!40101 SET @saved_cs_client = @@character_set_client */;  
441 -/*!50503 SET character_set_client = utf8mb4 */;  
442 -CREATE TABLE `stream_proxy` (  
443 - `id` int NOT NULL AUTO_INCREMENT,  
444 - `type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
445 - `app` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
446 - `stream` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
447 - `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
448 - `src_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
449 - `dst_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
450 - `timeout_ms` int DEFAULT NULL,  
451 - `ffmpeg_cmd_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
452 - `rtp_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
453 - `mediaServerId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
454 - `enable_audio` bit(1) DEFAULT NULL,  
455 - `enable_mp4` bit(1) DEFAULT NULL,  
456 - `enable` bit(1) NOT NULL,  
457 - `status` bit(1) NOT NULL,  
458 - `enable_remove_none_reader` bit(1) NOT NULL,  
459 - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
460 - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
461 - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
462 - `enable_disable_none_reader` bit(1) DEFAULT NULL,  
463 - PRIMARY KEY (`id`),  
464 - UNIQUE KEY `stream_proxy_pk` (`app`,`stream`)  
465 -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;  
466 -/*!40101 SET character_set_client = @saved_cs_client */;  
467 -  
468 ---  
469 --- Dumping data for table `stream_proxy`  
470 ---  
471 -  
472 -LOCK TABLES `stream_proxy` WRITE;  
473 -/*!40000 ALTER TABLE `stream_proxy` DISABLE KEYS */;  
474 -/*!40000 ALTER TABLE `stream_proxy` ENABLE KEYS */;  
475 -UNLOCK TABLES;  
476 -  
477 ---  
478 --- Table structure for table `stream_push`  
479 ---  
480 -  
481 -DROP TABLE IF EXISTS `stream_push`;  
482 -/*!40101 SET @saved_cs_client = @@character_set_client */;  
483 -/*!50503 SET character_set_client = utf8mb4 */;  
484 -CREATE TABLE `stream_push` (  
485 - `id` int NOT NULL AUTO_INCREMENT,  
486 - `app` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
487 - `stream` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
488 - `totalReaderCount` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
489 - `originType` int DEFAULT NULL,  
490 - `originTypeStr` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
491 - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
492 - `aliveSecond` int DEFAULT NULL,  
493 - `mediaServerId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
494 - `serverId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
495 - `pushTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
496 - `status` int DEFAULT NULL,  
497 - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
498 - `pushIng` int DEFAULT NULL,  
499 - `self` int DEFAULT NULL,  
500 - PRIMARY KEY (`id`),  
501 - UNIQUE KEY `stream_push_pk` (`app`,`stream`)  
502 -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;  
503 -/*!40101 SET character_set_client = @saved_cs_client */;  
504 -  
505 ---  
506 --- Dumping data for table `stream_push`  
507 ---  
508 -  
509 -LOCK TABLES `stream_push` WRITE;  
510 -/*!40000 ALTER TABLE `stream_push` DISABLE KEYS */;  
511 -/*!40000 ALTER TABLE `stream_push` ENABLE KEYS */;  
512 -UNLOCK TABLES;  
513 -  
514 ---  
515 --- Table structure for table `user`  
516 ---  
517 -  
518 -DROP TABLE IF EXISTS `user`;  
519 -/*!40101 SET @saved_cs_client = @@character_set_client */;  
520 -/*!50503 SET character_set_client = utf8mb4 */;  
521 -CREATE TABLE `user` (  
522 - `id` int NOT NULL AUTO_INCREMENT,  
523 - `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
524 - `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
525 - `roleId` int NOT NULL,  
526 - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
527 - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
528 - `pushKey` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
529 - PRIMARY KEY (`id`) USING BTREE,  
530 - UNIQUE KEY `user_username_uindex` (`username`) USING BTREE  
531 -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;  
532 -/*!40101 SET character_set_client = @saved_cs_client */;  
533 -  
534 ---  
535 --- Dumping data for table `user`  
536 ---  
537 -  
538 -LOCK TABLES `user` WRITE;  
539 -/*!40000 ALTER TABLE `user` DISABLE KEYS */;  
540 -INSERT INTO `user` VALUES (1,'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57','3e80d1762a324d5b0ff636e0bd16f1e3');  
541 -/*!40000 ALTER TABLE `user` ENABLE KEYS */;  
542 -UNLOCK TABLES;  
543 -  
544 ---  
545 --- Table structure for table `user_role`  
546 ---  
547 -  
548 -DROP TABLE IF EXISTS `user_role`;  
549 -/*!40101 SET @saved_cs_client = @@character_set_client */;  
550 -/*!50503 SET character_set_client = utf8mb4 */;  
551 -CREATE TABLE `user_role` (  
552 - `id` int NOT NULL AUTO_INCREMENT,  
553 - `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
554 - `authority` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
555 - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
556 - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
557 - PRIMARY KEY (`id`) USING BTREE  
558 -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;  
559 -/*!40101 SET character_set_client = @saved_cs_client */;  
560 -  
561 ---  
562 --- Dumping data for table `user_role`  
563 ---  
564 -  
565 -LOCK TABLES `user_role` WRITE;  
566 -/*!40000 ALTER TABLE `user_role` DISABLE KEYS */;  
567 -INSERT INTO `user_role` VALUES (1,'admin','0','2021-04-13 14:14:57','2021-04-13 14:14:57');  
568 -/*!40000 ALTER TABLE `user_role` ENABLE KEYS */;  
569 -UNLOCK TABLES;  
570 -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;  
571 -  
572 -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;  
573 -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;  
574 -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;  
575 -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;  
576 -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;  
577 -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;  
578 -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;  
579 -  
580 --- Dump completed on 2022-11-29 11:47:46  
581 \ No newline at end of file 287 \ No newline at end of file
src/main/java/com/genersoft/iot/vmp/common/CivilCodePo.java 0 → 100644
  1 +package com.genersoft.iot.vmp.common;
  2 +
  3 +public class CivilCodePo {
  4 +
  5 + private String code;
  6 +
  7 + private String name;
  8 +
  9 + private String parentCode;
  10 +
  11 + public static CivilCodePo getInstance(String[] infoArray) {
  12 + CivilCodePo civilCodePo = new CivilCodePo();
  13 + civilCodePo.setCode(infoArray[0]);
  14 + civilCodePo.setName(infoArray[1]);
  15 + civilCodePo.setParentCode(infoArray[2]);
  16 + return civilCodePo;
  17 + }
  18 +
  19 + public String getCode() {
  20 + return code;
  21 + }
  22 +
  23 + public void setCode(String code) {
  24 + this.code = code;
  25 + }
  26 +
  27 + public String getName() {
  28 + return name;
  29 + }
  30 +
  31 + public void setName(String name) {
  32 + this.name = name;
  33 + }
  34 +
  35 + public String getParentCode() {
  36 + return parentCode;
  37 + }
  38 +
  39 + public void setParentCode(String parentCode) {
  40 + this.parentCode = parentCode;
  41 + }
  42 +}
src/main/java/com/genersoft/iot/vmp/common/GeneralCallback.java 0 → 100644
  1 +package com.genersoft.iot.vmp.common;
  2 +
  3 +public interface GeneralCallback<T>{
  4 + void run(int code, String msg, T data);
  5 +}
src/main/java/com/genersoft/iot/vmp/common/InviteInfo.java
1 package com.genersoft.iot.vmp.common; 1 package com.genersoft.iot.vmp.common;
2 2
3 import com.genersoft.iot.vmp.service.bean.SSRCInfo; 3 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
4 5
5 /** 6 /**
6 * 记录每次发送invite消息的状态 7 * 记录每次发送invite消息的状态
@@ -28,7 +29,7 @@ public class InviteInfo { @@ -28,7 +29,7 @@ public class InviteInfo {
28 private StreamInfo streamInfo; 29 private StreamInfo streamInfo;
29 30
30 31
31 - public static InviteInfo getinviteInfo(String deviceId, String channelId, String stream, SSRCInfo ssrcInfo, 32 + public static InviteInfo getInviteInfo(String deviceId, String channelId, String stream, SSRCInfo ssrcInfo,
32 String receiveIp, Integer receivePort, String streamMode, 33 String receiveIp, Integer receivePort, String streamMode,
33 InviteSessionType type, InviteSessionStatus status) { 34 InviteSessionType type, InviteSessionStatus status) {
34 InviteInfo inviteInfo = new InviteInfo(); 35 InviteInfo inviteInfo = new InviteInfo();
@@ -123,4 +124,21 @@ public class InviteInfo { @@ -123,4 +124,21 @@ public class InviteInfo {
123 public void setStreamMode(String streamMode) { 124 public void setStreamMode(String streamMode) {
124 this.streamMode = streamMode; 125 this.streamMode = streamMode;
125 } 126 }
  127 +
  128 +
  129 + /*=========================设备主子码流逻辑START====================*/
  130 + @Schema(description = "是否为子码流(true-是,false-主码流)")
  131 + private boolean subStream;
  132 +
  133 + public boolean isSubStream() {
  134 + return subStream;
  135 + }
  136 +
  137 + public void setSubStream(boolean subStream) {
  138 + this.subStream = subStream;
  139 + }
  140 +
  141 +
  142 +
  143 +
126 } 144 }
src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
@@ -528,4 +528,19 @@ public class StreamInfo implements Serializable, Cloneable{ @@ -528,4 +528,19 @@ public class StreamInfo implements Serializable, Cloneable{
528 } 528 }
529 return instance; 529 return instance;
530 } 530 }
  531 +
  532 +
  533 + /*=========================设备主子码流逻辑START====================*/
  534 + @Schema(description = "是否为子码流(true-是,false-主码流)")
  535 + private boolean subStream;
  536 +
  537 + public boolean isSubStream() {
  538 + return subStream;
  539 + }
  540 +
  541 + public void setSubStream(boolean subStream) {
  542 + this.subStream = subStream;
  543 + }
  544 +
  545 +
531 } 546 }
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
@@ -108,6 +108,11 @@ public class VideoManagerConstants { @@ -108,6 +108,11 @@ public class VideoManagerConstants {
108 public static final String VM_MSG_STREAM_PUSH_RESPONSE = "VM_MSG_STREAM_PUSH_RESPONSE"; 108 public static final String VM_MSG_STREAM_PUSH_RESPONSE = "VM_MSG_STREAM_PUSH_RESPONSE";
109 109
110 /** 110 /**
  111 + * redis 通知平台关闭推流
  112 + */
  113 + public static final String VM_MSG_STREAM_PUSH_CLOSE = "VM_MSG_STREAM_PUSH_CLOSE";
  114 +
  115 + /**
111 * redis 消息请求所有的在线通道 116 * redis 消息请求所有的在线通道
112 */ 117 */
113 public static final String VM_MSG_GET_ALL_ONLINE_REQUESTED = "VM_MSG_GET_ALL_ONLINE_REQUESTED"; 118 public static final String VM_MSG_GET_ALL_ONLINE_REQUESTED = "VM_MSG_GET_ALL_ONLINE_REQUESTED";
src/main/java/com/genersoft/iot/vmp/conf/CivilCodeFileConf.java 0 → 100644
  1 +package com.genersoft.iot.vmp.conf;
  2 +
  3 +import com.genersoft.iot.vmp.common.CivilCodePo;
  4 +import org.ehcache.impl.internal.concurrent.ConcurrentHashMap;
  5 +import org.slf4j.Logger;
  6 +import org.slf4j.LoggerFactory;
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.boot.CommandLineRunner;
  9 +import org.springframework.context.annotation.Configuration;
  10 +import org.springframework.context.annotation.Lazy;
  11 +import org.springframework.core.annotation.Order;
  12 +import org.springframework.core.io.ClassPathResource;
  13 +import org.springframework.util.ObjectUtils;
  14 +
  15 +import java.io.*;
  16 +import java.nio.file.Files;
  17 +import java.util.Map;
  18 +
  19 +/**
  20 + * 启动时读取行政区划表
  21 + */
  22 +@Configuration
  23 +@Order(value=14)
  24 +public class CivilCodeFileConf implements CommandLineRunner {
  25 +
  26 + private final static Logger logger = LoggerFactory.getLogger(CivilCodeFileConf.class);
  27 +
  28 + private final Map<String, CivilCodePo> civilCodeMap= new ConcurrentHashMap<>();
  29 +
  30 + @Autowired
  31 + @Lazy
  32 + private UserSetting userSetting;
  33 +
  34 + @Override
  35 + public void run(String... args) throws Exception {
  36 + if (ObjectUtils.isEmpty(userSetting.getCivilCodeFile())) {
  37 + logger.warn("[行政区划] 文件未设置,可能造成目录刷新结果不完整");
  38 + return;
  39 + }
  40 + InputStream inputStream;
  41 + if (userSetting.getCivilCodeFile().startsWith("classpath:")){
  42 + String filePath = userSetting.getCivilCodeFile().substring("classpath:".length());
  43 + ClassPathResource civilCodeFile = new ClassPathResource(filePath);
  44 + if (!civilCodeFile.exists()) {
  45 + logger.warn("[行政区划] 文件<{}>不存在,可能造成目录刷新结果不完整", userSetting.getCivilCodeFile());
  46 + return;
  47 + }
  48 + inputStream = civilCodeFile.getInputStream();
  49 +
  50 + }else {
  51 + File civilCodeFile = new File(userSetting.getCivilCodeFile());
  52 + if (!civilCodeFile.exists()) {
  53 + logger.warn("[行政区划] 文件<{}>不存在,可能造成目录刷新结果不完整", userSetting.getCivilCodeFile());
  54 + return;
  55 + }
  56 + inputStream = Files.newInputStream(civilCodeFile.toPath());
  57 + }
  58 +
  59 + BufferedReader inputStreamReader = new BufferedReader(new InputStreamReader(inputStream));
  60 + int index = -1;
  61 + String line;
  62 + while ((line = inputStreamReader.readLine()) != null) {
  63 + index ++;
  64 + if (index == 0) {
  65 + continue;
  66 + }
  67 + String[] infoArray = line.split(",");
  68 + CivilCodePo civilCodePo = CivilCodePo.getInstance(infoArray);
  69 + civilCodeMap.put(civilCodePo.getCode(), civilCodePo);
  70 + }
  71 + inputStreamReader.close();
  72 + inputStream.close();
  73 + if (civilCodeMap.size() == 0) {
  74 + logger.warn("[行政区划] 文件内容为空,可能造成目录刷新结果不完整");
  75 + }else {
  76 + logger.info("[行政区划] 加载成功,共加载数据{}条", civilCodeMap.size());
  77 + }
  78 + }
  79 +
  80 + public CivilCodePo getParentCode(String code) {
  81 + if (code.length() > 8) {
  82 + return null;
  83 + }
  84 + if (code.length() == 8) {
  85 + String parentCode = code.substring(0, 6);
  86 + return civilCodeMap.get(parentCode);
  87 + }else {
  88 + CivilCodePo civilCodePo = civilCodeMap.get(code);
  89 + if (civilCodePo == null){
  90 + return null;
  91 + }
  92 + String parentCode = civilCodePo.getParentCode();
  93 + if (parentCode == null) {
  94 + return null;
  95 + }
  96 + return civilCodeMap.get(parentCode);
  97 + }
  98 +
  99 + }
  100 +
  101 +}
src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java
@@ -2,11 +2,11 @@ package com.genersoft.iot.vmp.conf; @@ -2,11 +2,11 @@ package com.genersoft.iot.vmp.conf;
2 2
3 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 3 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
4 import com.genersoft.iot.vmp.utils.DateUtil; 4 import com.genersoft.iot.vmp.utils.DateUtil;
5 -import org.junit.jupiter.api.Order;  
6 import org.slf4j.Logger; 5 import org.slf4j.Logger;
7 import org.slf4j.LoggerFactory; 6 import org.slf4j.LoggerFactory;
8 import org.springframework.beans.factory.annotation.Value; 7 import org.springframework.beans.factory.annotation.Value;
9 import org.springframework.context.annotation.Configuration; 8 import org.springframework.context.annotation.Configuration;
  9 +import org.springframework.core.annotation.Order;
10 import org.springframework.util.ObjectUtils; 10 import org.springframework.util.ObjectUtils;
11 11
12 import java.net.InetAddress; 12 import java.net.InetAddress;
src/main/java/com/genersoft/iot/vmp/conf/MybatisConfig.java 0 → 100644
  1 +package com.genersoft.iot.vmp.conf;
  2 +
  3 +import org.apache.ibatis.logging.stdout.StdOutImpl;
  4 +import org.apache.ibatis.session.SqlSessionFactory;
  5 +import org.mybatis.spring.SqlSessionFactoryBean;
  6 +import org.springframework.beans.factory.annotation.Autowired;
  7 +import org.springframework.context.annotation.Bean;
  8 +import org.springframework.context.annotation.Configuration;
  9 +import org.springframework.core.annotation.Order;
  10 +
  11 +import javax.sql.DataSource;
  12 +
  13 +/**
  14 + * 配置mybatis
  15 + */
  16 +@Configuration
  17 +@Order(value=1)
  18 +public class MybatisConfig {
  19 +
  20 + @Autowired
  21 + private UserSetting userSetting;
  22 +
  23 + @Bean
  24 + public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
  25 + final SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
  26 + sqlSessionFactory.setDataSource(dataSource);
  27 + org.apache.ibatis.session.Configuration config = new org.apache.ibatis.session.Configuration();
  28 + if (userSetting.getSqlLog()){
  29 + config.setLogImpl(StdOutImpl.class);
  30 + }
  31 + config.setMapUnderscoreToCamelCase(true);
  32 + sqlSessionFactory.setConfiguration(config);
  33 + return sqlSessionFactory.getObject();
  34 + }
  35 +
  36 +}
src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java
@@ -5,7 +5,7 @@ import com.genersoft.iot.vmp.service.IMediaServerService; @@ -5,7 +5,7 @@ import com.genersoft.iot.vmp.service.IMediaServerService;
5 import org.apache.http.HttpHost; 5 import org.apache.http.HttpHost;
6 import org.apache.http.HttpRequest; 6 import org.apache.http.HttpRequest;
7 import org.apache.http.HttpResponse; 7 import org.apache.http.HttpResponse;
8 -import org.junit.jupiter.api.Order; 8 +import org.springframework.core.annotation.Order;
9 import org.mitre.dsmiley.httpproxy.ProxyServlet; 9 import org.mitre.dsmiley.httpproxy.ProxyServlet;
10 import org.slf4j.Logger; 10 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory; 11 import org.slf4j.LoggerFactory;
src/main/java/com/genersoft/iot/vmp/conf/SipConfig.java
1 package com.genersoft.iot.vmp.conf; 1 package com.genersoft.iot.vmp.conf;
2 2
3 3
4 -import org.junit.jupiter.api.Order; 4 +import org.springframework.core.annotation.Order;
5 import org.springframework.boot.context.properties.ConfigurationProperties; 5 import org.springframework.boot.context.properties.ConfigurationProperties;
6 import org.springframework.stereotype.Component; 6 import org.springframework.stereotype.Component;
7 7
src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java
@@ -56,7 +56,7 @@ public class SipPlatformRunner implements CommandLineRunner { @@ -56,7 +56,7 @@ public class SipPlatformRunner implements CommandLineRunner {
56 } 56 }
57 57
58 // 设置所有平台离线 58 // 设置所有平台离线
59 - platformService.offline(parentPlatform, true); 59 + platformService.offline(parentPlatform, false);
60 } 60 }
61 } 61 }
62 } 62 }
src/main/java/com/genersoft/iot/vmp/conf/SpringDocConfig.java
@@ -4,7 +4,7 @@ import io.swagger.v3.oas.models.OpenAPI; @@ -4,7 +4,7 @@ import io.swagger.v3.oas.models.OpenAPI;
4 import io.swagger.v3.oas.models.info.Contact; 4 import io.swagger.v3.oas.models.info.Contact;
5 import io.swagger.v3.oas.models.info.Info; 5 import io.swagger.v3.oas.models.info.Info;
6 import io.swagger.v3.oas.models.info.License; 6 import io.swagger.v3.oas.models.info.License;
7 -import org.junit.jupiter.api.Order; 7 +import org.springframework.core.annotation.Order;
8 import org.springdoc.core.GroupedOpenApi; 8 import org.springdoc.core.GroupedOpenApi;
9 import org.springframework.beans.factory.annotation.Value; 9 import org.springframework.beans.factory.annotation.Value;
10 import org.springframework.context.annotation.Bean; 10 import org.springframework.context.annotation.Bean;
src/main/java/com/genersoft/iot/vmp/conf/ThreadPoolTaskConfig.java
1 package com.genersoft.iot.vmp.conf; 1 package com.genersoft.iot.vmp.conf;
2 2
3 -import org.junit.jupiter.api.Order;  
4 import org.springframework.context.annotation.Bean; 3 import org.springframework.context.annotation.Bean;
5 import org.springframework.context.annotation.Configuration; 4 import org.springframework.context.annotation.Configuration;
  5 +import org.springframework.core.annotation.Order;
6 import org.springframework.scheduling.annotation.EnableAsync; 6 import org.springframework.scheduling.annotation.EnableAsync;
7 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 7 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
8 8
src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
1 package com.genersoft.iot.vmp.conf; 1 package com.genersoft.iot.vmp.conf;
2 2
3 -import org.junit.jupiter.api.Order;  
4 import org.springframework.boot.context.properties.ConfigurationProperties; 3 import org.springframework.boot.context.properties.ConfigurationProperties;
  4 +import org.springframework.core.annotation.Order;
5 import org.springframework.stereotype.Component; 5 import org.springframework.stereotype.Component;
6 6
7 import java.util.ArrayList; 7 import java.util.ArrayList;
@@ -50,6 +50,7 @@ public class UserSetting { @@ -50,6 +50,7 @@ public class UserSetting {
50 private Boolean pushStreamAfterAck = Boolean.FALSE; 50 private Boolean pushStreamAfterAck = Boolean.FALSE;
51 51
52 private Boolean sipLog = Boolean.FALSE; 52 private Boolean sipLog = Boolean.FALSE;
  53 + private Boolean sqlLog = Boolean.FALSE;
53 private Boolean sendToPlatformsWhenIdLost = Boolean.FALSE; 54 private Boolean sendToPlatformsWhenIdLost = Boolean.FALSE;
54 55
55 private Boolean refuseChannelStatusChannelFormNotify = Boolean.FALSE; 56 private Boolean refuseChannelStatusChannelFormNotify = Boolean.FALSE;
@@ -65,12 +66,18 @@ public class UserSetting { @@ -65,12 +66,18 @@ public class UserSetting {
65 66
66 private String broadcastForPlatform = "UDP"; 67 private String broadcastForPlatform = "UDP";
67 68
  69 + private String civilCodeFile = "classpath:civilCode.csv";
  70 +
68 private List<String> interfaceAuthenticationExcludes = new ArrayList<>(); 71 private List<String> interfaceAuthenticationExcludes = new ArrayList<>();
69 72
70 private List<String> allowedOrigins = new ArrayList<>(); 73 private List<String> allowedOrigins = new ArrayList<>();
71 74
72 private int maxNotifyCountQueue = 10000; 75 private int maxNotifyCountQueue = 10000;
73 76
  77 + private int registerAgainAfterTime = 60;
  78 +
  79 + private boolean registerKeepIntDialog = false;
  80 +
74 public Boolean getSavePositionHistory() { 81 public Boolean getSavePositionHistory() {
75 return savePositionHistory; 82 return savePositionHistory;
76 } 83 }
@@ -306,4 +313,36 @@ public class UserSetting { @@ -306,4 +313,36 @@ public class UserSetting {
306 public void setUseCustomSsrcForParentInvite(Boolean useCustomSsrcForParentInvite) { 313 public void setUseCustomSsrcForParentInvite(Boolean useCustomSsrcForParentInvite) {
307 this.useCustomSsrcForParentInvite = useCustomSsrcForParentInvite; 314 this.useCustomSsrcForParentInvite = useCustomSsrcForParentInvite;
308 } 315 }
  316 +
  317 + public Boolean getSqlLog() {
  318 + return sqlLog;
  319 + }
  320 +
  321 + public void setSqlLog(Boolean sqlLog) {
  322 + this.sqlLog = sqlLog;
  323 + }
  324 +
  325 + public String getCivilCodeFile() {
  326 + return civilCodeFile;
  327 + }
  328 +
  329 + public void setCivilCodeFile(String civilCodeFile) {
  330 + this.civilCodeFile = civilCodeFile;
  331 + }
  332 +
  333 + public int getRegisterAgainAfterTime() {
  334 + return registerAgainAfterTime;
  335 + }
  336 +
  337 + public void setRegisterAgainAfterTime(int registerAgainAfterTime) {
  338 + this.registerAgainAfterTime = registerAgainAfterTime;
  339 + }
  340 +
  341 + public boolean isRegisterKeepIntDialog() {
  342 + return registerKeepIntDialog;
  343 + }
  344 +
  345 + public void setRegisterKeepIntDialog(boolean registerKeepIntDialog) {
  346 + this.registerKeepIntDialog = registerKeepIntDialog;
  347 + }
309 } 348 }
src/main/java/com/genersoft/iot/vmp/conf/VersionConfig.java
1 package com.genersoft.iot.vmp.conf; 1 package com.genersoft.iot.vmp.conf;
2 2
3 -import org.junit.jupiter.api.Order; 3 +import org.springframework.core.annotation.Order;
4 import org.springframework.boot.context.properties.ConfigurationProperties; 4 import org.springframework.boot.context.properties.ConfigurationProperties;
5 import org.springframework.stereotype.Component; 5 import org.springframework.stereotype.Component;
6 6
src/main/java/com/genersoft/iot/vmp/conf/redis/RedisMsgListenConfig.java
@@ -43,6 +43,9 @@ public class RedisMsgListenConfig { @@ -43,6 +43,9 @@ public class RedisMsgListenConfig {
43 @Autowired 43 @Autowired
44 private RedisPushStreamResponseListener redisPushStreamResponseListener; 44 private RedisPushStreamResponseListener redisPushStreamResponseListener;
45 45
  46 + @Autowired
  47 + private RedisCloseStreamMsgListener redisCloseStreamMsgListener;
  48 +
46 49
47 /** 50 /**
48 * redis消息监听器容器 可以添加多个监听不同话题的redis监听器,只需要把消息监听器和相应的消息订阅处理器绑定,该消息监听器 51 * redis消息监听器容器 可以添加多个监听不同话题的redis监听器,只需要把消息监听器和相应的消息订阅处理器绑定,该消息监听器
@@ -63,6 +66,7 @@ public class RedisMsgListenConfig { @@ -63,6 +66,7 @@ public class RedisMsgListenConfig {
63 container.addMessageListener(redisPushStreamStatusMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_STATUS_CHANGE)); 66 container.addMessageListener(redisPushStreamStatusMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_STATUS_CHANGE));
64 container.addMessageListener(redisPushStreamListMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_LIST_CHANGE)); 67 container.addMessageListener(redisPushStreamListMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_LIST_CHANGE));
65 container.addMessageListener(redisPushStreamResponseListener, new PatternTopic(VideoManagerConstants.VM_MSG_STREAM_PUSH_RESPONSE)); 68 container.addMessageListener(redisPushStreamResponseListener, new PatternTopic(VideoManagerConstants.VM_MSG_STREAM_PUSH_RESPONSE));
  69 + container.addMessageListener(redisCloseStreamMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_STREAM_PUSH_CLOSE));
66 return container; 70 return container;
67 } 71 }
68 } 72 }
src/main/java/com/genersoft/iot/vmp/conf/security/AnonymousAuthenticationEntryPoint.java
@@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.conf.security; @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.conf.security;
3 import com.alibaba.fastjson2.JSONObject; 3 import com.alibaba.fastjson2.JSONObject;
4 import com.genersoft.iot.vmp.conf.security.dto.JwtUser; 4 import com.genersoft.iot.vmp.conf.security.dto.JwtUser;
5 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; 5 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
  6 +import org.springframework.http.MediaType;
6 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 7 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
7 import org.springframework.security.core.AuthenticationException; 8 import org.springframework.security.core.AuthenticationException;
8 import org.springframework.security.core.context.SecurityContextHolder; 9 import org.springframework.security.core.context.SecurityContextHolder;
@@ -12,6 +13,7 @@ import org.springframework.stereotype.Component; @@ -12,6 +13,7 @@ import org.springframework.stereotype.Component;
12 import javax.servlet.http.HttpServletRequest; 13 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse; 14 import javax.servlet.http.HttpServletResponse;
14 import java.io.IOException; 15 import java.io.IOException;
  16 +import java.nio.charset.StandardCharsets;
15 17
16 /** 18 /**
17 * 处理匿名用户访问逻辑 19 * 处理匿名用户访问逻辑
@@ -35,6 +37,8 @@ public class AnonymousAuthenticationEntryPoint implements AuthenticationEntry @@ -35,6 +37,8 @@ public class AnonymousAuthenticationEntryPoint implements AuthenticationEntry
35 jsonObject.put("msg", e.getMessage()); 37 jsonObject.put("msg", e.getMessage());
36 } 38 }
37 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 39 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
  40 + response.setContentType(MediaType.APPLICATION_JSON_VALUE);
  41 + response.setCharacterEncoding(StandardCharsets.UTF_8.name());
38 try { 42 try {
39 response.getWriter().print(jsonObject.toJSONString()); 43 response.getWriter().print(jsonObject.toJSONString());
40 } catch (IOException ioException) { 44 } catch (IOException ioException) {
src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java
1 package com.genersoft.iot.vmp.conf.security; 1 package com.genersoft.iot.vmp.conf.security;
2 2
3 import com.genersoft.iot.vmp.conf.UserSetting; 3 import com.genersoft.iot.vmp.conf.UserSetting;
4 -import org.junit.jupiter.api.Order; 4 +import org.springframework.core.annotation.Order;
5 import org.slf4j.Logger; 5 import org.slf4j.Logger;
6 import org.slf4j.LoggerFactory; 6 import org.slf4j.LoggerFactory;
7 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.beans.factory.annotation.Autowired;
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
@@ -77,8 +77,8 @@ public class Device { @@ -77,8 +77,8 @@ public class Device {
77 /** 77 /**
78 * 在线 78 * 在线
79 */ 79 */
80 - @Schema(description = "是否在线,1为在线,0为离线")  
81 - private int online; 80 + @Schema(description = "是否在线,true为在线,false为离线")
  81 + private boolean onLine;
82 82
83 83
84 /** 84 /**
@@ -140,7 +140,7 @@ public class Device { @@ -140,7 +140,7 @@ public class Device {
140 /** 140 /**
141 * 目录订阅周期,0为不订阅 141 * 目录订阅周期,0为不订阅
142 */ 142 */
143 - @Schema(description = "目录订阅周期,0为不订阅") 143 + @Schema(description = "目录订阅周期,o为不订阅")
144 private int subscribeCycleForCatalog; 144 private int subscribeCycleForCatalog;
145 145
146 /** 146 /**
@@ -173,12 +173,6 @@ public class Device { @@ -173,12 +173,6 @@ public class Device {
173 @Schema(description = "地理坐标系, 目前支持 WGS84,GCJ02") 173 @Schema(description = "地理坐标系, 目前支持 WGS84,GCJ02")
174 private String geoCoordSys; 174 private String geoCoordSys;
175 175
176 - /**  
177 - * 树类型 国标规定了两种树的展现方式 行政区划:CivilCode 和业务分组:BusinessGroup  
178 - */  
179 - @Schema(description = "树类型 国标规定了两种树的展现方式 行政区划:CivilCode 和业务分组:BusinessGroup")  
180 - private String treeType;  
181 -  
182 @Schema(description = "密码") 176 @Schema(description = "密码")
183 private String password; 177 private String password;
184 178
@@ -195,6 +189,8 @@ public class Device { @@ -195,6 +189,8 @@ public class Device {
195 private SipTransactionInfo sipTransactionInfo; 189 private SipTransactionInfo sipTransactionInfo;
196 190
197 191
  192 +
  193 +
198 public String getDeviceId() { 194 public String getDeviceId() {
199 return deviceId; 195 return deviceId;
200 } 196 }
@@ -286,12 +282,12 @@ public class Device { @@ -286,12 +282,12 @@ public class Device {
286 this.hostAddress = hostAddress; 282 this.hostAddress = hostAddress;
287 } 283 }
288 284
289 - public int getOnline() {  
290 - return online; 285 + public boolean isOnLine() {
  286 + return onLine;
291 } 287 }
292 288
293 - public void setOnline(int online) {  
294 - this.online = online; 289 + public void setOnLine(boolean onLine) {
  290 + this.onLine = onLine;
295 } 291 }
296 292
297 public int getChannelCount() { 293 public int getChannelCount() {
@@ -406,15 +402,6 @@ public class Device { @@ -406,15 +402,6 @@ public class Device {
406 this.geoCoordSys = geoCoordSys; 402 this.geoCoordSys = geoCoordSys;
407 } 403 }
408 404
409 -  
410 - public String getTreeType() {  
411 - return treeType;  
412 - }  
413 -  
414 - public void setTreeType(String treeType) {  
415 - this.treeType = treeType;  
416 - }  
417 -  
418 public String getPassword() { 405 public String getPassword() {
419 return password; 406 return password;
420 } 407 }
@@ -462,4 +449,20 @@ public class Device { @@ -462,4 +449,20 @@ public class Device {
462 public void setSipTransactionInfo(SipTransactionInfo sipTransactionInfo) { 449 public void setSipTransactionInfo(SipTransactionInfo sipTransactionInfo) {
463 this.sipTransactionInfo = sipTransactionInfo; 450 this.sipTransactionInfo = sipTransactionInfo;
464 } 451 }
  452 +
  453 + /*======================设备主子码流逻辑START=========================*/
  454 + @Schema(description = "开启主子码流切换的开关(false-不开启,true-开启)")
  455 + private boolean switchPrimarySubStream;
  456 +
  457 + public boolean isSwitchPrimarySubStream() {
  458 + return switchPrimarySubStream;
  459 + }
  460 +
  461 + public void setSwitchPrimarySubStream(boolean switchPrimarySubStream) {
  462 + this.switchPrimarySubStream = switchPrimarySubStream;
  463 + }
  464 +
  465 + /*======================设备主子码流逻辑END=========================*/
  466 +
  467 +
465 } 468 }
src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java
@@ -172,7 +172,7 @@ public class DeviceChannel { @@ -172,7 +172,7 @@ public class DeviceChannel {
172 * 遇到过NVR下的IPC下发信令可以推流, 但是 Status 响应 OFF 172 * 遇到过NVR下的IPC下发信令可以推流, 但是 Status 响应 OFF
173 */ 173 */
174 @Schema(description = "在线/离线, 1在线,0离线") 174 @Schema(description = "在线/离线, 1在线,0离线")
175 - private int status; 175 + private boolean status;
176 176
177 /** 177 /**
178 * 经度 178 * 经度
@@ -455,11 +455,11 @@ public class DeviceChannel { @@ -455,11 +455,11 @@ public class DeviceChannel {
455 this.PTZTypeText = PTZTypeText; 455 this.PTZTypeText = PTZTypeText;
456 } 456 }
457 457
458 - public int getStatus() { 458 + public boolean isStatus() {
459 return status; 459 return status;
460 } 460 }
461 461
462 - public void setStatus(int status) { 462 + public void setStatus(boolean status) {
463 this.status = status; 463 this.status = status;
464 } 464 }
465 465
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Gb28181Sdp.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.bean;
  2 +
  3 +import javax.sdp.SessionDescription;
  4 +
  5 +/**
  6 + * 28181 的SDP解析器
  7 + */
  8 +public class Gb28181Sdp {
  9 + private SessionDescription baseSdb;
  10 + private String ssrc;
  11 +
  12 + private String mediaDescription;
  13 +
  14 + public static Gb28181Sdp getInstance(SessionDescription baseSdb, String ssrc, String mediaDescription) {
  15 + Gb28181Sdp gb28181Sdp = new Gb28181Sdp();
  16 + gb28181Sdp.setBaseSdb(baseSdb);
  17 + gb28181Sdp.setSsrc(ssrc);
  18 + gb28181Sdp.setMediaDescription(mediaDescription);
  19 + return gb28181Sdp;
  20 + }
  21 +
  22 +
  23 + public SessionDescription getBaseSdb() {
  24 + return baseSdb;
  25 + }
  26 +
  27 + public void setBaseSdb(SessionDescription baseSdb) {
  28 + this.baseSdb = baseSdb;
  29 + }
  30 +
  31 + public String getSsrc() {
  32 + return ssrc;
  33 + }
  34 +
  35 + public void setSsrc(String ssrc) {
  36 + this.ssrc = ssrc;
  37 + }
  38 +
  39 + public String getMediaDescription() {
  40 + return mediaDescription;
  41 + }
  42 +
  43 + public void setMediaDescription(String mediaDescription) {
  44 + this.mediaDescription = mediaDescription;
  45 + }
  46 +}
src/main/java/com/genersoft/iot/vmp/gb28181/bean/GbStream.java
@@ -10,7 +10,7 @@ import io.swagger.v3.oas.annotations.media.Schema; @@ -10,7 +10,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
10 public class GbStream extends PlatformGbStream{ 10 public class GbStream extends PlatformGbStream{
11 11
12 @Schema(description = "ID") 12 @Schema(description = "ID")
13 - private Integer gbStreamId; 13 + private int gbStreamId;
14 @Schema(description = "应用名") 14 @Schema(description = "应用名")
15 private String app; 15 private String app;
16 @Schema(description = "流ID") 16 @Schema(description = "流ID")
src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java
@@ -183,12 +183,6 @@ public class ParentPlatform { @@ -183,12 +183,6 @@ public class ParentPlatform {
183 @Schema(description = "创建时间") 183 @Schema(description = "创建时间")
184 private String createTime; 184 private String createTime;
185 185
186 - /**  
187 - * 树类型 国标规定了两种树的展现方式 行政区划 CivilCode 和业务分组:BusinessGroup  
188 - */  
189 - @Schema(description = "树类型 国标规定了两种树的展现方式 行政区划 CivilCode 和业务分组:BusinessGrou")  
190 - private String treeType;  
191 -  
192 @Schema(description = "是否作为消息通道") 186 @Schema(description = "是否作为消息通道")
193 private boolean asMessageChannel; 187 private boolean asMessageChannel;
194 188
@@ -424,14 +418,6 @@ public class ParentPlatform { @@ -424,14 +418,6 @@ public class ParentPlatform {
424 this.createTime = createTime; 418 this.createTime = createTime;
425 } 419 }
426 420
427 - public String getTreeType() {  
428 - return treeType;  
429 - }  
430 -  
431 - public void setTreeType(String treeType) {  
432 - this.treeType = treeType;  
433 - }  
434 -  
435 public boolean isAsMessageChannel() { 421 public boolean isAsMessageChannel() {
436 return asMessageChannel; 422 return asMessageChannel;
437 } 423 }
src/main/java/com/genersoft/iot/vmp/gb28181/bean/PlatformGbStream.java
@@ -5,7 +5,7 @@ import io.swagger.v3.oas.annotations.media.Schema; @@ -5,7 +5,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
5 public class PlatformGbStream { 5 public class PlatformGbStream {
6 6
7 @Schema(description = "ID") 7 @Schema(description = "ID")
8 - private Integer gbStreamId; 8 + private int gbStreamId;
9 9
10 @Schema(description = "平台ID") 10 @Schema(description = "平台ID")
11 private String platformId; 11 private String platformId;
src/main/java/com/genersoft/iot/vmp/gb28181/bean/TreeType.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.gb28181.bean;  
2 -  
3 -/**  
4 - * 目录结构类型  
5 - * @author lin  
6 - */  
7 -public class TreeType {  
8 - public static final String BUSINESS_GROUP = "BusinessGroup";  
9 - public static final String CIVIL_CODE = "CivilCode";  
10 -}  
src/main/java/com/genersoft/iot/vmp/gb28181/session/SSRCFactory.java
1 package com.genersoft.iot.vmp.gb28181.session; 1 package com.genersoft.iot.vmp.gb28181.session;
2 2
3 import com.genersoft.iot.vmp.conf.SipConfig; 3 import com.genersoft.iot.vmp.conf.SipConfig;
  4 +import com.genersoft.iot.vmp.conf.UserSetting;
4 import org.springframework.beans.factory.annotation.Autowired; 5 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.data.redis.core.StringRedisTemplate; 6 import org.springframework.data.redis.core.StringRedisTemplate;
6 import org.springframework.stereotype.Component; 7 import org.springframework.stereotype.Component;
@@ -31,10 +32,13 @@ public class SSRCFactory { @@ -31,10 +32,13 @@ public class SSRCFactory {
31 @Autowired 32 @Autowired
32 private SipConfig sipConfig; 33 private SipConfig sipConfig;
33 34
  35 + @Autowired
  36 + private UserSetting userSetting;
  37 +
34 38
35 public void initMediaServerSSRC(String mediaServerId, Set<String> usedSet) { 39 public void initMediaServerSSRC(String mediaServerId, Set<String> usedSet) {
36 String ssrcPrefix = sipConfig.getDomain().substring(3, 8); 40 String ssrcPrefix = sipConfig.getDomain().substring(3, 8);
37 - String redisKey = SSRC_INFO_KEY + mediaServerId; 41 + String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId;
38 List<String> ssrcList = new ArrayList<>(); 42 List<String> ssrcList = new ArrayList<>();
39 for (int i = 1; i < MAX_STREAM_COUNT; i++) { 43 for (int i = 1; i < MAX_STREAM_COUNT; i++) {
40 String ssrc = String.format("%s%04d", ssrcPrefix, i); 44 String ssrc = String.format("%s%04d", ssrcPrefix, i);
@@ -77,7 +81,7 @@ public class SSRCFactory { @@ -77,7 +81,7 @@ public class SSRCFactory {
77 return; 81 return;
78 } 82 }
79 String sn = ssrc.substring(1); 83 String sn = ssrc.substring(1);
80 - String redisKey = SSRC_INFO_KEY + mediaServerId; 84 + String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId;
81 redisTemplate.opsForSet().add(redisKey, sn); 85 redisTemplate.opsForSet().add(redisKey, sn);
82 } 86 }
83 87
@@ -86,7 +90,7 @@ public class SSRCFactory { @@ -86,7 +90,7 @@ public class SSRCFactory {
86 */ 90 */
87 private String getSN(String mediaServerId) { 91 private String getSN(String mediaServerId) {
88 String sn = null; 92 String sn = null;
89 - String redisKey = SSRC_INFO_KEY + mediaServerId; 93 + String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId;
90 Long size = redisTemplate.opsForSet().size(redisKey); 94 Long size = redisTemplate.opsForSet().size(redisKey);
91 if (size == null || size == 0) { 95 if (size == null || size == 0) {
92 throw new RuntimeException("ssrc已经用完"); 96 throw new RuntimeException("ssrc已经用完");
@@ -113,20 +117,8 @@ public class SSRCFactory { @@ -113,20 +117,8 @@ public class SSRCFactory {
113 * @param mediaServerId 流媒体服务ID 117 * @param mediaServerId 流媒体服务ID
114 */ 118 */
115 public boolean hasMediaServerSSRC(String mediaServerId) { 119 public boolean hasMediaServerSSRC(String mediaServerId) {
116 - String redisKey = SSRC_INFO_KEY + mediaServerId; 120 + String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId;
117 return redisTemplate.opsForSet().members(redisKey) != null; 121 return redisTemplate.opsForSet().members(redisKey) != null;
118 } 122 }
119 123
120 - /**  
121 - * 查询ssrc是否可用  
122 - *  
123 - * @param mediaServerId  
124 - * @param ssrc  
125 - * @return  
126 - */  
127 - public boolean checkSsrc(String mediaServerId, String ssrc) {  
128 - String sn = ssrc.substring(1);  
129 - String redisKey = SSRC_INFO_KEY + mediaServerId;  
130 - return redisTemplate.opsForSet().isMember(redisKey, sn) != null;  
131 - }  
132 } 124 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
@@ -39,16 +39,22 @@ public class DeferredResultHolder { @@ -39,16 +39,22 @@ public class DeferredResultHolder {
39 39
40 public static final String CALLBACK_CMD_DOWNLOAD = "CALLBACK_DOWNLOAD"; 40 public static final String CALLBACK_CMD_DOWNLOAD = "CALLBACK_DOWNLOAD";
41 41
  42 + public static final String CALLBACK_CMD_PROXY = "CALLBACK_PROXY";
  43 +
42 public static final String CALLBACK_CMD_STOP = "CALLBACK_STOP"; 44 public static final String CALLBACK_CMD_STOP = "CALLBACK_STOP";
43 45
44 public static final String UPLOAD_FILE_CHANNEL = "UPLOAD_FILE_CHANNEL"; 46 public static final String UPLOAD_FILE_CHANNEL = "UPLOAD_FILE_CHANNEL";
45 47
46 - public static final String CALLBACK_CMD_MOBILEPOSITION = "CALLBACK_MOBILEPOSITION"; 48 + public static final String CALLBACK_CMD_MOBILE_POSITION = "CALLBACK_CMD_MOBILE_POSITION";
47 49
48 public static final String CALLBACK_CMD_PRESETQUERY = "CALLBACK_PRESETQUERY"; 50 public static final String CALLBACK_CMD_PRESETQUERY = "CALLBACK_PRESETQUERY";
49 51
50 public static final String CALLBACK_CMD_ALARM = "CALLBACK_ALARM"; 52 public static final String CALLBACK_CMD_ALARM = "CALLBACK_ALARM";
51 53
  54 + public static final String CALLBACK_CMD_BROADCAST = "CALLBACK_BROADCAST";
  55 +
  56 + public static final String CALLBACK_CMD_SNAP= "CALLBACK_SNAP";
  57 +
52 private Map<String, Map<String, DeferredResultEx>> map = new ConcurrentHashMap<>(); 58 private Map<String, Map<String, DeferredResultEx>> map = new ConcurrentHashMap<>();
53 59
54 60
@@ -149,4 +155,6 @@ public class DeferredResultHolder { @@ -149,4 +155,6 @@ public class DeferredResultHolder {
149 map.remove(msg.getKey()); 155 map.remove(msg.getKey());
150 } 156 }
151 } 157 }
  158 +
  159 +
152 } 160 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
@@ -80,7 +80,7 @@ public interface ISIPCommanderForPlatform { @@ -80,7 +80,7 @@ public interface ISIPCommanderForPlatform {
80 * @param fromTag 80 * @param fromTag
81 * @return 81 * @return
82 */ 82 */
83 - void deviceStatusResponse(ParentPlatform parentPlatform,String channelId, String sn, String fromTag,int status) throws SipException, InvalidArgumentException, ParseException ; 83 + void deviceStatusResponse(ParentPlatform parentPlatform,String channelId, String sn, String fromTag,boolean status) throws SipException, InvalidArgumentException, ParseException;
84 84
85 /** 85 /**
86 * 向上级回复移动位置订阅消息 86 * 向上级回复移动位置订阅消息
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
@@ -55,8 +55,8 @@ public class SIPRequestHeaderPlarformProvider { @@ -55,8 +55,8 @@ public class SIPRequestHeaderPlarformProvider {
55 parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort()); 55 parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort());
56 //via 56 //via
57 ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); 57 ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
58 - ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(parentPlatform.getServerIP(),  
59 - parentPlatform.getServerPort(), parentPlatform.getTransport(), SipUtils.getNewViaTag()); 58 + ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(parentPlatform.getDeviceIp(),
  59 + Integer.parseInt(parentPlatform.getDevicePort()), parentPlatform.getTransport(), SipUtils.getNewViaTag());
60 viaHeader.setRPort(); 60 viaHeader.setRPort();
61 viaHeaders.add(viaHeader); 61 viaHeaders.add(viaHeader);
62 //from 62 //from
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
1 package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl; 1 package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
2 2
3 -import com.alibaba.fastjson2.JSONObject;  
4 import com.genersoft.iot.vmp.common.InviteSessionType; 3 import com.genersoft.iot.vmp.common.InviteSessionType;
5 import com.genersoft.iot.vmp.common.StreamInfo; 4 import com.genersoft.iot.vmp.common.StreamInfo;
6 import com.genersoft.iot.vmp.conf.SipConfig; 5 import com.genersoft.iot.vmp.conf.SipConfig;
7 import com.genersoft.iot.vmp.conf.UserSetting; 6 import com.genersoft.iot.vmp.conf.UserSetting;
8 import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; 7 import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
9 import com.genersoft.iot.vmp.gb28181.SipLayer; 8 import com.genersoft.iot.vmp.gb28181.SipLayer;
10 -import com.genersoft.iot.vmp.gb28181.bean.*; 9 +import com.genersoft.iot.vmp.gb28181.bean.Device;
  10 +import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
  11 +import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
11 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 12 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
12 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; 13 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
13 import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; 14 import com.genersoft.iot.vmp.gb28181.transmit.SIPSender;
@@ -21,6 +22,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; @@ -21,6 +22,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
21 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; 22 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
22 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamPush; 23 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamPush;
23 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 24 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  25 +import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam;
24 import com.genersoft.iot.vmp.service.IMediaServerService; 26 import com.genersoft.iot.vmp.service.IMediaServerService;
25 import com.genersoft.iot.vmp.service.bean.SSRCInfo; 27 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
26 import com.genersoft.iot.vmp.utils.DateUtil; 28 import com.genersoft.iot.vmp.utils.DateUtil;
@@ -155,6 +157,11 @@ public class SIPCommander implements ISIPCommander { @@ -155,6 +157,11 @@ public class SIPCommander implements ISIPCommander {
155 builder.append(strTmp, 0, 2); 157 builder.append(strTmp, 0, 2);
156 strTmp = String.format("%02X", parameter2); 158 strTmp = String.format("%02X", parameter2);
157 builder.append(strTmp, 0, 2); 159 builder.append(strTmp, 0, 2);
  160 + //优化zoom变倍速率
  161 + if ((combineCode2 > 0) && (combineCode2 <16))
  162 + {
  163 + combineCode2 = 16;
  164 + }
158 strTmp = String.format("%X", combineCode2); 165 strTmp = String.format("%X", combineCode2);
159 builder.append(strTmp, 0, 1).append("0"); 166 builder.append(strTmp, 0, 1).append("0");
160 //计算校验码 167 //计算校验码
@@ -280,9 +287,9 @@ public class SIPCommander implements ISIPCommander { @@ -280,9 +287,9 @@ public class SIPCommander implements ISIPCommander {
280 287
281 logger.info("{} 分配的ZLM为: {} [{}:{}]", stream, mediaServerItem.getId(), mediaServerItem.getSdpIp(), ssrcInfo.getPort()); 288 logger.info("{} 分配的ZLM为: {} [{}:{}]", stream, mediaServerItem.getId(), mediaServerItem.getSdpIp(), ssrcInfo.getPort());
282 HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId()); 289 HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId());
283 - subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json) -> { 290 + subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, HookParam hookParam) -> {
284 if (event != null) { 291 if (event != null) {
285 - event.response(mediaServerItemInUse, json); 292 + event.response(mediaServerItemInUse, hookParam);
286 subscribe.removeSubscribe(hookSubscribe); 293 subscribe.removeSubscribe(hookSubscribe);
287 } 294 }
288 }); 295 });
@@ -345,6 +352,22 @@ public class SIPCommander implements ISIPCommander { @@ -345,6 +352,22 @@ public class SIPCommander implements ISIPCommander {
345 } 352 }
346 } 353 }
347 354
  355 + if( device.isSwitchPrimarySubStream() ){
  356 + if("TP-LINK".equals(device.getManufacturer())){
  357 + if (device.isSwitchPrimarySubStream()){
  358 + content.append("a=streamMode:sub\r\n");
  359 + }else {
  360 + content.append("a=streamMode:main\r\n");
  361 + }
  362 + }else {
  363 + if (device.isSwitchPrimarySubStream()){
  364 + content.append("a=streamprofile:1\r\n");
  365 + }else {
  366 + content.append("a=streamprofile:0\r\n");
  367 + }
  368 + }
  369 + }
  370 +
348 content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc 371 content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc
349 // f字段:f= v/编码格式/分辨率/帧率/码率类型/码率大小a/编码格式/码率大小/采样率 372 // f字段:f= v/编码格式/分辨率/帧率/码率类型/码率大小a/编码格式/码率大小/采样率
350 // content.append("f=v/2/5/25/1/4000a/1/8/1" + "\r\n"); // 未发现支持此特性的设备 373 // content.append("f=v/2/5/25/1/4000a/1/8/1" + "\r\n"); // 未发现支持此特性的设备
@@ -360,7 +383,8 @@ public class SIPCommander implements ISIPCommander { @@ -360,7 +383,8 @@ public class SIPCommander implements ISIPCommander {
360 // 这里为例避免一个通道的点播只有一个callID这个参数使用一个固定值 383 // 这里为例避免一个通道的点播只有一个callID这个参数使用一个固定值
361 ResponseEvent responseEvent = (ResponseEvent) e.event; 384 ResponseEvent responseEvent = (ResponseEvent) e.event;
362 SIPResponse response = (SIPResponse) responseEvent.getResponse(); 385 SIPResponse response = (SIPResponse) responseEvent.getResponse();
363 - streamSession.put(device.getDeviceId(), channelId, "play", stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), response, InviteSessionType.PLAY); 386 + streamSession.put(device.getDeviceId(), channelId, "play", stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), response,
  387 + InviteSessionType.PLAY);
364 okEvent.response(e); 388 okEvent.response(e);
365 }); 389 });
366 } 390 }
@@ -450,13 +474,13 @@ public class SIPCommander implements ISIPCommander { @@ -450,13 +474,13 @@ public class SIPCommander implements ISIPCommander {
450 474
451 HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId()); 475 HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId());
452 // 添加订阅 476 // 添加订阅
453 - subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json) -> { 477 + subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, HookParam hookParam) -> {
454 if (hookEvent != null) { 478 if (hookEvent != null) {
455 - hookEvent.response(mediaServerItemInUse, json); 479 + hookEvent.response(mediaServerItemInUse, hookParam);
456 } 480 }
457 subscribe.removeSubscribe(hookSubscribe); 481 subscribe.removeSubscribe(hookSubscribe);
458 }); 482 });
459 - Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()), ssrcInfo.getSsrc()); 483 + Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()), ssrcInfo.getSsrc());
460 484
461 sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, event -> { 485 sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, event -> {
462 ResponseEvent responseEvent = (ResponseEvent) event.event; 486 ResponseEvent responseEvent = (ResponseEvent) event.event;
@@ -553,15 +577,15 @@ public class SIPCommander implements ISIPCommander { @@ -553,15 +577,15 @@ public class SIPCommander implements ISIPCommander {
553 // 添加订阅 577 // 添加订阅
554 CallIdHeader newCallIdHeader = sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()), device.getTransport()); 578 CallIdHeader newCallIdHeader = sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()), device.getTransport());
555 String callId= newCallIdHeader.getCallId(); 579 String callId= newCallIdHeader.getCallId();
556 - subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json) -> { 580 + subscribe.addSubscribe(hookSubscribe, (mediaServerItemInUse, hookParam) -> {
557 logger.debug("sipc 添加订阅===callId {}",callId); 581 logger.debug("sipc 添加订阅===callId {}",callId);
558 - hookEvent.response(mediaServerItemInUse, json); 582 + hookEvent.response(mediaServerItemInUse, hookParam);
559 subscribe.removeSubscribe(hookSubscribe); 583 subscribe.removeSubscribe(hookSubscribe);
560 hookSubscribe.getContent().put("regist", false); 584 hookSubscribe.getContent().put("regist", false);
561 hookSubscribe.getContent().put("schema", "rtsp"); 585 hookSubscribe.getContent().put("schema", "rtsp");
562 // 添加流注销的订阅,注销了后向设备发送bye 586 // 添加流注销的订阅,注销了后向设备发送bye
563 subscribe.addSubscribe(hookSubscribe, 587 subscribe.addSubscribe(hookSubscribe,
564 - (MediaServerItem mediaServerItemForEnd, JSONObject jsonForEnd) -> { 588 + (mediaServerItemForEnd, hookParam1) -> {
565 logger.info("[录像]下载结束, 发送BYE"); 589 logger.info("[录像]下载结束, 发送BYE");
566 try { 590 try {
567 streamByeCmd(device, channelId, ssrcInfo.getStream(), callId); 591 streamByeCmd(device, channelId, ssrcInfo.getStream(), callId);
@@ -572,17 +596,13 @@ public class SIPCommander implements ISIPCommander { @@ -572,17 +596,13 @@ public class SIPCommander implements ISIPCommander {
572 }); 596 });
573 }); 597 });
574 598
575 - Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, SipUtils.getNewFromTag(), null,newCallIdHeader, ssrcInfo.getSsrc()); 599 + Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,newCallIdHeader, ssrcInfo.getSsrc());
576 600
577 sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, event -> { 601 sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, event -> {
578 ResponseEvent responseEvent = (ResponseEvent) event.event; 602 ResponseEvent responseEvent = (ResponseEvent) event.event;
579 SIPResponse response = (SIPResponse) responseEvent.getResponse(); 603 SIPResponse response = (SIPResponse) responseEvent.getResponse();
580 String contentString =new String(response.getRawContent()); 604 String contentString =new String(response.getRawContent());
581 - int ssrcIndex = contentString.indexOf("y=");  
582 - String ssrc=ssrcInfo.getSsrc();  
583 - if (ssrcIndex >= 0) {  
584 - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);  
585 - } 605 + String ssrc = SipUtils.getSsrcFromSdp(contentString);
586 streamSession.put(device.getDeviceId(), channelId, response.getCallIdHeader().getCallId(), ssrcInfo.getStream(), ssrc, mediaServerItem.getId(), response, InviteSessionType.DOWNLOAD); 606 streamSession.put(device.getDeviceId(), channelId, response.getCallIdHeader().getCallId(), ssrcInfo.getStream(), ssrc, mediaServerItem.getId(), response, InviteSessionType.DOWNLOAD);
587 okEvent.response(event); 607 okEvent.response(event);
588 }); 608 });
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
@@ -230,59 +230,150 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -230,59 +230,150 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
230 // 行政区划分组只需要这两项就可以 230 // 行政区划分组只需要这两项就可以
231 catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n"); 231 catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n");
232 catalogXml.append("<Name>" + channel.getName() + "</Name>\r\n"); 232 catalogXml.append("<Name>" + channel.getName() + "</Name>\r\n");
233 - if (channel.getParentId() != null) {  
234 - // 业务分组加上这一项即可,提高兼容性,  
235 - catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n");  
236 -// catalogXml.append("<ParentID>" + parentPlatform.getDeviceGBId() + "/" + channel.getParentId() + "</ParentID>\r\n");  
237 - }  
238 - if (channel.getChannelId().length() == 20 && Integer.parseInt(channel.getChannelId().substring(10, 13)) == 216) {  
239 - // 虚拟组织增加BusinessGroupID字段  
240 - catalogXml.append("<BusinessGroupID>" + channel.getParentId() + "</BusinessGroupID>\r\n");  
241 - }  
242 - if (!channel.getChannelId().equals(parentPlatform.getDeviceGBId())) {  
243 - catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n");  
244 - if (channel.getParental() == 0) {  
245 - catalogXml.append("<Status>" + (channel.getStatus() == 0 ? "OFF" : "ON") + "</Status>\r\n"); 233 + if (channel.getChannelId().length() <= 8) {
  234 + catalogXml.append("</Item>\r\n");
  235 + continue;
  236 + }else {
  237 + if (channel.getChannelId().length() != 20) {
  238 + catalogXml.append("</Item>\r\n");
  239 + continue;
246 } 240 }
247 - }  
248 - if (channel.getParental() == 0) {  
249 - // 通道项  
250 - catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n");  
251 - catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");  
252 - catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n");  
253 - String civilCode = channel.getCivilCode() == null?parentPlatform.getAdministrativeDivision() : channel.getCivilCode();  
254 - if (channel.getChannelType() != 2) { // 业务分组/虚拟组织/行政区划 不设置以下属性  
255 - catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n");  
256 - catalogXml.append("<Owner>" + parentPlatform.getDeviceGBId()+ "</Owner>\r\n");  
257 - catalogXml.append("<CivilCode>" + civilCode + "</CivilCode>\r\n");  
258 - if (channel.getAddress() == null) {  
259 - catalogXml.append("<Address></Address>\r\n");  
260 - }else {  
261 - catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n");  
262 - }  
263 - catalogXml.append("<Block>" + channel.getBlock() + "</Block>\r\n");  
264 - catalogXml.append("<SafetyWay>" + channel.getSafetyWay() + "</SafetyWay>\r\n");  
265 - catalogXml.append("<CertNum>" + channel.getCertNum() + "</CertNum>\r\n");  
266 - catalogXml.append("<Certifiable>" + channel.getCertifiable() + "</Certifiable>\r\n");  
267 - catalogXml.append("<ErrCode>" + channel.getErrCode() + "</ErrCode>\r\n");  
268 - catalogXml.append("<EndTime>" + channel.getEndTime() + "</EndTime>\r\n");  
269 - catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");  
270 - catalogXml.append("<IPAddress>" + channel.getIpAddress() + "</IPAddress>\r\n");  
271 - catalogXml.append("<Port>" + channel.getPort() + "</Port>\r\n");  
272 - catalogXml.append("<Password>" + channel.getPort() + "</Password>\r\n");  
273 - catalogXml.append("<PTZType>" + channel.getPTZType() + "</PTZType>\r\n");  
274 - catalogXml.append("<Status>" + (channel.getStatus() == 1?"ON":"OFF") + "</Status>\r\n");  
275 - catalogXml.append("<Longitude>" +  
276 - (channel.getLongitudeWgs84() != 0? channel.getLongitudeWgs84():channel.getLongitude())  
277 - + "</Longitude>\r\n");  
278 - catalogXml.append("<Latitude>" +  
279 - (channel.getLatitudeWgs84() != 0? channel.getLatitudeWgs84():channel.getLatitude())  
280 - + "</Latitude>\r\n");  
281 - 241 + switch (Integer.parseInt(channel.getChannelId().substring(10, 13))){
  242 + case 200:
  243 +// catalogXml.append("<Manufacturer>三永华通</Manufacturer>\r\n");
  244 +// GitUtil gitUtil = SpringBeanFactory.getBean("gitUtil");
  245 +// String model = (gitUtil == null || gitUtil.getBuildVersion() == null)?"1.0": gitUtil.getBuildVersion();
  246 +// catalogXml.append("<Model>" + model + "</Manufacturer>\r\n");
  247 +// catalogXml.append("<Owner>三永华通</Owner>\r\n");
  248 + if (channel.getCivilCode() != null) {
  249 + catalogXml.append("<CivilCode>"+channel.getCivilCode()+"</CivilCode>\r\n");
  250 + }else {
  251 + catalogXml.append("<CivilCode></CivilCode>\r\n");
  252 + }
  253 +
  254 + catalogXml.append("<RegisterWay>1</RegisterWay>\r\n");
  255 + catalogXml.append("<Secrecy>0</Secrecy>\r\n");
  256 + break;
  257 + case 215:
  258 + if (!ObjectUtils.isEmpty(channel.getParentId())) {
  259 + catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n");
  260 + }
  261 +
  262 + break;
  263 + case 216:
  264 + if (!ObjectUtils.isEmpty(channel.getParentId())) {
  265 + catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n");
  266 + }else {
  267 + catalogXml.append("<ParentID></ParentID>\r\n");
  268 + }
  269 + if (!ObjectUtils.isEmpty(channel.getBusinessGroupId())) {
  270 + catalogXml.append("<BusinessGroupID>" + channel.getBusinessGroupId() + "</BusinessGroupID>\r\n");
  271 + }else {
  272 + catalogXml.append("<BusinessGroupID></BusinessGroupID>\r\n");
  273 + }
  274 + break;
  275 + default:
  276 + // 通道项
  277 + if (channel.getManufacture() != null) {
  278 + catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n");
  279 + }else {
  280 + catalogXml.append("<Manufacturer></Manufacturer>\r\n");
  281 + }
  282 + if (channel.getSecrecy() != null) {
  283 + catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
  284 + }else {
  285 + catalogXml.append("<Secrecy></Secrecy>\r\n");
  286 + }
  287 + catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n");
  288 + if (channel.getModel() != null) {
  289 + catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n");
  290 + }else {
  291 + catalogXml.append("<Model></Model>\r\n");
  292 + }
  293 + if (channel.getOwner() != null) {
  294 + catalogXml.append("<Owner>" + channel.getOwner()+ "</Owner>\r\n");
  295 + }else {
  296 + catalogXml.append("<Owner></Owner>\r\n");
  297 + }
  298 + if (channel.getCivilCode() != null) {
  299 + catalogXml.append("<CivilCode>" + channel.getCivilCode() + "</CivilCode>\r\n");
  300 + }else {
  301 + catalogXml.append("<CivilCode></CivilCode>\r\n");
  302 + }
  303 + if (channel.getAddress() == null) {
  304 + catalogXml.append("<Address></Address>\r\n");
  305 + }else {
  306 + catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n");
  307 + }
  308 + if (!ObjectUtils.isEmpty(channel.getParentId())) {
  309 + catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n");
  310 + }else {
  311 + catalogXml.append("<ParentID></ParentID>\r\n");
  312 + }
  313 + if (!ObjectUtils.isEmpty(channel.getBlock())) {
  314 + catalogXml.append("<Block>" + channel.getBlock() + "</Block>\r\n");
  315 + }else {
  316 + catalogXml.append("<Block></Block>\r\n");
  317 + }
  318 + if (!ObjectUtils.isEmpty(channel.getSafetyWay())) {
  319 + catalogXml.append("<SafetyWay>" + channel.getSafetyWay() + "</SafetyWay>\r\n");
  320 + }else {
  321 + catalogXml.append("<SafetyWay></SafetyWay>\r\n");
  322 + }
  323 + if (!ObjectUtils.isEmpty(channel.getCertNum())) {
  324 + catalogXml.append("<CertNum>" + channel.getCertNum() + "</CertNum>\r\n");
  325 + }else {
  326 + catalogXml.append("<CertNum></CertNum>\r\n");
  327 + }
  328 + if (!ObjectUtils.isEmpty(channel.getCertifiable())) {
  329 + catalogXml.append("<Certifiable>" + channel.getCertifiable() + "</Certifiable>\r\n");
  330 + }else {
  331 + catalogXml.append("<Certifiable></Certifiable>\r\n");
  332 + }
  333 + if (!ObjectUtils.isEmpty(channel.getErrCode())) {
  334 + catalogXml.append("<ErrCode>" + channel.getErrCode() + "</ErrCode>\r\n");
  335 + }else {
  336 + catalogXml.append("<ErrCode></ErrCode>\r\n");
  337 + }
  338 + if (!ObjectUtils.isEmpty(channel.getEndTime())) {
  339 + catalogXml.append("<EndTime>" + channel.getEndTime() + "</EndTime>\r\n");
  340 + }else {
  341 + catalogXml.append("<EndTime></EndTime>\r\n");
  342 + }
  343 + if (!ObjectUtils.isEmpty(channel.getSecrecy())) {
  344 + catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
  345 + }else {
  346 + catalogXml.append("<Secrecy></Secrecy>\r\n");
  347 + }
  348 + if (!ObjectUtils.isEmpty(channel.getIpAddress())) {
  349 + catalogXml.append("<IPAddress>" + channel.getIpAddress() + "</IPAddress>\r\n");
  350 + }else {
  351 + catalogXml.append("<IPAddress></IPAddress>\r\n");
  352 + }
  353 + catalogXml.append("<Port>" + channel.getPort() + "</Port>\r\n");
  354 + if (!ObjectUtils.isEmpty(channel.getPassword())) {
  355 + catalogXml.append("<Password>" + channel.getPassword() + "</Password>\r\n");
  356 + }else {
  357 + catalogXml.append("<Password></Password>\r\n");
  358 + }
  359 + if (!ObjectUtils.isEmpty(channel.getPTZType())) {
  360 + catalogXml.append("<PTZType>" + channel.getPTZType() + "</PTZType>\r\n");
  361 + }else {
  362 + catalogXml.append("<PTZType></PTZType>\r\n");
  363 + }
  364 + catalogXml.append("<Status>" + (channel.isStatus() ?"ON":"OFF") + "</Status>\r\n");
  365 +
  366 + catalogXml.append("<Longitude>" +
  367 + (channel.getLongitudeWgs84() != 0? channel.getLongitudeWgs84():channel.getLongitude())
  368 + + "</Longitude>\r\n");
  369 + catalogXml.append("<Latitude>" +
  370 + (channel.getLatitudeWgs84() != 0? channel.getLatitudeWgs84():channel.getLatitude())
  371 + + "</Latitude>\r\n");
  372 + break;
282 373
283 } 374 }
  375 + catalogXml.append("</Item>\r\n");
284 } 376 }
285 - catalogXml.append("</Item>\r\n");  
286 } 377 }
287 } 378 }
288 379
@@ -399,11 +490,11 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -399,11 +490,11 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
399 * @return 490 * @return
400 */ 491 */
401 @Override 492 @Override
402 - public void deviceStatusResponse(ParentPlatform parentPlatform,String channelId, String sn, String fromTag,int status) throws SipException, InvalidArgumentException, ParseException { 493 + public void deviceStatusResponse(ParentPlatform parentPlatform,String channelId, String sn, String fromTag,boolean status) throws SipException, InvalidArgumentException, ParseException {
403 if (parentPlatform == null) { 494 if (parentPlatform == null) {
404 return ; 495 return ;
405 } 496 }
406 - String statusStr = (status==1)?"ONLINE":"OFFLINE"; 497 + String statusStr = (status)?"ONLINE":"OFFLINE";
407 String characterSet = parentPlatform.getCharacterSet(); 498 String characterSet = parentPlatform.getCharacterSet();
408 StringBuffer deviceStatusXml = new StringBuffer(600); 499 StringBuffer deviceStatusXml = new StringBuffer(600);
409 deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n") 500 deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n")
@@ -564,7 +655,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -564,7 +655,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
564 catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n") 655 catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n")
565 .append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n") 656 .append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n")
566 .append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n") 657 .append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n")
567 - .append("<Status>" + (channel.getStatus() == 0 ? "OFF" : "ON") + "</Status>\r\n"); 658 + .append("<Status>" + (channel.isStatus() ? "ON" : "OFF") + "</Status>\r\n");
568 659
569 if (channel.getChannelType() != 2) { // 业务分组/虚拟组织/行政区划 不设置以下属性 660 if (channel.getChannelType() != 2) { // 业务分组/虚拟组织/行政区划 不设置以下属性
570 catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n") 661 catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n")
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
@@ -166,9 +166,8 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In @@ -166,9 +166,8 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
166 streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlay.getStream()); 166 streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlay.getStream());
167 } 167 }
168 InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId); 168 InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
169 - 169 + inviteStreamService.removeInviteInfo(inviteInfo);
170 if (inviteInfo != null) { 170 if (inviteInfo != null) {
171 - inviteStreamService.removeInviteInfo(inviteInfo);  
172 if (inviteInfo.getStreamInfo() != null) { 171 if (inviteInfo.getStreamInfo() != null) {
173 mediaServerService.closeRTPServer(inviteInfo.getStreamInfo().getMediaServerId(), inviteInfo.getStream()); 172 mediaServerService.closeRTPServer(inviteInfo.getStreamInfo().getMediaServerId(), inviteInfo.getStream());
174 } 173 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
@@ -22,11 +22,12 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; @@ -22,11 +22,12 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
22 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; 22 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
23 import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; 23 import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
24 import com.genersoft.iot.vmp.media.zlm.dto.*; 24 import com.genersoft.iot.vmp.media.zlm.dto.*;
  25 +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
25 import com.genersoft.iot.vmp.service.IMediaServerService; 26 import com.genersoft.iot.vmp.service.IMediaServerService;
26 import com.genersoft.iot.vmp.service.IPlayService; 27 import com.genersoft.iot.vmp.service.IPlayService;
27 import com.genersoft.iot.vmp.service.IStreamProxyService; 28 import com.genersoft.iot.vmp.service.IStreamProxyService;
28 import com.genersoft.iot.vmp.service.IStreamPushService; 29 import com.genersoft.iot.vmp.service.IStreamPushService;
29 -import com.genersoft.iot.vmp.service.bean.InviteErrorCallback; 30 +import com.genersoft.iot.vmp.service.bean.ErrorCallback;
30 import com.genersoft.iot.vmp.service.bean.InviteErrorCode; 31 import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
31 import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; 32 import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
32 import com.genersoft.iot.vmp.service.bean.SSRCInfo; 33 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
@@ -217,6 +218,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -217,6 +218,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
217 logger.error("[命令发送失败] invite GONE: {}", e.getMessage()); 218 logger.error("[命令发送失败] invite GONE: {}", e.getMessage());
218 } 219 }
219 return; 220 return;
  221 + }else {
  222 + // TODO 可能漏回复消息
220 } 223 }
221 } 224 }
222 } else { 225 } else {
@@ -270,18 +273,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -270,18 +273,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
270 // 解析sdp消息, 使用jainsip 自带的sdp解析方式 273 // 解析sdp消息, 使用jainsip 自带的sdp解析方式
271 String contentString = new String(request.getRawContent()); 274 String contentString = new String(request.getRawContent());
272 275
273 - // jainSip不支持y=字段, 移除以解析。  
274 - // 检查是否有y字段  
275 - int ssrcIndex = contentString.indexOf("y=");  
276 -  
277 - SessionDescription sdp;  
278 - if (ssrcIndex >= 0) {  
279 - //ssrc规定长度为10个字节,不取余下长度以避免后续还有“f=”字段  
280 - String substring = contentString.substring(0, ssrcIndex);  
281 - sdp = SdpFactory.getInstance().createSessionDescription(substring);  
282 - } else {  
283 - sdp = SdpFactory.getInstance().createSessionDescription(contentString);  
284 - } 276 + Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
  277 + SessionDescription sdp = gb28181Sdp.getBaseSdb();
285 String sessionName = sdp.getSessionName().getValue(); 278 String sessionName = sdp.getSessionName().getValue();
286 279
287 Long startTime = null; 280 Long startTime = null;
@@ -369,11 +362,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -369,11 +362,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
369 } 362 }
370 363
371 String ssrc; 364 String ssrc;
372 - if (userSetting.getUseCustomSsrcForParentInvite() || ssrcIndex < 0) { 365 + if (userSetting.getUseCustomSsrcForParentInvite() || gb28181Sdp.getSsrc() == null) {
373 // 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 366 // 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式
374 ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); 367 ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId());
375 - } else {  
376 - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); 368 + }else {
  369 + ssrc = gb28181Sdp.getSsrc();
377 } 370 }
378 String streamTypeStr = null; 371 String streamTypeStr = null;
379 if (mediaTransmissionTCP) { 372 if (mediaTransmissionTCP) {
@@ -406,8 +399,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -406,8 +399,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
406 399
407 Long finalStartTime = startTime; 400 Long finalStartTime = startTime;
408 Long finalStopTime = stopTime; 401 Long finalStopTime = stopTime;
409 - InviteErrorCallback<Object> hookEvent = (code, msg, data) -> {  
410 - StreamInfo streamInfo = (StreamInfo) data; 402 + ErrorCallback<Object> hookEvent = (code, msg, data) -> {
  403 + StreamInfo streamInfo = (StreamInfo)data;
411 MediaServerItem mediaServerItemInUSe = mediaServerService.getOne(streamInfo.getMediaServerId()); 404 MediaServerItem mediaServerItemInUSe = mediaServerService.getOne(streamInfo.getMediaServerId());
412 logger.info("[上级Invite]下级已经开始推流。 回复200OK(SDP), {}/{}", streamInfo.getApp(), streamInfo.getStream()); 405 logger.info("[上级Invite]下级已经开始推流。 回复200OK(SDP), {}/{}", streamInfo.getApp(), streamInfo.getStream());
413 // * 0 等待设备推流上来 406 // * 0 等待设备推流上来
@@ -460,7 +453,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -460,7 +453,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
460 logger.error("[命令发送失败] 国标级联 回复SdpAck", e); 453 logger.error("[命令发送失败] 国标级联 回复SdpAck", e);
461 } 454 }
462 }; 455 };
463 - InviteErrorCallback<Object> errorEvent = ((statusCode, msg, data) -> { 456 + ErrorCallback<Object> errorEvent = ((statusCode, msg, data) -> {
464 // 未知错误。直接转发设备点播的错误 457 // 未知错误。直接转发设备点播的错误
465 try { 458 try {
466 if (statusCode > 0) { 459 if (statusCode > 0) {
@@ -547,11 +540,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -547,11 +540,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
547 } else if (gbStream != null) { 540 } else if (gbStream != null) {
548 541
549 String ssrc; 542 String ssrc;
550 - if (userSetting.getUseCustomSsrcForParentInvite() || ssrcIndex < 0) { 543 + if (userSetting.getUseCustomSsrcForParentInvite() || gb28181Sdp.getSsrc() == null) {
551 // 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 544 // 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式
552 ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); 545 ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId());
553 - } else {  
554 - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); 546 + }else {
  547 + ssrc = gb28181Sdp.getSsrc();
555 } 548 }
556 549
557 if ("push".equals(gbStream.getStreamType())) { 550 if ("push".equals(gbStream.getStreamType())) {
@@ -690,10 +683,9 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -690,10 +683,9 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
690 logger.info("[ app={}, stream={} ]通道未推流,启用流后开始推流", gbStream.getApp(), gbStream.getStream()); 683 logger.info("[ app={}, stream={} ]通道未推流,启用流后开始推流", gbStream.getApp(), gbStream.getStream());
691 // 监听流上线 684 // 监听流上线
692 HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed(gbStream.getApp(), gbStream.getStream(), true, "rtsp", mediaServerItem.getId()); 685 HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed(gbStream.getApp(), gbStream.getStream(), true, "rtsp", mediaServerItem.getId());
693 - zlmHttpHookSubscribe.addSubscribe(hookSubscribe, (mediaServerItemInUSe, responseJSON) -> {  
694 - String app = responseJSON.getString("app");  
695 - String stream = responseJSON.getString("stream");  
696 - logger.info("[上级点播]拉流代理已经就绪, {}/{}", app, stream); 686 + zlmHttpHookSubscribe.addSubscribe(hookSubscribe, (mediaServerItemInUSe, hookParam) -> {
  687 + OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam)hookParam;
  688 + logger.info("[上级点播]拉流代理已经就绪, {}/{}", streamChangedHookParam.getApp(), streamChangedHookParam.getStream());
697 dynamicTask.stop(callIdHeader.getCallId()); 689 dynamicTask.stop(callIdHeader.getCallId());
698 pushProxyStream(evt, request, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive, 690 pushProxyStream(evt, request, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive,
699 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); 691 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
@@ -971,20 +963,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -971,20 +963,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
971 } 963 }
972 String contentString = new String(request.getRawContent()); 964 String contentString = new String(request.getRawContent());
973 // jainSip不支持y=字段, 移除移除以解析。 965 // jainSip不支持y=字段, 移除移除以解析。
974 - String substring = contentString;  
975 String ssrc = "0000000404"; 966 String ssrc = "0000000404";
976 - int ssrcIndex = contentString.indexOf("y=");  
977 - if (ssrcIndex > 0) {  
978 - substring = contentString.substring(0, ssrcIndex);  
979 - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12).trim();  
980 - }  
981 - ssrcIndex = substring.indexOf("f=");  
982 - if (ssrcIndex > 0) {  
983 - substring = contentString.substring(0, ssrcIndex);  
984 - }  
985 - try {  
986 - SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring);  
987 967
  968 + try {
  969 + Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
  970 + SessionDescription sdp = gb28181Sdp.getBaseSdb();
988 // 获取支持的格式 971 // 获取支持的格式
989 Vector mediaDescriptions = sdp.getMediaDescriptions(true); 972 Vector mediaDescriptions = sdp.getMediaDescriptions(true);
990 973
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java
1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
2 2
  3 +import com.genersoft.iot.vmp.conf.CivilCodeFileConf;
3 import com.genersoft.iot.vmp.conf.DynamicTask; 4 import com.genersoft.iot.vmp.conf.DynamicTask;
4 import com.genersoft.iot.vmp.conf.UserSetting; 5 import com.genersoft.iot.vmp.conf.UserSetting;
5 import com.genersoft.iot.vmp.gb28181.bean.Device; 6 import com.genersoft.iot.vmp.gb28181.bean.Device;
@@ -20,7 +21,10 @@ import org.springframework.stereotype.Component; @@ -20,7 +21,10 @@ import org.springframework.stereotype.Component;
20 21
21 import javax.sip.RequestEvent; 22 import javax.sip.RequestEvent;
22 import javax.sip.header.FromHeader; 23 import javax.sip.header.FromHeader;
23 -import java.util.*; 24 +import java.util.ArrayList;
  25 +import java.util.Iterator;
  26 +import java.util.List;
  27 +import java.util.Map;
24 import java.util.concurrent.ConcurrentHashMap; 28 import java.util.concurrent.ConcurrentHashMap;
25 import java.util.concurrent.CopyOnWriteArrayList; 29 import java.util.concurrent.CopyOnWriteArrayList;
26 30
@@ -56,6 +60,9 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent @@ -56,6 +60,9 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
56 @Autowired 60 @Autowired
57 private DynamicTask dynamicTask; 61 private DynamicTask dynamicTask;
58 62
  63 + @Autowired
  64 + private CivilCodeFileConf civilCodeFileConf;
  65 +
59 private final static String talkKey = "notify-request-for-catalog-task"; 66 private final static String talkKey = "notify-request-for-catalog-task";
60 67
61 public void process(RequestEvent evt) { 68 public void process(RequestEvent evt) {
@@ -65,7 +72,7 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent @@ -65,7 +72,7 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
65 String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader); 72 String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader);
66 73
67 Device device = redisCatchStorage.getDevice(deviceId); 74 Device device = redisCatchStorage.getDevice(deviceId);
68 - if (device == null || device.getOnline() == 0) { 75 + if (device == null || !device.isOnLine()) {
69 logger.warn("[收到目录订阅]:{}, 但是设备已经离线", (device != null ? device.getDeviceId():"" )); 76 logger.warn("[收到目录订阅]:{}, 但是设备已经离线", (device != null ? device.getDeviceId():"" ));
70 return; 77 return;
71 } 78 }
@@ -96,7 +103,7 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent @@ -96,7 +103,7 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
96 }else { 103 }else {
97 event = eventElement.getText().toUpperCase(); 104 event = eventElement.getText().toUpperCase();
98 } 105 }
99 - DeviceChannel channel = XmlUtil.channelContentHander(itemDevice, device, event); 106 + DeviceChannel channel = XmlUtil.channelContentHandler(itemDevice, device, event, civilCodeFileConf);
100 107
101 channel.setDeviceId(device.getDeviceId()); 108 channel.setDeviceId(device.getDeviceId());
102 logger.info("[收到目录订阅]:{}/{}", device.getDeviceId(), channel.getChannelId()); 109 logger.info("[收到目录订阅]:{}/{}", device.getDeviceId(), channel.getChannelId());
@@ -175,6 +182,11 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent @@ -175,6 +182,11 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
175 } 182 }
176 }else { 183 }else {
177 addChannelMap.put(channel.getChannelId(), channel); 184 addChannelMap.put(channel.getChannelId(), channel);
  185 + if (userSetting.getDeviceStatusNotify()) {
  186 + // 发送redis消息
  187 + redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), channel.getChannelId(), true);
  188 + }
  189 +
178 if (addChannelMap.keySet().size() > 300) { 190 if (addChannelMap.keySet().size() > 300) {
179 executeSaveForAdd(); 191 executeSaveForAdd();
180 } 192 }
@@ -185,6 +197,10 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent @@ -185,6 +197,10 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
185 // 删除 197 // 删除
186 logger.info("[收到删除通道通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId()); 198 logger.info("[收到删除通道通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId());
187 deleteChannelList.add(channel); 199 deleteChannelList.add(channel);
  200 + if (userSetting.getDeviceStatusNotify()) {
  201 + // 发送redis消息
  202 + redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), channel.getChannelId(), false);
  203 + }
188 if (deleteChannelList.size() > 300) { 204 if (deleteChannelList.size() > 300) {
189 executeSaveForDelete(); 205 executeSaveForDelete();
190 } 206 }
@@ -205,6 +221,10 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent @@ -205,6 +221,10 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
205 if (addChannelMap.keySet().size() > 300) { 221 if (addChannelMap.keySet().size() > 300) {
206 executeSaveForAdd(); 222 executeSaveForAdd();
207 } 223 }
  224 + if (userSetting.getDeviceStatusNotify()) {
  225 + // 发送redis消息
  226 + redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), channel.getChannelId(), true);
  227 + }
208 } 228 }
209 break; 229 break;
210 default: 230 default:
@@ -232,7 +252,6 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent @@ -232,7 +252,6 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
232 } 252 }
233 253
234 private void executeSave(){ 254 private void executeSave(){
235 - System.out.println("定时存储数据");  
236 executeSaveForUpdate(); 255 executeSaveForUpdate();
237 executeSaveForDelete(); 256 executeSaveForDelete();
238 executeSaveForOnline(); 257 executeSaveForOnline();
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java
1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
2 2
3 import com.alibaba.fastjson2.JSONObject; 3 import com.alibaba.fastjson2.JSONObject;
  4 +import com.genersoft.iot.vmp.conf.CivilCodeFileConf;
4 import com.genersoft.iot.vmp.conf.SipConfig; 5 import com.genersoft.iot.vmp.conf.SipConfig;
5 import com.genersoft.iot.vmp.conf.UserSetting; 6 import com.genersoft.iot.vmp.conf.UserSetting;
6 import com.genersoft.iot.vmp.gb28181.bean.*; 7 import com.genersoft.iot.vmp.gb28181.bean.*;
@@ -79,6 +80,9 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements @@ -79,6 +80,9 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
79 @Autowired 80 @Autowired
80 private NotifyRequestForCatalogProcessor notifyRequestForCatalogProcessor; 81 private NotifyRequestForCatalogProcessor notifyRequestForCatalogProcessor;
81 82
  83 + @Autowired
  84 + private CivilCodeFileConf civilCodeFileConf;
  85 +
82 private ConcurrentLinkedQueue<HandlerCatchData> taskQueue = new ConcurrentLinkedQueue<>(); 86 private ConcurrentLinkedQueue<HandlerCatchData> taskQueue = new ConcurrentLinkedQueue<>();
83 87
84 @Qualifier("taskExecutor") 88 @Qualifier("taskExecutor")
@@ -192,7 +196,12 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements @@ -192,7 +196,12 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
192 mobilePosition.setDeviceId(device.getDeviceId()); 196 mobilePosition.setDeviceId(device.getDeviceId());
193 mobilePosition.setChannelId(channelId); 197 mobilePosition.setChannelId(channelId);
194 String time = XmlUtil.getText(rootElement, "Time"); 198 String time = XmlUtil.getText(rootElement, "Time");
195 - mobilePosition.setTime(time); 199 + if (ObjectUtils.isEmpty(time)){
  200 + mobilePosition.setTime(DateUtil.getNow());
  201 + }else {
  202 + mobilePosition.setTime(SipUtils.parseTime(time));
  203 + }
  204 +
196 mobilePosition.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude"))); 205 mobilePosition.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude")));
197 mobilePosition.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude"))); 206 mobilePosition.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude")));
198 if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Speed"))) { 207 if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Speed"))) {
@@ -237,7 +246,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements @@ -237,7 +246,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
237 246
238 // 发送redis消息。 通知位置信息的变化 247 // 发送redis消息。 通知位置信息的变化
239 JSONObject jsonObject = new JSONObject(); 248 JSONObject jsonObject = new JSONObject();
240 - jsonObject.put("time", time); 249 + jsonObject.put("time", DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(mobilePosition.getTime()));
241 jsonObject.put("serial", deviceId); 250 jsonObject.put("serial", deviceId);
242 jsonObject.put("code", channelId); 251 jsonObject.put("code", channelId);
243 jsonObject.put("longitude", mobilePosition.getLongitude()); 252 jsonObject.put("longitude", mobilePosition.getLongitude());
@@ -339,7 +348,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements @@ -339,7 +348,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
339 storager.updateChannelPosition(deviceChannel); 348 storager.updateChannelPosition(deviceChannel);
340 // 发送redis消息。 通知位置信息的变化 349 // 发送redis消息。 通知位置信息的变化
341 JSONObject jsonObject = new JSONObject(); 350 JSONObject jsonObject = new JSONObject();
342 - jsonObject.put("time", mobilePosition.getTime()); 351 + jsonObject.put("time", DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(mobilePosition.getTime()));
343 jsonObject.put("serial", deviceChannel.getDeviceId()); 352 jsonObject.put("serial", deviceChannel.getDeviceId());
344 jsonObject.put("code", deviceChannel.getChannelId()); 353 jsonObject.put("code", deviceChannel.getChannelId());
345 jsonObject.put("longitude", mobilePosition.getLongitude()); 354 jsonObject.put("longitude", mobilePosition.getLongitude());
@@ -372,7 +381,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements @@ -372,7 +381,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
372 String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader); 381 String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader);
373 382
374 Device device = redisCatchStorage.getDevice(deviceId); 383 Device device = redisCatchStorage.getDevice(deviceId);
375 - if (device == null || device.getOnline() == 0) { 384 + if (device == null || !device.isOnLine()) {
376 logger.warn("[收到目录订阅]:{}, 但是设备已经离线", (device != null ? device.getDeviceId():"" )); 385 logger.warn("[收到目录订阅]:{}, 但是设备已经离线", (device != null ? device.getDeviceId():"" ));
377 return; 386 return;
378 } 387 }
@@ -403,7 +412,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements @@ -403,7 +412,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
403 }else { 412 }else {
404 event = eventElement.getText().toUpperCase(); 413 event = eventElement.getText().toUpperCase();
405 } 414 }
406 - DeviceChannel channel = XmlUtil.channelContentHander(itemDevice, device, event); 415 + DeviceChannel channel = XmlUtil.channelContentHandler(itemDevice, device, event, civilCodeFileConf);
407 channel.setDeviceId(device.getDeviceId()); 416 channel.setDeviceId(device.getDeviceId());
408 logger.info("[收到目录订阅]:{}/{}", device.getDeviceId(), channel.getChannelId()); 417 logger.info("[收到目录订阅]:{}/{}", device.getDeviceId(), channel.getChannelId());
409 switch (event) { 418 switch (event) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java
@@ -167,9 +167,8 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen @@ -167,9 +167,8 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
167 device.setStreamMode("UDP"); 167 device.setStreamMode("UDP");
168 device.setCharset("GB2312"); 168 device.setCharset("GB2312");
169 device.setGeoCoordSys("WGS84"); 169 device.setGeoCoordSys("WGS84");
170 - device.setTreeType("CivilCode");  
171 device.setDeviceId(deviceId); 170 device.setDeviceId(deviceId);
172 - device.setOnline(0); 171 + device.setOnLine(false);
173 } 172 }
174 device.setIp(remoteAddressInfo.getIp()); 173 device.setIp(remoteAddressInfo.getIp());
175 device.setPort(remoteAddressInfo.getPort()); 174 device.setPort(remoteAddressInfo.getPort());
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java
@@ -164,7 +164,7 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme @@ -164,7 +164,7 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
164 164
165 // 发送redis消息。 通知位置信息的变化 165 // 发送redis消息。 通知位置信息的变化
166 JSONObject jsonObject = new JSONObject(); 166 JSONObject jsonObject = new JSONObject();
167 - jsonObject.put("time", mobilePosition.getTime()); 167 + jsonObject.put("time", DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(mobilePosition.getTime()));
168 jsonObject.put("serial", deviceChannel.getDeviceId()); 168 jsonObject.put("serial", deviceChannel.getDeviceId());
169 jsonObject.put("code", deviceChannel.getChannelId()); 169 jsonObject.put("code", deviceChannel.getChannelId());
170 jsonObject.put("longitude", mobilePosition.getLongitude()); 170 jsonObject.put("longitude", mobilePosition.getLongitude());
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java
@@ -83,12 +83,12 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp @@ -83,12 +83,12 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
83 83
84 device.setKeepaliveTime(DateUtil.getNow()); 84 device.setKeepaliveTime(DateUtil.getNow());
85 85
86 - if (device.getOnline() == 1) { 86 + if (device.isOnLine()) {
87 deviceService.updateDevice(device); 87 deviceService.updateDevice(device);
88 }else { 88 }else {
89 // 对于已经离线的设备判断他的注册是否已经过期 89 // 对于已经离线的设备判断他的注册是否已经过期
90 if (!deviceService.expire(device)){ 90 if (!deviceService.expire(device)){
91 - device.setOnline(0); 91 + device.setOnLine(false);
92 deviceService.online(device, null); 92 deviceService.online(device, null);
93 } 93 }
94 } 94 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java
@@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorP @@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorP
7 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; 7 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
8 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; 8 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler;
9 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; 9 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
  10 +import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
10 import com.genersoft.iot.vmp.service.IDeviceChannelService; 11 import com.genersoft.iot.vmp.service.IDeviceChannelService;
11 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 12 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
12 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 13 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
@@ -95,7 +96,12 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen @@ -95,7 +96,12 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen
95 } 96 }
96 mobilePosition.setDeviceId(sipMsgInfo.getDevice().getDeviceId()); 97 mobilePosition.setDeviceId(sipMsgInfo.getDevice().getDeviceId());
97 mobilePosition.setChannelId(getText(rootElementAfterCharset, "DeviceID")); 98 mobilePosition.setChannelId(getText(rootElementAfterCharset, "DeviceID"));
98 - mobilePosition.setTime(getText(rootElementAfterCharset, "Time")); 99 + String time = getText(rootElementAfterCharset, "Time");
  100 + if (ObjectUtils.isEmpty(time)){
  101 + mobilePosition.setTime(DateUtil.getNow());
  102 + }else {
  103 + mobilePosition.setTime(SipUtils.parseTime(time));
  104 + }
99 mobilePosition.setLongitude(Double.parseDouble(getText(rootElementAfterCharset, "Longitude"))); 105 mobilePosition.setLongitude(Double.parseDouble(getText(rootElementAfterCharset, "Longitude")));
100 mobilePosition.setLatitude(Double.parseDouble(getText(rootElementAfterCharset, "Latitude"))); 106 mobilePosition.setLatitude(Double.parseDouble(getText(rootElementAfterCharset, "Latitude")));
101 if (NumericUtil.isDouble(getText(rootElementAfterCharset, "Speed"))) { 107 if (NumericUtil.isDouble(getText(rootElementAfterCharset, "Speed"))) {
@@ -138,7 +144,7 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen @@ -138,7 +144,7 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen
138 144
139 // 发送redis消息。 通知位置信息的变化 145 // 发送redis消息。 通知位置信息的变化
140 JSONObject jsonObject = new JSONObject(); 146 JSONObject jsonObject = new JSONObject();
141 - jsonObject.put("time", mobilePosition.getTime()); 147 + jsonObject.put("time", DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(mobilePosition.getTime()));
142 jsonObject.put("serial", deviceChannel.getDeviceId()); 148 jsonObject.put("serial", deviceChannel.getDeviceId());
143 jsonObject.put("code", deviceChannel.getChannelId()); 149 jsonObject.put("code", deviceChannel.getChannelId());
144 jsonObject.put("longitude", mobilePosition.getLongitude()); 150 jsonObject.put("longitude", mobilePosition.getLongitude());
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/DeviceStatusQueryMessageHandler.java
@@ -77,7 +77,7 @@ public class DeviceStatusQueryMessageHandler extends SIPRequestProcessorParent i @@ -77,7 +77,7 @@ public class DeviceStatusQueryMessageHandler extends SIPRequestProcessorParent i
77 return; 77 return;
78 } 78 }
79 try { 79 try {
80 - cmderFroPlatform.deviceStatusResponse(parentPlatform,channelId, sn, fromHeader.getTag(),deviceChannel.getStatus()); 80 + cmderFroPlatform.deviceStatusResponse(parentPlatform,channelId, sn, fromHeader.getTag(),deviceChannel.isStatus());
81 } catch (SipException | InvalidArgumentException | ParseException e) { 81 } catch (SipException | InvalidArgumentException | ParseException e) {
82 logger.error("[命令发送失败] 国标级联 DeviceStatus查询回复: {}", e.getMessage()); 82 logger.error("[命令发送失败] 国标级联 DeviceStatus查询回复: {}", e.getMessage());
83 } 83 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java
1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd; 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
2 2
  3 +import com.genersoft.iot.vmp.conf.CivilCodeFileConf;
3 import com.genersoft.iot.vmp.gb28181.bean.*; 4 import com.genersoft.iot.vmp.gb28181.bean.*;
4 import com.genersoft.iot.vmp.gb28181.session.CatalogDataCatch; 5 import com.genersoft.iot.vmp.gb28181.session.CatalogDataCatch;
5 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; 6 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
@@ -54,6 +55,9 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp @@ -54,6 +55,9 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
54 @Autowired 55 @Autowired
55 private ThreadPoolTaskExecutor taskExecutor; 56 private ThreadPoolTaskExecutor taskExecutor;
56 57
  58 + @Autowired
  59 + private CivilCodeFileConf civilCodeFileConf;
  60 +
57 @Override 61 @Override
58 public void afterPropertiesSet() throws Exception { 62 public void afterPropertiesSet() throws Exception {
59 responseMessageHandler.addHandler(cmdType, this); 63 responseMessageHandler.addHandler(cmdType, this);
@@ -101,6 +105,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp @@ -101,6 +105,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
101 Iterator<Element> deviceListIterator = deviceListElement.elementIterator(); 105 Iterator<Element> deviceListIterator = deviceListElement.elementIterator();
102 if (deviceListIterator != null) { 106 if (deviceListIterator != null) {
103 List<DeviceChannel> channelList = new ArrayList<>(); 107 List<DeviceChannel> channelList = new ArrayList<>();
  108 + List<String> parentChannelIds = new ArrayList<>();
104 // 遍历DeviceList 109 // 遍历DeviceList
105 while (deviceListIterator.hasNext()) { 110 while (deviceListIterator.hasNext()) {
106 Element itemDevice = deviceListIterator.next(); 111 Element itemDevice = deviceListIterator.next();
@@ -108,7 +113,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp @@ -108,7 +113,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
108 if (channelDeviceElement == null) { 113 if (channelDeviceElement == null) {
109 continue; 114 continue;
110 } 115 }
111 - DeviceChannel deviceChannel = XmlUtil.channelContentHander(itemDevice, device, null); 116 + DeviceChannel deviceChannel = XmlUtil.channelContentHandler(itemDevice, device, null, civilCodeFileConf);
112 deviceChannel = SipUtils.updateGps(deviceChannel, device.getGeoCoordSys()); 117 deviceChannel = SipUtils.updateGps(deviceChannel, device.getGeoCoordSys());
113 deviceChannel.setDeviceId(take.getDevice().getDeviceId()); 118 deviceChannel.setDeviceId(take.getDevice().getDeviceId());
114 119
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceInfoResponseMessageHandler.java
1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd; 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
2 2
3 -import com.genersoft.iot.vmp.common.VideoManagerConstants;  
4 -import com.genersoft.iot.vmp.conf.SipConfig;  
5 import com.genersoft.iot.vmp.gb28181.bean.Device; 3 import com.genersoft.iot.vmp.gb28181.bean.Device;
6 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 4 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
7 -import com.genersoft.iot.vmp.gb28181.event.EventPublisher;  
8 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; 5 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
9 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; 6 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
10 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; 7 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; 8 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
12 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler; 9 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
13 import com.genersoft.iot.vmp.service.IDeviceService; 10 import com.genersoft.iot.vmp.service.IDeviceService;
14 -import com.genersoft.iot.vmp.storager.IRedisCatchStorage;  
15 -import com.genersoft.iot.vmp.storager.IVideoManagerStorage;  
16 import gov.nist.javax.sip.message.SIPRequest; 11 import gov.nist.javax.sip.message.SIPRequest;
17 import org.dom4j.DocumentException; 12 import org.dom4j.DocumentException;
18 import org.dom4j.Element; 13 import org.dom4j.Element;
@@ -59,7 +54,7 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent @@ -59,7 +54,7 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent
59 public void handForDevice(RequestEvent evt, Device device, Element rootElement) { 54 public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
60 logger.debug("接收到DeviceInfo应答消息"); 55 logger.debug("接收到DeviceInfo应答消息");
61 // 检查设备是否存在, 不存在则不回复 56 // 检查设备是否存在, 不存在则不回复
62 - if (device == null || device.getOnline() == 0) { 57 + if (device == null || !device.isOnLine()) {
63 logger.warn("[接收到DeviceInfo应答消息,但是设备已经离线]:" + (device != null ? device.getDeviceId():"" )); 58 logger.warn("[接收到DeviceInfo应答消息,但是设备已经离线]:" + (device != null ? device.getDeviceId():"" ));
64 return; 59 return;
65 } 60 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/MobilePositionResponseMessageHandler.java
@@ -2,17 +2,21 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.respon @@ -2,17 +2,21 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.respon
2 2
3 import com.alibaba.fastjson2.JSONObject; 3 import com.alibaba.fastjson2.JSONObject;
4 import com.genersoft.iot.vmp.conf.UserSetting; 4 import com.genersoft.iot.vmp.conf.UserSetting;
5 -import com.genersoft.iot.vmp.gb28181.bean.*; 5 +import com.genersoft.iot.vmp.gb28181.bean.Device;
  6 +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
  7 +import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
  8 +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  9 +import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
  10 +import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
6 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; 11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
7 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; 12 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
8 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler; 13 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
9 -import com.genersoft.iot.vmp.gb28181.utils.Coordtransform;  
10 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; 14 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
  15 +import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
11 import com.genersoft.iot.vmp.service.IDeviceChannelService; 16 import com.genersoft.iot.vmp.service.IDeviceChannelService;
12 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 17 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
13 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 18 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
14 import com.genersoft.iot.vmp.utils.DateUtil; 19 import com.genersoft.iot.vmp.utils.DateUtil;
15 -import com.genersoft.iot.vmp.utils.GpsUtil;  
16 import gov.nist.javax.sip.message.SIPRequest; 20 import gov.nist.javax.sip.message.SIPRequest;
17 import org.dom4j.DocumentException; 21 import org.dom4j.DocumentException;
18 import org.dom4j.Element; 22 import org.dom4j.Element;
@@ -56,6 +60,9 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar @@ -56,6 +60,9 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar
56 @Autowired 60 @Autowired
57 private IDeviceChannelService deviceChannelService; 61 private IDeviceChannelService deviceChannelService;
58 62
  63 + @Autowired
  64 + private DeferredResultHolder resultHolder;
  65 +
59 @Override 66 @Override
60 public void afterPropertiesSet() throws Exception { 67 public void afterPropertiesSet() throws Exception {
61 responseMessageHandler.addHandler(cmdType, this); 68 responseMessageHandler.addHandler(cmdType, this);
@@ -83,7 +90,13 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar @@ -83,7 +90,13 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar
83 } 90 }
84 mobilePosition.setDeviceId(device.getDeviceId()); 91 mobilePosition.setDeviceId(device.getDeviceId());
85 mobilePosition.setChannelId(getText(rootElement, "DeviceID")); 92 mobilePosition.setChannelId(getText(rootElement, "DeviceID"));
86 - mobilePosition.setTime(getText(rootElement, "Time")); 93 + //兼容ISO 8601格式时间
  94 + String time = getText(rootElement, "Time");
  95 + if (ObjectUtils.isEmpty(time)){
  96 + mobilePosition.setTime(DateUtil.getNow());
  97 + }else {
  98 + mobilePosition.setTime(SipUtils.parseTime(time));
  99 + }
87 mobilePosition.setLongitude(Double.parseDouble(getText(rootElement, "Longitude"))); 100 mobilePosition.setLongitude(Double.parseDouble(getText(rootElement, "Longitude")));
88 mobilePosition.setLatitude(Double.parseDouble(getText(rootElement, "Latitude"))); 101 mobilePosition.setLatitude(Double.parseDouble(getText(rootElement, "Latitude")));
89 if (NumericUtil.isDouble(getText(rootElement, "Speed"))) { 102 if (NumericUtil.isDouble(getText(rootElement, "Speed"))) {
@@ -121,11 +134,18 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar @@ -121,11 +134,18 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar
121 if (userSetting.getSavePositionHistory()) { 134 if (userSetting.getSavePositionHistory()) {
122 storager.insertMobilePosition(mobilePosition); 135 storager.insertMobilePosition(mobilePosition);
123 } 136 }
  137 +
124 storager.updateChannelPosition(deviceChannel); 138 storager.updateChannelPosition(deviceChannel);
125 139
  140 + String key = DeferredResultHolder.CALLBACK_CMD_MOBILE_POSITION + device.getDeviceId();
  141 + RequestMessage msg = new RequestMessage();
  142 + msg.setKey(key);
  143 + msg.setData(mobilePosition);
  144 + resultHolder.invokeAllResult(msg);
  145 +
126 // 发送redis消息。 通知位置信息的变化 146 // 发送redis消息。 通知位置信息的变化
127 JSONObject jsonObject = new JSONObject(); 147 JSONObject jsonObject = new JSONObject();
128 - jsonObject.put("time", mobilePosition.getTime()); 148 + jsonObject.put("time", DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(mobilePosition.getTime()));
129 jsonObject.put("serial", deviceChannel.getDeviceId()); 149 jsonObject.put("serial", deviceChannel.getDeviceId());
130 jsonObject.put("code", deviceChannel.getChannelId()); 150 jsonObject.put("code", deviceChannel.getChannelId());
131 jsonObject.put("longitude", mobilePosition.getLongitude()); 151 jsonObject.put("longitude", mobilePosition.getLongitude());
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java
1 package com.genersoft.iot.vmp.gb28181.transmit.event.response.impl; 1 package com.genersoft.iot.vmp.gb28181.transmit.event.response.impl;
2 2
3 import com.genersoft.iot.vmp.gb28181.SipLayer; 3 import com.genersoft.iot.vmp.gb28181.SipLayer;
  4 +import com.genersoft.iot.vmp.gb28181.bean.Gb28181Sdp;
4 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; 5 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
5 import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; 6 import com.genersoft.iot.vmp.gb28181.transmit.SIPSender;
6 import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; 7 import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
7 import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcessorAbstract; 8 import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcessorAbstract;
  9 +import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
8 import gov.nist.javax.sip.ResponseEventExt; 10 import gov.nist.javax.sip.ResponseEventExt;
9 import gov.nist.javax.sip.message.SIPResponse; 11 import gov.nist.javax.sip.message.SIPResponse;
10 import org.slf4j.Logger; 12 import org.slf4j.Logger;
@@ -12,7 +14,6 @@ import org.slf4j.LoggerFactory; @@ -12,7 +14,6 @@ import org.slf4j.LoggerFactory;
12 import org.springframework.beans.factory.annotation.Autowired; 14 import org.springframework.beans.factory.annotation.Autowired;
13 import org.springframework.stereotype.Component; 15 import org.springframework.stereotype.Component;
14 16
15 -import javax.sdp.SdpFactory;  
16 import javax.sdp.SdpParseException; 17 import javax.sdp.SdpParseException;
17 import javax.sdp.SessionDescription; 18 import javax.sdp.SessionDescription;
18 import javax.sip.InvalidArgumentException; 19 import javax.sip.InvalidArgumentException;
@@ -82,19 +83,8 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract { @@ -82,19 +83,8 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract {
82 ResponseEventExt event = (ResponseEventExt)evt; 83 ResponseEventExt event = (ResponseEventExt)evt;
83 84
84 String contentString = new String(response.getRawContent()); 85 String contentString = new String(response.getRawContent());
85 - // jainSip不支持y=字段, 移除以解析。  
86 - int ssrcIndex = contentString.indexOf("y=");  
87 - // 检查是否有y字段  
88 - SessionDescription sdp;  
89 - if (ssrcIndex >= 0) {  
90 - //ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段  
91 - String substring = contentString.substring(0, contentString.indexOf("y="));  
92 - sdp = SdpFactory.getInstance().createSessionDescription(substring);  
93 - } else {  
94 - sdp = SdpFactory.getInstance().createSessionDescription(contentString);  
95 - }  
96 - // 查看是否是来自设备的,此是回复  
97 - 86 + Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
  87 + SessionDescription sdp = gb28181Sdp.getBaseSdb();
98 SipURI requestUri = SipFactory.getInstance().createAddressFactory().createSipURI(sdp.getOrigin().getUsername(), event.getRemoteIpAddress() + ":" + event.getRemotePort()); 88 SipURI requestUri = SipFactory.getInstance().createAddressFactory().createSipURI(sdp.getOrigin().getUsername(), event.getRemoteIpAddress() + ":" + event.getRemotePort());
99 Request reqAck = headerProvider.createAckRequest(response.getLocalAddress().getHostAddress(), requestUri, response); 89 Request reqAck = headerProvider.createAckRequest(response.getLocalAddress().getHostAddress(), requestUri, response);
100 90
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/RegisterResponseProcessor.java
@@ -102,7 +102,7 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract { @@ -102,7 +102,7 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract {
102 SipTransactionInfo sipTransactionInfo = new SipTransactionInfo(response); 102 SipTransactionInfo sipTransactionInfo = new SipTransactionInfo(response);
103 platformService.online(parentPlatform, sipTransactionInfo); 103 platformService.online(parentPlatform, sipTransactionInfo);
104 }else { 104 }else {
105 - platformService.offline(parentPlatform, false); 105 + platformService.offline(parentPlatform, true);
106 } 106 }
107 107
108 // 注册/注销成功移除缓存的信息 108 // 注册/注销成功移除缓存的信息
src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java
1 package com.genersoft.iot.vmp.gb28181.utils; 1 package com.genersoft.iot.vmp.gb28181.utils;
2 2
3 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; 3 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
  4 +import com.genersoft.iot.vmp.gb28181.bean.Gb28181Sdp;
4 import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; 5 import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo;
  6 +import com.genersoft.iot.vmp.utils.DateUtil;
5 import com.genersoft.iot.vmp.utils.GitUtil; 7 import com.genersoft.iot.vmp.utils.GitUtil;
6 import gov.nist.javax.sip.address.AddressImpl; 8 import gov.nist.javax.sip.address.AddressImpl;
7 import gov.nist.javax.sip.address.SipUri; 9 import gov.nist.javax.sip.address.SipUri;
8 import gov.nist.javax.sip.header.Subject; 10 import gov.nist.javax.sip.header.Subject;
9 import gov.nist.javax.sip.message.SIPRequest; 11 import gov.nist.javax.sip.message.SIPRequest;
  12 +import org.apache.commons.lang3.RandomStringUtils;
  13 +import org.slf4j.Logger;
  14 +import org.slf4j.LoggerFactory;
10 import org.springframework.util.ObjectUtils; 15 import org.springframework.util.ObjectUtils;
11 16
  17 +import javax.sdp.SdpFactory;
  18 +import javax.sdp.SdpParseException;
  19 +import javax.sdp.SessionDescription;
12 import javax.sip.PeerUnavailableException; 20 import javax.sip.PeerUnavailableException;
13 import javax.sip.SipFactory; 21 import javax.sip.SipFactory;
14 import javax.sip.header.FromHeader; 22 import javax.sip.header.FromHeader;
@@ -16,6 +24,8 @@ import javax.sip.header.Header; @@ -16,6 +24,8 @@ import javax.sip.header.Header;
16 import javax.sip.header.UserAgentHeader; 24 import javax.sip.header.UserAgentHeader;
17 import javax.sip.message.Request; 25 import javax.sip.message.Request;
18 import java.text.ParseException; 26 import java.text.ParseException;
  27 +import java.time.LocalDateTime;
  28 +import java.time.format.DateTimeParseException;
19 import java.util.ArrayList; 29 import java.util.ArrayList;
20 import java.util.List; 30 import java.util.List;
21 import java.util.UUID; 31 import java.util.UUID;
@@ -28,6 +38,8 @@ import java.util.UUID; @@ -28,6 +38,8 @@ import java.util.UUID;
28 */ 38 */
29 public class SipUtils { 39 public class SipUtils {
30 40
  41 + private final static Logger logger = LoggerFactory.getLogger(SipUtils.class);
  42 +
31 public static String getUserIdFromFromHeader(Request request) { 43 public static String getUserIdFromFromHeader(Request request) {
32 FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME); 44 FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME);
33 return getUserIdFromFromHeader(fromHeader); 45 return getUserIdFromFromHeader(fromHeader);
@@ -51,7 +63,7 @@ public class SipUtils { @@ -51,7 +63,7 @@ public class SipUtils {
51 } 63 }
52 64
53 public static String getNewViaTag() { 65 public static String getNewViaTag() {
54 - return "z9hG4bK" + System.currentTimeMillis(); 66 + return "z9hG4bK" + RandomStringUtils.randomNumeric(10);
55 } 67 }
56 68
57 public static UserAgentHeader createUserAgentHeader(GitUtil gitUtil) throws PeerUnavailableException, ParseException { 69 public static UserAgentHeader createUserAgentHeader(GitUtil gitUtil) throws PeerUnavailableException, ParseException {
@@ -113,6 +125,12 @@ public class SipUtils { @@ -113,6 +125,12 @@ public class SipUtils {
113 strTmp = String.format("%02X", moveSpeed); 125 strTmp = String.format("%02X", moveSpeed);
114 builder.append(strTmp, 0, 2); 126 builder.append(strTmp, 0, 2);
115 builder.append(strTmp, 0, 2); 127 builder.append(strTmp, 0, 2);
  128 +
  129 + //优化zoom低倍速下的变倍速率
  130 + if ((zoomSpeed > 0) && (zoomSpeed <16))
  131 + {
  132 + zoomSpeed = 16;
  133 + }
116 strTmp = String.format("%X", zoomSpeed); 134 strTmp = String.format("%X", zoomSpeed);
117 builder.append(strTmp, 0, 1).append("0"); 135 builder.append(strTmp, 0, 1).append("0");
118 //计算校验码 136 //计算校验码
@@ -203,4 +221,66 @@ public class SipUtils { @@ -203,4 +221,66 @@ public class SipUtils {
203 } 221 }
204 return deviceChannel; 222 return deviceChannel;
205 } 223 }
  224 +
  225 + public static Gb28181Sdp parseSDP(String sdpStr) throws SdpParseException {
  226 +
  227 + // jainSip不支持y= f=字段, 移除以解析。
  228 + int ssrcIndex = sdpStr.indexOf("y=");
  229 + int mediaDescriptionIndex = sdpStr.indexOf("f=");
  230 + // 检查是否有y字段
  231 + SessionDescription sdp;
  232 + String ssrc = null;
  233 + String mediaDescription = null;
  234 + if (mediaDescriptionIndex == 0 && ssrcIndex == 0) {
  235 + sdp = SdpFactory.getInstance().createSessionDescription(sdpStr);
  236 + }else {
  237 + String lines[] = sdpStr.split("\\r?\\n");
  238 + StringBuilder sdpBuffer = new StringBuilder();
  239 + for (String line : lines) {
  240 + if (line.trim().startsWith("y=")) {
  241 + ssrc = line.substring(2);
  242 + }else if (line.trim().startsWith("f=")) {
  243 + mediaDescription = line.substring(2);
  244 + }else {
  245 + sdpBuffer.append(line.trim()).append("\r\n");
  246 + }
  247 + }
  248 + sdp = SdpFactory.getInstance().createSessionDescription(sdpBuffer.toString());
  249 + }
  250 + return Gb28181Sdp.getInstance(sdp, ssrc, mediaDescription);
  251 + }
  252 +
  253 + public static String getSsrcFromSdp(String sdpStr) {
  254 +
  255 + // jainSip不支持y= f=字段, 移除以解析。
  256 + int ssrcIndex = sdpStr.indexOf("y=");
  257 + if (ssrcIndex == 0) {
  258 + return null;
  259 + }
  260 + String lines[] = sdpStr.split("\\r?\\n");
  261 + for (String line : lines) {
  262 + if (line.trim().startsWith("y=")) {
  263 + return line.substring(2);
  264 + }
  265 + }
  266 + return null;
  267 + }
  268 +
  269 + public static String parseTime(String timeStr) {
  270 + if (ObjectUtils.isEmpty(timeStr)){
  271 + return null;
  272 + }
  273 + LocalDateTime localDateTime;
  274 + try {
  275 + localDateTime = LocalDateTime.parse(timeStr);
  276 + }catch (DateTimeParseException e) {
  277 + try {
  278 + localDateTime = LocalDateTime.parse(timeStr, DateUtil.formatterISO8601);
  279 + }catch (DateTimeParseException e2) {
  280 + logger.error("[格式化时间] 无法格式化时间: {}", timeStr);
  281 + return null;
  282 + }
  283 + }
  284 + return localDateTime.format(DateUtil.formatterISO8601);
  285 + }
206 } 286 }
src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
@@ -2,6 +2,8 @@ package com.genersoft.iot.vmp.gb28181.utils; @@ -2,6 +2,8 @@ package com.genersoft.iot.vmp.gb28181.utils;
2 2
3 import com.alibaba.fastjson2.JSONArray; 3 import com.alibaba.fastjson2.JSONArray;
4 import com.alibaba.fastjson2.JSONObject; 4 import com.alibaba.fastjson2.JSONObject;
  5 +import com.genersoft.iot.vmp.common.CivilCodePo;
  6 +import com.genersoft.iot.vmp.conf.CivilCodeFileConf;
5 import com.genersoft.iot.vmp.gb28181.bean.Device; 7 import com.genersoft.iot.vmp.gb28181.bean.Device;
6 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; 8 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
7 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; 9 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
@@ -192,7 +194,7 @@ public class XmlUtil { @@ -192,7 +194,7 @@ public class XmlUtil {
192 CivilCode, BusinessGroup,VirtualOrganization,Other 194 CivilCode, BusinessGroup,VirtualOrganization,Other
193 } 195 }
194 196
195 - public static DeviceChannel channelContentHander(Element itemDevice, Device device, String event){ 197 + public static DeviceChannel channelContentHandler(Element itemDevice, Device device, String event, CivilCodeFileConf civilCodeFileConf){
196 DeviceChannel deviceChannel = new DeviceChannel(); 198 DeviceChannel deviceChannel = new DeviceChannel();
197 deviceChannel.setDeviceId(device.getDeviceId()); 199 deviceChannel.setDeviceId(device.getDeviceId());
198 Element channdelIdElement = itemDevice.element("DeviceID"); 200 Element channdelIdElement = itemDevice.element("DeviceID");
@@ -210,208 +212,353 @@ public class XmlUtil { @@ -210,208 +212,353 @@ public class XmlUtil {
210 // 除了ADD和update情况下需要识别全部内容, 212 // 除了ADD和update情况下需要识别全部内容,
211 return deviceChannel; 213 return deviceChannel;
212 } 214 }
213 -  
214 - ChannelType channelType = ChannelType.Other;  
215 - if (channelId.length() <= 8) {  
216 - channelType = ChannelType.CivilCode; 215 + Element nameElement = itemDevice.element("Name");
  216 + if (nameElement != null) {
  217 + deviceChannel.setName(nameElement.getText());
  218 + }
  219 + if(channelId.length() <= 8) {
217 deviceChannel.setHasAudio(false); 220 deviceChannel.setHasAudio(false);
  221 + CivilCodePo parentCode = civilCodeFileConf.getParentCode(channelId);
  222 + if (parentCode != null) {
  223 + deviceChannel.setParentId(parentCode.getCode());
  224 + deviceChannel.setCivilCode(parentCode.getCode());
  225 + }else {
  226 + logger.warn("[xml解析] 无法确定行政区划{}的上级行政区划", channelId);
  227 + }
  228 + deviceChannel.setStatus(true);
  229 + return deviceChannel;
218 }else { 230 }else {
219 - if (channelId.length() == 20) {  
220 - int code = Integer.parseInt(channelId.substring(10, 13));  
221 - switch (code){  
222 - case 215:  
223 - channelType = ChannelType.BusinessGroup;  
224 - deviceChannel.setHasAudio(false);  
225 - break;  
226 - case 216:  
227 - channelType = ChannelType.VirtualOrganization;  
228 - deviceChannel.setHasAudio(false);  
229 - break;  
230 - case 136:  
231 - case 137:  
232 - case 138:  
233 - deviceChannel.setHasAudio(true);  
234 - break;  
235 - default:  
236 - deviceChannel.setHasAudio(false);  
237 - break;  
238 -  
239 - } 231 + if(channelId.length() != 20) {
  232 + logger.warn("[xml解析] 失败,编号不符合国标28181定义: {}", channelId);
  233 + return null;
240 } 234 }
241 - }  
242 235
243 - Element channdelNameElement = itemDevice.element("Name");  
244 - String channelName = channdelNameElement != null ? channdelNameElement.getTextTrim() : "";  
245 - deviceChannel.setName(channelName);  
246 -  
247 - String civilCode = XmlUtil.getText(itemDevice, "CivilCode");  
248 - deviceChannel.setCivilCode(civilCode);  
249 - if (channelType == ChannelType.CivilCode && civilCode == null) {  
250 - deviceChannel.setParental(1);  
251 - // 行政区划如果没有传递具体值,则推测一个  
252 - if (channelId.length() > 2) {  
253 - deviceChannel.setCivilCode(channelId.substring(0, channelId.length() - 2));  
254 - }  
255 - }  
256 - if (channelType.equals(ChannelType.CivilCode)) {  
257 - // 行政区划其他字段没必要识别了,默认在线即可  
258 - deviceChannel.setStatus(1);  
259 - deviceChannel.setParental(1);  
260 - deviceChannel.setCreateTime(DateUtil.getNow());  
261 - deviceChannel.setUpdateTime(DateUtil.getNow());  
262 - return deviceChannel;  
263 - }  
264 - /**  
265 - * 行政区划展示设备树与业务分组展示设备树是两种不同的模式  
266 - * 行政区划展示设备树 各个目录之间主要靠deviceId做关联,摄像头通过CivilCode指定其属于那个行政区划;都是不超过十位的编号; 结构如下:  
267 - * 河北省  
268 - * --> 石家庄市  
269 - * --> 摄像头  
270 - *String parentId = XmlUtil.getText(itemDevice, "ParentID");  
271 - if (parentId != null) {  
272 - if (parentId.contains("/")) {  
273 - String lastParentId = parentId.substring(parentId.lastIndexOf("/") + 1);  
274 - String businessGroup = parentId.substring(0, parentId.indexOf("/"));  
275 - deviceChannel.setParentId(lastParentId);  
276 - }else {  
277 - deviceChannel.setParentId(parentId);  
278 - }  
279 - }  
280 - deviceCh --> 正定县  
281 - * --> 摄像头  
282 - * --> 摄像头  
283 - *  
284 - * 业务分组展示设备树是顶级是业务分组,其下的虚拟组织靠BusinessGroupID指定其所属的业务分组;摄像头通过ParentId来指定其所属于的虚拟组织:  
285 - * 业务分组  
286 - * --> 虚拟组织  
287 - * --> 摄像头  
288 - * --> 虚拟组织  
289 - * --> 摄像头  
290 - * --> 摄像头  
291 - */  
292 - String parentId = XmlUtil.getText(itemDevice, "ParentID");  
293 - String businessGroupID = XmlUtil.getText(itemDevice, "BusinessGroupID");  
294 - if (parentId != null) {  
295 - if (parentId.contains("/")) {  
296 - String lastParentId = parentId.substring(parentId.lastIndexOf("/") + 1);  
297 - if (businessGroupID == null) {  
298 - businessGroupID = parentId.substring(0, parentId.indexOf("/"));  
299 - }  
300 - deviceChannel.setParentId(lastParentId); 236 + int code = Integer.parseInt(channelId.substring(10, 13));
  237 + if (code == 136 || code == 137 || code == 138) {
  238 + deviceChannel.setHasAudio(true);
301 }else { 239 }else {
302 - deviceChannel.setParentId(parentId); 240 + deviceChannel.setHasAudio(false);
303 } 241 }
304 - // 兼容设备通道信息中自己为自己父节点的情况  
305 - if (deviceChannel.getParentId().equals(deviceChannel.getChannelId())) {  
306 - deviceChannel.setParentId(null); 242 + // 设备厂商
  243 + String manufacturer = getText(itemDevice, "Manufacturer");
  244 + // 设备型号
  245 + String model = getText(itemDevice, "Model");
  246 + // 设备归属
  247 + String owner = getText(itemDevice, "Owner");
  248 + // 行政区域
  249 + String civilCode = getText(itemDevice, "CivilCode");
  250 + // 虚拟组织所属的业务分组ID,业务分组根据特定的业务需求制定,一个业务分组包含一组特定的虚拟组织
  251 + String businessGroupID = getText(itemDevice, "BusinessGroupID");
  252 + // 父设备/区域/系统ID
  253 + String parentID = getText(itemDevice, "ParentID");
  254 + if (parentID != null && parentID.equalsIgnoreCase("null")) {
  255 + parentID = null;
307 } 256 }
308 - }  
309 - deviceChannel.setBusinessGroupId(businessGroupID);  
310 - if (channelType.equals(ChannelType.BusinessGroup) || channelType.equals(ChannelType.VirtualOrganization)) {  
311 - // 业务分组和虚拟组织 其他字段没必要识别了,默认在线即可  
312 - deviceChannel.setStatus(1);  
313 - deviceChannel.setParental(1);  
314 - deviceChannel.setCreateTime(DateUtil.getNow());  
315 - deviceChannel.setUpdateTime(DateUtil.getNow());  
316 - return deviceChannel;  
317 - } 257 + // 注册方式(必选)缺省为1;1:符合IETFRFC3261标准的认证注册模式;2:基于口令的双向认证注册模式;3:基于数字证书的双向认证注册模式
  258 + String registerWay = getText(itemDevice, "RegisterWay");
  259 + // 保密属性(必选)缺省为0;0:不涉密,1:涉密
  260 + String secrecy = getText(itemDevice, "Secrecy");
  261 + // 安装地址
  262 + String address = getText(itemDevice, "Address");
  263 +
  264 + switch (code){
  265 + case 200:
  266 + // 系统目录
  267 + if (!ObjectUtils.isEmpty(manufacturer)) {
  268 + deviceChannel.setManufacture(manufacturer);
  269 + }
  270 + if (!ObjectUtils.isEmpty(model)) {
  271 + deviceChannel.setModel(model);
  272 + }
  273 + if (!ObjectUtils.isEmpty(owner)) {
  274 + deviceChannel.setOwner(owner);
  275 + }
  276 + if (!ObjectUtils.isEmpty(civilCode)) {
  277 + deviceChannel.setCivilCode(civilCode);
  278 + deviceChannel.setParentId(civilCode);
  279 + }else {
  280 + if (!ObjectUtils.isEmpty(parentID)) {
  281 + deviceChannel.setParentId(parentID);
  282 + }
  283 + }
  284 + if (!ObjectUtils.isEmpty(address)) {
  285 + deviceChannel.setAddress(address);
  286 + }
  287 + deviceChannel.setStatus(true);
  288 + if (!ObjectUtils.isEmpty(registerWay)) {
  289 + try {
  290 + deviceChannel.setRegisterWay(Integer.parseInt(registerWay));
  291 + }catch (NumberFormatException exception) {
  292 + logger.warn("[xml解析] 从通道数据获取registerWay失败: {}", registerWay);
  293 + }
  294 + }
  295 + if (!ObjectUtils.isEmpty(secrecy)) {
  296 + deviceChannel.setSecrecy(secrecy);
  297 + }
  298 + return deviceChannel;
  299 + case 215:
  300 + // 业务分组
  301 + deviceChannel.setStatus(true);
  302 + if (!ObjectUtils.isEmpty(parentID)) {
  303 + if (!parentID.trim().equalsIgnoreCase(device.getDeviceId())) {
  304 + deviceChannel.setParentId(parentID);
  305 + }
  306 + }else {
  307 + logger.warn("[xml解析] 业务分组数据中缺少关键信息->ParentId");
  308 + if (!ObjectUtils.isEmpty(civilCode)) {
  309 + deviceChannel.setCivilCode(civilCode);
  310 + }
  311 + }
  312 + break;
  313 + case 216:
  314 + // 虚拟组织
  315 + deviceChannel.setStatus(true);
  316 + if (!ObjectUtils.isEmpty(businessGroupID)) {
  317 + deviceChannel.setBusinessGroupId(businessGroupID);
  318 + }
318 319
319 - Element statusElement = itemDevice.element("Status");  
320 320
321 - if (statusElement != null) {  
322 - String status = statusElement.getTextTrim().trim();  
323 - // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理  
324 - if (status.equals("ON") || status.equals("On") || status.equals("ONLINE") || status.equals("OK")) {  
325 - deviceChannel.setStatus(1);  
326 - }  
327 - if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) {  
328 - deviceChannel.setStatus(0);  
329 - }  
330 - }else {  
331 - deviceChannel.setStatus(1);  
332 - }  
333 - // 识别自带的目录标识  
334 - String parental = XmlUtil.getText(itemDevice, "Parental");  
335 - // 由于海康会错误的发送65535作为这里的取值,所以这里除非是0否则认为是1  
336 - if (!ObjectUtils.isEmpty(parental) && parental.length() == 1 && Integer.parseInt(parental) == 0) {  
337 - deviceChannel.setParental(0);  
338 - }else {  
339 - deviceChannel.setParental(1);  
340 - } 321 + if (!ObjectUtils.isEmpty(parentID)) {
  322 + if (parentID.contains("/")) {
  323 + String[] parentIdArray = parentID.split("/");
  324 + parentID = parentIdArray[parentIdArray.length - 1];
  325 + }
  326 + deviceChannel.setParentId(parentID);
  327 + }else {
  328 + if (!ObjectUtils.isEmpty(businessGroupID)) {
  329 + deviceChannel.setParentId(businessGroupID);
  330 + }
  331 + }
  332 + break;
  333 + default:
  334 + // 设备目录
  335 + if (!ObjectUtils.isEmpty(manufacturer)) {
  336 + deviceChannel.setManufacture(manufacturer);
  337 + }
  338 + if (!ObjectUtils.isEmpty(model)) {
  339 + deviceChannel.setModel(model);
  340 + }
  341 + if (!ObjectUtils.isEmpty(owner)) {
  342 + deviceChannel.setOwner(owner);
  343 + }
  344 + if (!ObjectUtils.isEmpty(civilCode)) {
  345 + deviceChannel.setCivilCode(civilCode);
  346 + }
  347 + if (!ObjectUtils.isEmpty(businessGroupID)) {
  348 + deviceChannel.setBusinessGroupId(businessGroupID);
  349 + }
341 350
  351 + // 警区
  352 + String block = getText(itemDevice, "Block");
  353 + if (!ObjectUtils.isEmpty(block)) {
  354 + deviceChannel.setBlock(block);
  355 + }
  356 + if (!ObjectUtils.isEmpty(address)) {
  357 + deviceChannel.setAddress(address);
  358 + }
342 359
343 - deviceChannel.setManufacture(XmlUtil.getText(itemDevice, "Manufacturer"));  
344 - deviceChannel.setModel(XmlUtil.getText(itemDevice, "Model"));  
345 - deviceChannel.setOwner(XmlUtil.getText(itemDevice, "Owner"));  
346 - deviceChannel.setCertNum(XmlUtil.getText(itemDevice, "CertNum"));  
347 - deviceChannel.setBlock(XmlUtil.getText(itemDevice, "Block"));  
348 - deviceChannel.setAddress(XmlUtil.getText(itemDevice, "Address"));  
349 - deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password")); 360 + if (!ObjectUtils.isEmpty(secrecy)) {
  361 + deviceChannel.setSecrecy(secrecy);
  362 + }
350 363
351 - String safetyWay = XmlUtil.getText(itemDevice, "SafetyWay");  
352 - if (ObjectUtils.isEmpty(safetyWay)) {  
353 - deviceChannel.setSafetyWay(0);  
354 - } else {  
355 - deviceChannel.setSafetyWay(Integer.parseInt(safetyWay));  
356 - } 364 + // 当为设备时,是否有子设备(必选)1有,0没有
  365 + String parental = getText(itemDevice, "Parental");
  366 + if (!ObjectUtils.isEmpty(parental)) {
  367 + try {
  368 + // 由于海康会错误的发送65535作为这里的取值,所以这里除非是0否则认为是1
  369 + if (!ObjectUtils.isEmpty(parental) && parental.length() == 1 && Integer.parseInt(parental) == 0) {
  370 + deviceChannel.setParental(0);
  371 + }else {
  372 + deviceChannel.setParental(1);
  373 + }
  374 + }catch (NumberFormatException e) {
  375 + logger.warn("[xml解析] 从通道数据获取 parental失败: {}", parental);
  376 + }
  377 + }
  378 + // 父设备/区域/系统ID
  379 + String realParentId = parentID;
  380 + if (!ObjectUtils.isEmpty(parentID)) {
  381 + if (parentID.contains("/")) {
  382 + String[] parentIdArray = parentID.split("/");
  383 + realParentId = parentIdArray[parentIdArray.length - 1];
  384 + }
  385 + deviceChannel.setParentId(realParentId);
  386 + }else {
  387 + if (!ObjectUtils.isEmpty(businessGroupID)) {
  388 + deviceChannel.setParentId(businessGroupID);
  389 + }else {
  390 + if (!ObjectUtils.isEmpty(civilCode)) {
  391 + deviceChannel.setParentId(civilCode);
  392 + }
  393 + }
  394 + }
  395 + // 注册方式
  396 + if (!ObjectUtils.isEmpty(registerWay)) {
  397 + try {
  398 + int registerWayInt = Integer.parseInt(registerWay);
  399 + deviceChannel.setRegisterWay(registerWayInt);
  400 + }catch (NumberFormatException exception) {
  401 + logger.warn("[xml解析] 从通道数据获取registerWay失败: {}", registerWay);
  402 + deviceChannel.setRegisterWay(1);
  403 + }
  404 + }else {
  405 + deviceChannel.setRegisterWay(1);
  406 + }
357 407
358 - String registerWay = XmlUtil.getText(itemDevice, "RegisterWay");  
359 - if (ObjectUtils.isEmpty(registerWay)) {  
360 - deviceChannel.setRegisterWay(1);  
361 - } else {  
362 - deviceChannel.setRegisterWay(Integer.parseInt(registerWay));  
363 - } 408 + // 信令安全模式(可选)缺省为0; 0:不采用;2:S/MIME 签名方式;3:S/MIME加密签名同时采用方式;4:数字摘要方式
  409 + String safetyWay = getText(itemDevice, "SafetyWay");
  410 + if (!ObjectUtils.isEmpty(safetyWay)) {
  411 + try {
  412 + deviceChannel.setSafetyWay(Integer.parseInt(safetyWay));
  413 + }catch (NumberFormatException e) {
  414 + logger.warn("[xml解析] 从通道数据获取 safetyWay失败: {}", safetyWay);
  415 + }
  416 + }
364 417
365 - if (XmlUtil.getText(itemDevice, "Certifiable") == null  
366 - || XmlUtil.getText(itemDevice, "Certifiable") == "") {  
367 - deviceChannel.setCertifiable(0);  
368 - } else {  
369 - deviceChannel.setCertifiable(Integer.parseInt(XmlUtil.getText(itemDevice, "Certifiable")));  
370 - } 418 + // 证书序列号(有证书的设备必选)
  419 + String certNum = getText(itemDevice, "CertNum");
  420 + if (!ObjectUtils.isEmpty(certNum)) {
  421 + deviceChannel.setCertNum(certNum);
  422 + }
371 423
372 - if (XmlUtil.getText(itemDevice, "ErrCode") == null  
373 - || XmlUtil.getText(itemDevice, "ErrCode") == "") {  
374 - deviceChannel.setErrCode(0);  
375 - } else {  
376 - deviceChannel.setErrCode(Integer.parseInt(XmlUtil.getText(itemDevice, "ErrCode")));  
377 - } 424 + // 证书有效标识(有证书的设备必选)缺省为0;证书有效标识:0:无效 1:有效
  425 + String certifiable = getText(itemDevice, "Certifiable");
  426 + if (!ObjectUtils.isEmpty(certifiable)) {
  427 + try {
  428 + deviceChannel.setCertifiable(Integer.parseInt(certifiable));
  429 + }catch (NumberFormatException e) {
  430 + logger.warn("[xml解析] 从通道数据获取 Certifiable失败: {}", certifiable);
  431 + }
  432 + }
378 433
379 - deviceChannel.setEndTime(XmlUtil.getText(itemDevice, "EndTime"));  
380 - deviceChannel.setSecrecy(XmlUtil.getText(itemDevice, "Secrecy"));  
381 - deviceChannel.setIpAddress(XmlUtil.getText(itemDevice, "IPAddress"));  
382 - if (XmlUtil.getText(itemDevice, "Port") == null || XmlUtil.getText(itemDevice, "Port") == "") {  
383 - deviceChannel.setPort(0);  
384 - } else {  
385 - deviceChannel.setPort(Integer.parseInt(XmlUtil.getText(itemDevice, "Port")));  
386 - } 434 + // 无效原因码(有证书且证书无效的设备必选)
  435 + String errCode = getText(itemDevice, "ErrCode");
  436 + if (!ObjectUtils.isEmpty(errCode)) {
  437 + try {
  438 + deviceChannel.setErrCode(Integer.parseInt(errCode));
  439 + }catch (NumberFormatException e) {
  440 + logger.warn("[xml解析] 从通道数据获取 ErrCode失败: {}", errCode);
  441 + }
  442 + }
387 443
  444 + // 证书终止有效期(有证书的设备必选)
  445 + String endTime = getText(itemDevice, "EndTime");
  446 + if (!ObjectUtils.isEmpty(endTime)) {
  447 + deviceChannel.setEndTime(endTime);
  448 + }
388 449
389 - String longitude = XmlUtil.getText(itemDevice, "Longitude");  
390 - if (NumericUtil.isDouble(longitude)) {  
391 - deviceChannel.setLongitude(Double.parseDouble(longitude));  
392 - } else {  
393 - deviceChannel.setLongitude(0.00);  
394 - }  
395 - String latitude = XmlUtil.getText(itemDevice, "Latitude");  
396 - if (NumericUtil.isDouble(latitude)) {  
397 - deviceChannel.setLatitude(Double.parseDouble(latitude));  
398 - } else {  
399 - deviceChannel.setLatitude(0.00);  
400 - }  
401 450
402 - deviceChannel.setGpsTime(DateUtil.getNow()); 451 + // 设备/区域/系统IP地址
  452 + String ipAddress = getText(itemDevice, "IPAddress");
  453 + if (!ObjectUtils.isEmpty(ipAddress)) {
  454 + deviceChannel.setIpAddress(ipAddress);
  455 + }
  456 +
  457 + // 设备/区域/系统端口
  458 + String port = getText(itemDevice, "Port");
  459 + if (!ObjectUtils.isEmpty(port)) {
  460 + try {
  461 + deviceChannel.setPort(Integer.parseInt(port));
  462 + }catch (NumberFormatException e) {
  463 + logger.warn("[xml解析] 从通道数据获取 Port失败: {}", port);
  464 + }
  465 + }
  466 +
  467 + // 设备口令
  468 + String password = getText(itemDevice, "Password");
  469 + if (!ObjectUtils.isEmpty(password)) {
  470 + deviceChannel.setPassword(password);
  471 + }
403 472
404 473
405 - if (XmlUtil.getText(itemDevice, "PTZType") == null || "".equals(XmlUtil.getText(itemDevice, "PTZType"))) {  
406 - //兼容INFO中的信息  
407 - Element info = itemDevice.element("Info");  
408 - if(XmlUtil.getText(info, "PTZType") == null || "".equals(XmlUtil.getText(info, "PTZType"))){  
409 - deviceChannel.setPTZType(0);  
410 - }else{  
411 - deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(info, "PTZType"))); 474 + // 设备状态
  475 + String status = getText(itemDevice, "Status");
  476 + if (status != null) {
  477 + // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理
  478 + if (status.equals("ON") || status.equals("On") || status.equals("ONLINE") || status.equals("OK")) {
  479 + deviceChannel.setStatus(true);
  480 + }
  481 + if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) {
  482 + deviceChannel.setStatus(false);
  483 + }
  484 + }else {
  485 + deviceChannel.setStatus(true);
  486 + }
  487 +
  488 + // 经度
  489 + String longitude = getText(itemDevice, "Longitude");
  490 + if (NumericUtil.isDouble(longitude)) {
  491 + deviceChannel.setLongitude(Double.parseDouble(longitude));
  492 + } else {
  493 + deviceChannel.setLongitude(0.00);
  494 + }
  495 +
  496 + // 纬度
  497 + String latitude = getText(itemDevice, "Latitude");
  498 + if (NumericUtil.isDouble(latitude)) {
  499 + deviceChannel.setLatitude(Double.parseDouble(latitude));
  500 + } else {
  501 + deviceChannel.setLatitude(0.00);
  502 + }
  503 +
  504 + deviceChannel.setGpsTime(DateUtil.getNow());
  505 +
  506 + // -摄像机类型扩展,标识摄像机类型:1-球机;2-半球;3-固定枪机;4-遥控枪机。当目录项为摄像机时可选
  507 + String ptzType = getText(itemDevice, "PTZType");
  508 + if (ObjectUtils.isEmpty(ptzType)) {
  509 + //兼容INFO中的信息
  510 + Element info = itemDevice.element("Info");
  511 + String ptzTypeFromInfo = XmlUtil.getText(info, "PTZType");
  512 + if(!ObjectUtils.isEmpty(ptzTypeFromInfo)){
  513 + try {
  514 + deviceChannel.setPTZType(Integer.parseInt(ptzTypeFromInfo));
  515 + }catch (NumberFormatException e){
  516 + logger.warn("[xml解析] 从通道数据info中获取PTZType失败: {}", ptzTypeFromInfo);
  517 + }
  518 + }
  519 + } else {
  520 + try {
  521 + deviceChannel.setPTZType(Integer.parseInt(ptzType));
  522 + }catch (NumberFormatException e){
  523 + logger.warn("[xml解析] 从通道数据中获取PTZType失败: {}", ptzType);
  524 + }
  525 + }
  526 +
  527 + // TODO 摄像机位置类型扩展。
  528 + // 1-省际检查站、
  529 + // 2-党政机关、
  530 + // 3-车站码头、
  531 + // 4-中心广场、
  532 + // 5-体育场馆、
  533 + // 6-商业中心、
  534 + // 7-宗教场所、
  535 + // 8-校园周边、
  536 + // 9-治安复杂区域、
  537 + // 10-交通干线。
  538 + // String positionType = getText(itemDevice, "PositionType");
  539 +
  540 + // TODO 摄像机安装位置室外、室内属性。1-室外、2-室内。
  541 + // String roomType = getText(itemDevice, "RoomType");
  542 + // TODO 摄像机用途属性
  543 + // String useType = getText(itemDevice, "UseType");
  544 + // TODO 摄像机补光属性。1-无补光、2-红外补光、3-白光补光
  545 + // String supplyLightType = getText(itemDevice, "SupplyLightType");
  546 + // TODO 摄像机监视方位属性。1-东、2-西、3-南、4-北、5-东南、6-东北、7-西南、8-西北。
  547 + // String directionType = getText(itemDevice, "DirectionType");
  548 + // TODO 摄像机支持的分辨率,可有多个分辨率值,各个取值间以“/”分隔。分辨率取值参见附录 F中SDPf字段规定
  549 + // String resolution = getText(itemDevice, "Resolution");
  550 +
  551 + // TODO 下载倍速范围(可选),各可选参数以“/”分隔,如设备支持1,2,4倍速下载则应写为“1/2/4
  552 + // String downloadSpeed = getText(itemDevice, "DownloadSpeed");
  553 + // TODO 空域编码能力,取值0:不支持;1:1级增强(1个增强层);2:2级增强(2个增强层);3:3级增强(3个增强层)
  554 + // String svcSpaceSupportMode = getText(itemDevice, "SVCSpaceSupportMode");
  555 + // TODO 时域编码能力,取值0:不支持;1:1级增强;2:2级增强;3:3级增强
  556 + // String svcTimeSupportMode = getText(itemDevice, "SVCTimeSupportMode");
  557 +
  558 +
  559 + deviceChannel.setSecrecy(secrecy);
  560 + break;
412 } 561 }
413 - } else {  
414 - deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType")));  
415 } 562 }
416 563
417 return deviceChannel; 564 return deviceChannel;
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -131,14 +131,12 @@ public class ZLMHttpHookListener { @@ -131,14 +131,12 @@ public class ZLMHttpHookListener {
131 @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8") 131 @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8")
132 public HookResult onServerKeepalive(@RequestBody OnServerKeepaliveHookParam param) { 132 public HookResult onServerKeepalive(@RequestBody OnServerKeepaliveHookParam param) {
133 133
134 -// logger.info("[ZLM HOOK] 收到zlm心跳:" + param.getMediaServerId());  
135 134
136 taskExecutor.execute(() -> { 135 taskExecutor.execute(() -> {
137 List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive); 136 List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive);
138 - JSONObject json = (JSONObject) JSON.toJSON(param);  
139 if (subscribes != null && subscribes.size() > 0) { 137 if (subscribes != null && subscribes.size() > 0) {
140 for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { 138 for (ZlmHttpHookSubscribe.Event subscribe : subscribes) {
141 - subscribe.response(null, json); 139 + subscribe.response(null, param);
142 } 140 }
143 } 141 }
144 }); 142 });
@@ -165,7 +163,7 @@ public class ZLMHttpHookListener { @@ -165,7 +163,7 @@ public class ZLMHttpHookListener {
165 if (subscribe != null) { 163 if (subscribe != null) {
166 MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); 164 MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
167 if (mediaInfo != null) { 165 if (mediaInfo != null) {
168 - subscribe.response(mediaInfo, json); 166 + subscribe.response(mediaInfo, param);
169 } 167 }
170 } 168 }
171 }); 169 });
@@ -198,13 +196,13 @@ public class ZLMHttpHookListener { @@ -198,13 +196,13 @@ public class ZLMHttpHookListener {
198 if (userSetting.getPushAuthority()) { 196 if (userSetting.getPushAuthority()) {
199 // 推流鉴权 197 // 推流鉴权
200 if (param.getParams() == null) { 198 if (param.getParams() == null) {
201 - logger.info("推流鉴权失败: 缺少要参数:sign=md5(user表的pushKey)"); 199 + logger.info("推流鉴权失败: 缺少要参数:sign=md5(user表的pushKey)");
202 return new HookResultForOnPublish(401, "Unauthorized"); 200 return new HookResultForOnPublish(401, "Unauthorized");
203 } 201 }
204 Map<String, String> paramMap = urlParamToMap(param.getParams()); 202 Map<String, String> paramMap = urlParamToMap(param.getParams());
205 String sign = paramMap.get("sign"); 203 String sign = paramMap.get("sign");
206 if (sign == null) { 204 if (sign == null) {
207 - logger.info("推流鉴权失败: 缺少要参数:sign=md5(user表的pushKey)"); 205 + logger.info("推流鉴权失败: 缺少要参数:sign=md5(user表的pushKey)");
208 return new HookResultForOnPublish(401, "Unauthorized"); 206 return new HookResultForOnPublish(401, "Unauthorized");
209 } 207 }
210 // 推流自定义播放鉴权码 208 // 推流自定义播放鉴权码
@@ -241,7 +239,7 @@ public class ZLMHttpHookListener { @@ -241,7 +239,7 @@ public class ZLMHttpHookListener {
241 ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json); 239 ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json);
242 if (subscribe != null) { 240 if (subscribe != null) {
243 if (mediaInfo != null) { 241 if (mediaInfo != null) {
244 - subscribe.response(mediaInfo, json); 242 + subscribe.response(mediaInfo, param);
245 } else { 243 } else {
246 new HookResultForOnPublish(1, "zlm not register"); 244 new HookResultForOnPublish(1, "zlm not register");
247 } 245 }
@@ -321,7 +319,7 @@ public class ZLMHttpHookListener { @@ -321,7 +319,7 @@ public class ZLMHttpHookListener {
321 return; 319 return;
322 } 320 }
323 if (subscribe != null) { 321 if (subscribe != null) {
324 - subscribe.response(mediaInfo, json); 322 + subscribe.response(mediaInfo, param);
325 } 323 }
326 324
327 List<OnStreamChangedHookParam.MediaTrack> tracks = param.getTracks(); 325 List<OnStreamChangedHookParam.MediaTrack> tracks = param.getTracks();
@@ -551,7 +549,9 @@ public class ZLMHttpHookListener { @@ -551,7 +549,9 @@ public class ZLMHttpHookListener {
551 Device device = deviceService.getDevice(inviteInfo.getDeviceId()); 549 Device device = deviceService.getDevice(inviteInfo.getDeviceId());
552 if (device != null) { 550 if (device != null) {
553 try { 551 try {
554 - if (inviteStreamService.getInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId(), inviteInfo.getChannelId(), inviteInfo.getStream()) != null) { 552 + InviteInfo info = inviteStreamService.getInviteInfo(inviteInfo.getType(),
  553 + inviteInfo.getDeviceId(), inviteInfo.getChannelId(), inviteInfo.getStream());
  554 + if (info != null) {
555 cmder.streamByeCmd(device, inviteInfo.getChannelId(), 555 cmder.streamByeCmd(device, inviteInfo.getChannelId(),
556 inviteInfo.getStream(), null); 556 inviteInfo.getStream(), null);
557 } 557 }
@@ -578,13 +578,13 @@ public class ZLMHttpHookListener { @@ -578,13 +578,13 @@ public class ZLMHttpHookListener {
578 // 拉流代理 578 // 拉流代理
579 StreamProxyItem streamProxyItem = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream()); 579 StreamProxyItem streamProxyItem = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream());
580 if (streamProxyItem != null) { 580 if (streamProxyItem != null) {
581 - if (streamProxyItem.isEnable_remove_none_reader()) { 581 + if (streamProxyItem.isEnableDisableNoneReader()) {
582 // 无人观看自动移除 582 // 无人观看自动移除
583 ret.put("close", true); 583 ret.put("close", true);
584 streamProxyService.del(param.getApp(), param.getStream()); 584 streamProxyService.del(param.getApp(), param.getStream());
585 - String url = streamProxyItem.getUrl() != null ? streamProxyItem.getUrl() : streamProxyItem.getSrc_url(); 585 + String url = streamProxyItem.getUrl() != null ? streamProxyItem.getUrl() : streamProxyItem.getSrcUrl();
586 logger.info("[{}/{}]<-[{}] 拉流代理无人观看已经移除", param.getApp(), param.getStream(), url); 586 logger.info("[{}/{}]<-[{}] 拉流代理无人观看已经移除", param.getApp(), param.getStream(), url);
587 - } else if (streamProxyItem.isEnable_disable_none_reader()) { 587 + } else if (streamProxyItem.isEnableDisableNoneReader()) {
588 // 无人观看停用 588 // 无人观看停用
589 ret.put("close", true); 589 ret.put("close", true);
590 // 修改数据 590 // 修改数据
@@ -669,7 +669,7 @@ public class ZLMHttpHookListener { @@ -669,7 +669,7 @@ public class ZLMHttpHookListener {
669 } else { 669 } else {
670 // 拉流代理 670 // 拉流代理
671 StreamProxyItem streamProxyByAppAndStream = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream()); 671 StreamProxyItem streamProxyByAppAndStream = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream());
672 - if (streamProxyByAppAndStream != null && streamProxyByAppAndStream.isEnable_disable_none_reader()) { 672 + if (streamProxyByAppAndStream != null && streamProxyByAppAndStream.isEnableDisableNoneReader()) {
673 streamProxyService.start(param.getApp(), param.getStream()); 673 streamProxyService.start(param.getApp(), param.getStream());
674 } 674 }
675 DeferredResult<HookResult> result = new DeferredResult<>(); 675 DeferredResult<HookResult> result = new DeferredResult<>();
@@ -693,7 +693,7 @@ public class ZLMHttpHookListener { @@ -693,7 +693,7 @@ public class ZLMHttpHookListener {
693 List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_started); 693 List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_started);
694 if (subscribes != null && subscribes.size() > 0) { 694 if (subscribes != null && subscribes.size() > 0) {
695 for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { 695 for (ZlmHttpHookSubscribe.Event subscribe : subscribes) {
696 - subscribe.response(null, jsonObject); 696 + subscribe.response(null, zlmServerConfig);
697 } 697 }
698 } 698 }
699 mediaServerService.zlmServerOnline(zlmServerConfig); 699 mediaServerService.zlmServerOnline(zlmServerConfig);
@@ -749,7 +749,7 @@ public class ZLMHttpHookListener { @@ -749,7 +749,7 @@ public class ZLMHttpHookListener {
749 List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_rtp_server_timeout); 749 List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_rtp_server_timeout);
750 if (subscribes != null && subscribes.size() > 0) { 750 if (subscribes != null && subscribes.size() > 0) {
751 for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { 751 for (ZlmHttpHookSubscribe.Event subscribe : subscribes) {
752 - subscribe.response(null, json); 752 + subscribe.response(null, param);
753 } 753 }
754 } 754 }
755 }); 755 });
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
@@ -157,7 +157,6 @@ public class ZLMRESTfulUtils { @@ -157,7 +157,6 @@ public class ZLMRESTfulUtils {
157 157
158 public void sendGetForImg(MediaServerItem mediaServerItem, String api, Map<String, Object> params, String targetPath, String fileName) { 158 public void sendGetForImg(MediaServerItem mediaServerItem, String api, Map<String, Object> params, String targetPath, String fileName) {
159 String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api); 159 String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api);
160 - logger.debug(url);  
161 HttpUrl parseUrl = HttpUrl.parse(url); 160 HttpUrl parseUrl = HttpUrl.parse(url);
162 if (parseUrl == null) { 161 if (parseUrl == null) {
163 return; 162 return;
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
@@ -9,6 +9,11 @@ import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; @@ -9,6 +9,11 @@ import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
9 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; 9 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
10 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout; 10 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout;
11 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 11 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  12 +import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam;
  13 +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRtpServerTimeoutHookParam;
  14 +import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
  15 +import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout;
  16 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
12 import org.slf4j.Logger; 17 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory; 18 import org.slf4j.LoggerFactory;
14 import org.springframework.beans.factory.annotation.Autowired; 19 import org.springframework.beans.factory.annotation.Autowired;
@@ -228,7 +233,7 @@ public class ZLMRTPServerFactory { @@ -228,7 +233,7 @@ public class ZLMRTPServerFactory {
228 int localPort = 0; 233 int localPort = 0;
229 if (userSetting.getGbSendStreamStrict()) { 234 if (userSetting.getGbSendStreamStrict()) {
230 if (userSetting.getGbSendStreamStrict()) { 235 if (userSetting.getGbSendStreamStrict()) {
231 - localPort = keepPort(serverItem, ssrc, null); 236 + localPort = keepPort(serverItem, ssrc, localPort);
232 if (localPort == 0) { 237 if (localPort == 0) {
233 return null; 238 return null;
234 } 239 }
@@ -264,7 +269,7 @@ public class ZLMRTPServerFactory { @@ -264,7 +269,7 @@ public class ZLMRTPServerFactory {
264 // 默认为随机端口 269 // 默认为随机端口
265 int localPort = 0; 270 int localPort = 0;
266 if (userSetting.getGbSendStreamStrict()) { 271 if (userSetting.getGbSendStreamStrict()) {
267 - localPort = keepPort(serverItem, ssrc, null); 272 + localPort = keepPort(serverItem, ssrc, localPort);
268 if (localPort == 0) { 273 if (localPort == 0) {
269 return null; 274 return null;
270 } 275 }
@@ -290,9 +295,6 @@ public class ZLMRTPServerFactory { @@ -290,9 +295,6 @@ public class ZLMRTPServerFactory {
290 */ 295 */
291 public int keepPort(MediaServerItem serverItem, String ssrc, Integer localPort) { 296 public int keepPort(MediaServerItem serverItem, String ssrc, Integer localPort) {
292 Map<String, Object> param = new HashMap<>(3); 297 Map<String, Object> param = new HashMap<>(3);
293 - if (localPort == null) {  
294 - localPort = 0;  
295 - }  
296 param.put("port", localPort); 298 param.put("port", localPort);
297 param.put("enable_tcp", 1); 299 param.put("enable_tcp", 1);
298 param.put("stream_id", ssrc); 300 param.put("stream_id", ssrc);
@@ -302,22 +304,24 @@ public class ZLMRTPServerFactory { @@ -302,22 +304,24 @@ public class ZLMRTPServerFactory {
302 HookSubscribeForRtpServerTimeout hookSubscribeForRtpServerTimeout = HookSubscribeFactory.on_rtp_server_timeout(ssrc, null, serverItem.getId()); 304 HookSubscribeForRtpServerTimeout hookSubscribeForRtpServerTimeout = HookSubscribeFactory.on_rtp_server_timeout(ssrc, null, serverItem.getId());
303 Integer finalLocalPort = localPort; 305 Integer finalLocalPort = localPort;
304 hookSubscribe.addSubscribe(hookSubscribeForRtpServerTimeout, 306 hookSubscribe.addSubscribe(hookSubscribeForRtpServerTimeout,
305 - (MediaServerItem mediaServerItem, JSONObject response)->{  
306 - if (ssrc.equals(response.getString("ssrc"))) {  
307 - logger.info("[上级点播] {}->监听端口到期继续保持监听", ssrc);  
308 - int port = keepPort(serverItem, ssrc, finalLocalPort);  
309 - if (port == 0) {  
310 - logger.info("[上级点播] {}->监听端口失败,移除监听", ssrc);  
311 - hookSubscribe.removeSubscribe(hookSubscribeForRtpServerTimeout);  
312 - } 307 + (MediaServerItem mediaServerItem, HookParam hookParam)->{
  308 + logger.info("[上级点播] {}->监听端口到期继续保持监听: {}", ssrc, finalLocalPort);
  309 + OnRtpServerTimeoutHookParam rtpServerTimeoutHookParam = (OnRtpServerTimeoutHookParam) hookParam;
  310 + if (!ssrc.equals(rtpServerTimeoutHookParam.getSsrc())) {
  311 + return;
  312 + }
  313 + int port = keepPort(serverItem, ssrc, finalLocalPort);
  314 + if (port == 0) {
  315 + logger.info("[上级点播] {}->监听端口失败,移除监听", ssrc);
  316 + hookSubscribe.removeSubscribe(hookSubscribeForRtpServerTimeout);
313 } 317 }
314 }); 318 });
315 - logger.info("[保持端口] {}->监听端口: {}", ssrc, localPort);  
316 - logger.info("[保持端口] {}->监听端口: {}", ssrc, localPort); 319 + logger.info("[上级点播] {}->监听端口: {}", ssrc, localPort);
  320 + return localPort;
317 }else { 321 }else {
318 - logger.info("[保持端口] 监听端口失败: {}", ssrc); 322 + logger.info("[上级点播] 监听端口失败: {}->{}", ssrc, localPort);
  323 + return 0;
319 } 324 }
320 - return localPort;  
321 } 325 }
322 326
323 /** 327 /**
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
@@ -65,8 +65,8 @@ public class ZLMRunner implements CommandLineRunner { @@ -65,8 +65,8 @@ public class ZLMRunner implements CommandLineRunner {
65 HookSubscribeForServerStarted hookSubscribeForServerStarted = HookSubscribeFactory.on_server_started(); 65 HookSubscribeForServerStarted hookSubscribeForServerStarted = HookSubscribeFactory.on_server_started();
66 // 订阅 zlm启动事件, 新的zlm也会从这里进入系统 66 // 订阅 zlm启动事件, 新的zlm也会从这里进入系统
67 hookSubscribe.addSubscribe(hookSubscribeForServerStarted, 67 hookSubscribe.addSubscribe(hookSubscribeForServerStarted,
68 - (MediaServerItem mediaServerItem, JSONObject response)->{  
69 - ZLMServerConfig zlmServerConfig = response.to(ZLMServerConfig.class); 68 + (mediaServerItem, hookParam)->{
  69 + ZLMServerConfig zlmServerConfig = (ZLMServerConfig)hookParam;
70 if (zlmServerConfig !=null ) { 70 if (zlmServerConfig !=null ) {
71 if (startGetMedia != null) { 71 if (startGetMedia != null) {
72 startGetMedia.remove(zlmServerConfig.getGeneralMediaServerId()); 72 startGetMedia.remove(zlmServerConfig.getGeneralMediaServerId());
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerConfig.java
1 package com.genersoft.iot.vmp.media.zlm; 1 package com.genersoft.iot.vmp.media.zlm;
2 2
3 import com.alibaba.fastjson2.annotation.JSONField; 3 import com.alibaba.fastjson2.annotation.JSONField;
  4 +import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam;
4 5
5 -public class ZLMServerConfig { 6 +public class ZLMServerConfig extends HookParam {
6 7
7 @JSONField(name = "api.apiDebug") 8 @JSONField(name = "api.apiDebug")
8 private String apiDebug; 9 private String apiDebug;
src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java
@@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSONObject; @@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSONObject;
4 import com.genersoft.iot.vmp.media.zlm.dto.HookType; 4 import com.genersoft.iot.vmp.media.zlm.dto.HookType;
5 import com.genersoft.iot.vmp.media.zlm.dto.IHookSubscribe; 5 import com.genersoft.iot.vmp.media.zlm.dto.IHookSubscribe;
6 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 6 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  7 +import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam;
7 import org.slf4j.Logger; 8 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory; 9 import org.slf4j.LoggerFactory;
9 import org.springframework.scheduling.annotation.Scheduled; 10 import org.springframework.scheduling.annotation.Scheduled;
@@ -26,7 +27,7 @@ public class ZlmHttpHookSubscribe { @@ -26,7 +27,7 @@ public class ZlmHttpHookSubscribe {
26 27
27 @FunctionalInterface 28 @FunctionalInterface
28 public interface Event{ 29 public interface Event{
29 - void response(MediaServerItem mediaServerItem, JSONObject response); 30 + void response(MediaServerItem mediaServerItem, HookParam hookParam);
30 } 31 }
31 32
32 private Map<HookType, Map<IHookSubscribe, ZlmHttpHookSubscribe.Event>> allSubscribes = new ConcurrentHashMap<>(); 33 private Map<HookType, Map<IHookSubscribe, ZlmHttpHookSubscribe.Event>> allSubscribes = new ConcurrentHashMap<>();
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java
@@ -20,28 +20,26 @@ public class StreamProxyItem extends GbStream { @@ -20,28 +20,26 @@ public class StreamProxyItem extends GbStream {
20 @Schema(description = "拉流地址") 20 @Schema(description = "拉流地址")
21 private String url; 21 private String url;
22 @Schema(description = "拉流地址") 22 @Schema(description = "拉流地址")
23 - private String src_url; 23 + private String srcUrl;
24 @Schema(description = "目标地址") 24 @Schema(description = "目标地址")
25 - private String dst_url; 25 + private String dstUrl;
26 @Schema(description = "超时时间") 26 @Schema(description = "超时时间")
27 - private int timeout_ms; 27 + private int timeoutMs;
28 @Schema(description = "ffmpeg模板KEY") 28 @Schema(description = "ffmpeg模板KEY")
29 - private String ffmpeg_cmd_key; 29 + private String ffmpegCmdKey;
30 @Schema(description = "rtsp拉流时,拉流方式,0:tcp,1:udp,2:组播") 30 @Schema(description = "rtsp拉流时,拉流方式,0:tcp,1:udp,2:组播")
31 - private String rtp_type; 31 + private String rtpType;
32 @Schema(description = "是否启用") 32 @Schema(description = "是否启用")
33 private boolean enable; 33 private boolean enable;
34 @Schema(description = "是否启用音频") 34 @Schema(description = "是否启用音频")
35 - private boolean enable_audio; 35 + private boolean enableAudio;
36 @Schema(description = "是否启用MP4") 36 @Schema(description = "是否启用MP4")
37 - private boolean enable_mp4; 37 + private boolean enableMp4;
38 @Schema(description = "是否 无人观看时删除") 38 @Schema(description = "是否 无人观看时删除")
39 - private boolean enable_remove_none_reader; 39 + private boolean enableRemoveNoneReader;
40 40
41 @Schema(description = "是否 无人观看时自动停用") 41 @Schema(description = "是否 无人观看时自动停用")
42 - private boolean enable_disable_none_reader;  
43 - @Schema(description = "创建时间")  
44 - private String createTime; 42 + private boolean enableDisableNoneReader;
45 43
46 public String getType() { 44 public String getType() {
47 return type; 45 return type;
@@ -89,44 +87,44 @@ public class StreamProxyItem extends GbStream { @@ -89,44 +87,44 @@ public class StreamProxyItem extends GbStream {
89 this.url = url; 87 this.url = url;
90 } 88 }
91 89
92 - public String getSrc_url() {  
93 - return src_url; 90 + public String getSrcUrl() {
  91 + return srcUrl;
94 } 92 }
95 93
96 - public void setSrc_url(String src_url) {  
97 - this.src_url = src_url; 94 + public void setSrcUrl(String src_url) {
  95 + this.srcUrl = src_url;
98 } 96 }
99 97
100 - public String getDst_url() {  
101 - return dst_url; 98 + public String getDstUrl() {
  99 + return dstUrl;
102 } 100 }
103 101
104 - public void setDst_url(String dst_url) {  
105 - this.dst_url = dst_url; 102 + public void setDstUrl(String dst_url) {
  103 + this.dstUrl = dst_url;
106 } 104 }
107 105
108 - public int getTimeout_ms() {  
109 - return timeout_ms; 106 + public int getTimeoutMs() {
  107 + return timeoutMs;
110 } 108 }
111 109
112 - public void setTimeout_ms(int timeout_ms) {  
113 - this.timeout_ms = timeout_ms; 110 + public void setTimeoutMs(int timeout_ms) {
  111 + this.timeoutMs = timeout_ms;
114 } 112 }
115 113
116 - public String getFfmpeg_cmd_key() {  
117 - return ffmpeg_cmd_key; 114 + public String getFfmpegCmdKey() {
  115 + return ffmpegCmdKey;
118 } 116 }
119 117
120 - public void setFfmpeg_cmd_key(String ffmpeg_cmd_key) {  
121 - this.ffmpeg_cmd_key = ffmpeg_cmd_key; 118 + public void setFfmpegCmdKey(String ffmpeg_cmd_key) {
  119 + this.ffmpegCmdKey = ffmpeg_cmd_key;
122 } 120 }
123 121
124 - public String getRtp_type() {  
125 - return rtp_type; 122 + public String getRtpType() {
  123 + return rtpType;
126 } 124 }
127 125
128 - public void setRtp_type(String rtp_type) {  
129 - this.rtp_type = rtp_type; 126 + public void setRtpType(String rtp_type) {
  127 + this.rtpType = rtp_type;
130 } 128 }
131 129
132 public boolean isEnable() { 130 public boolean isEnable() {
@@ -137,45 +135,37 @@ public class StreamProxyItem extends GbStream { @@ -137,45 +135,37 @@ public class StreamProxyItem extends GbStream {
137 this.enable = enable; 135 this.enable = enable;
138 } 136 }
139 137
140 - public boolean isEnable_mp4() {  
141 - return enable_mp4; 138 + public boolean isEnableMp4() {
  139 + return enableMp4;
142 } 140 }
143 141
144 - public void setEnable_mp4(boolean enable_mp4) {  
145 - this.enable_mp4 = enable_mp4; 142 + public void setEnableMp4(boolean enable_mp4) {
  143 + this.enableMp4 = enable_mp4;
146 } 144 }
147 145
148 - @Override  
149 - public String getCreateTime() {  
150 - return createTime; 146 + public boolean isEnableRemoveNoneReader() {
  147 + return enableRemoveNoneReader;
151 } 148 }
152 149
153 - @Override  
154 - public void setCreateTime(String createTime) {  
155 - this.createTime = createTime; 150 + public void setEnableRemoveNoneReader(boolean enable_remove_none_reader) {
  151 + this.enableRemoveNoneReader = enable_remove_none_reader;
156 } 152 }
157 153
158 - public boolean isEnable_remove_none_reader() {  
159 - return enable_remove_none_reader; 154 + public boolean isEnableDisableNoneReader() {
  155 + return enableDisableNoneReader;
160 } 156 }
161 157
162 - public void setEnable_remove_none_reader(boolean enable_remove_none_reader) {  
163 - this.enable_remove_none_reader = enable_remove_none_reader; 158 + public void setEnableDisableNoneReader(boolean enable_disable_none_reader) {
  159 + this.enableDisableNoneReader = enable_disable_none_reader;
164 } 160 }
165 161
166 - public boolean isEnable_disable_none_reader() {  
167 - return enable_disable_none_reader; 162 + public boolean isEnableAudio() {
  163 + return enableAudio;
168 } 164 }
169 165
170 - public void setEnable_disable_none_reader(boolean enable_disable_none_reader) {  
171 - this.enable_disable_none_reader = enable_disable_none_reader; 166 + public void setEnableAudio(boolean enable_audio) {
  167 + this.enableAudio = enable_audio;
172 } 168 }
173 169
174 - public boolean isEnable_audio() {  
175 - return enable_audio;  
176 - }  
177 170
178 - public void setEnable_audio(boolean enable_audio) {  
179 - this.enable_audio = enable_audio;  
180 - }  
181 } 171 }
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java
@@ -325,5 +325,65 @@ public class StreamPushItem extends GbStream implements Comparable&lt;StreamPushIte @@ -325,5 +325,65 @@ public class StreamPushItem extends GbStream implements Comparable&lt;StreamPushIte
325 public void setSelf(boolean self) { 325 public void setSelf(boolean self) {
326 this.self = self; 326 this.self = self;
327 } 327 }
  328 +
  329 +// @Override
  330 +// public Integer getGbStreamId() {
  331 +// return super.getGbStreamId();
  332 +// }
  333 +//
  334 +// @Override
  335 +// public void setGbStreamId(Integer gbStreamId) {
  336 +// super.setGbStreamId(gbStreamId);
  337 +// }
  338 +//
  339 +//
  340 +// public String getGbId() {
  341 +// return super.getGbId();
  342 +// }
  343 +//
  344 +// public void setGbId(String gbId) {
  345 +// super.setGbId(gbId);
  346 +// }
  347 +//
  348 +// public String getName() {
  349 +// return super.getName();
  350 +// }
  351 +//
  352 +// public void setName(String name) {
  353 +// super.setName(name);
  354 +// }
  355 +//
  356 +// public double getLongitude() {
  357 +// return super.getLongitude();
  358 +// }
  359 +//
  360 +// public void setLongitude(double longitude) {
  361 +// super.setLongitude(longitude);
  362 +// }
  363 +//
  364 +// public double getLatitude() {
  365 +// return super.getLatitude();
  366 +// }
  367 +//
  368 +// public void setLatitude(double latitude) {
  369 +// super.setLatitude(latitude);
  370 +// }
  371 +//
  372 +// public String getStreamType() {
  373 +// return super.getStreamType();
  374 +// }
  375 +//
  376 +// public void setStreamType(String streamType) {
  377 +// super.setStreamType(streamType);
  378 +// }
  379 +//
  380 +// public boolean isStatus() {
  381 +// return super.isStatus();
  382 +// }
  383 +//
  384 +// public void setStatus(boolean status) {
  385 +// super.setStatus(status);
  386 +// }
  387 +
328 } 388 }
329 389
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookResultForOnPublish.java
@@ -50,4 +50,6 @@ public class HookResultForOnPublish extends HookResult{ @@ -50,4 +50,6 @@ public class HookResultForOnPublish extends HookResult{
50 public void setMp4_save_path(String mp4_save_path) { 50 public void setMp4_save_path(String mp4_save_path) {
51 this.mp4_save_path = mp4_save_path; 51 this.mp4_save_path = mp4_save_path;
52 } 52 }
  53 +
  54 +
53 } 55 }
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnPlayHookParam.java
@@ -81,6 +81,15 @@ public class OnPlayHookParam extends HookParam{ @@ -81,6 +81,15 @@ public class OnPlayHookParam extends HookParam{
81 81
82 @Override 82 @Override
83 public String toString() { 83 public String toString() {
84 - return String.format("%s://%s:%s/%s/%s?%s", schema, ip, port, app, stream, params); 84 + return "OnPlayHookParam{" +
  85 + "id='" + id + '\'' +
  86 + ", app='" + app + '\'' +
  87 + ", stream='" + stream + '\'' +
  88 + ", ip='" + ip + '\'' +
  89 + ", params='" + params + '\'' +
  90 + ", port=" + port +
  91 + ", schema='" + schema + '\'' +
  92 + ", vhost='" + vhost + '\'' +
  93 + '}';
85 } 94 }
86 } 95 }
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnPublishHookParam.java
@@ -81,6 +81,15 @@ public class OnPublishHookParam extends HookParam{ @@ -81,6 +81,15 @@ public class OnPublishHookParam extends HookParam{
81 81
82 @Override 82 @Override
83 public String toString() { 83 public String toString() {
84 - return String.format("%s://%s:%s/%s/%s?%s", schema, ip, port, app, stream, params); 84 + return "OnPublishHookParam{" +
  85 + "id='" + id + '\'' +
  86 + ", app='" + app + '\'' +
  87 + ", stream='" + stream + '\'' +
  88 + ", ip='" + ip + '\'' +
  89 + ", params='" + params + '\'' +
  90 + ", port=" + port +
  91 + ", schema='" + schema + '\'' +
  92 + ", vhost='" + vhost + '\'' +
  93 + '}';
85 } 94 }
86 } 95 }
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnRtpServerTimeoutHookParam.java
@@ -50,4 +50,15 @@ public class OnRtpServerTimeoutHookParam extends HookParam{ @@ -50,4 +50,15 @@ public class OnRtpServerTimeoutHookParam extends HookParam{
50 public void setSsrc(String ssrc) { 50 public void setSsrc(String ssrc) {
51 this.ssrc = ssrc; 51 this.ssrc = ssrc;
52 } 52 }
  53 +
  54 + @Override
  55 + public String toString() {
  56 + return "OnRtpServerTimeoutHookParam{" +
  57 + "local_port=" + local_port +
  58 + ", stream_id='" + stream_id + '\'' +
  59 + ", tcpMode=" + tcpMode +
  60 + ", re_use_port=" + re_use_port +
  61 + ", ssrc='" + ssrc + '\'' +
  62 + '}';
  63 + }
53 } 64 }
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnSendRtpStoppedHookParam.java
@@ -24,4 +24,12 @@ public class OnSendRtpStoppedHookParam extends HookParam{ @@ -24,4 +24,12 @@ public class OnSendRtpStoppedHookParam extends HookParam{
24 public void setStream(String stream) { 24 public void setStream(String stream) {
25 this.stream = stream; 25 this.stream = stream;
26 } 26 }
  27 +
  28 + @Override
  29 + public String toString() {
  30 + return "OnSendRtpStoppedHookParam{" +
  31 + "app='" + app + '\'' +
  32 + ", stream='" + stream + '\'' +
  33 + '}';
  34 + }
27 } 35 }
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnServerKeepaliveHookParam.java
@@ -17,4 +17,11 @@ public class OnServerKeepaliveHookParam extends HookParam{ @@ -17,4 +17,11 @@ public class OnServerKeepaliveHookParam extends HookParam{
17 public void setData(ServerKeepaliveData data) { 17 public void setData(ServerKeepaliveData data) {
18 this.data = data; 18 this.data = data;
19 } 19 }
  20 +
  21 + @Override
  22 + public String toString() {
  23 + return "OnServerKeepaliveHookParam{" +
  24 + "data=" + data +
  25 + '}';
  26 + }
20 } 27 }
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamChangedHookParam.java
@@ -430,4 +430,14 @@ public class OnStreamChangedHookParam extends HookParam{ @@ -430,4 +430,14 @@ public class OnStreamChangedHookParam extends HookParam{
430 public void setCallId(String callId) { 430 public void setCallId(String callId) {
431 this.callId = callId; 431 this.callId = callId;
432 } 432 }
  433 +
  434 + @Override
  435 + public String toString() {
  436 + return "OnStreamChangedHookParam{" +
  437 + "regist=" + regist +
  438 + ", app='" + app + '\'' +
  439 + ", stream='" + stream + '\'' +
  440 + ", severId='" + severId + '\'' +
  441 + '}';
  442 + }
433 } 443 }
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamNoneReaderHookParam.java
@@ -38,4 +38,14 @@ public class OnStreamNoneReaderHookParam extends HookParam{ @@ -38,4 +38,14 @@ public class OnStreamNoneReaderHookParam extends HookParam{
38 public void setVhost(String vhost) { 38 public void setVhost(String vhost) {
39 this.vhost = vhost; 39 this.vhost = vhost;
40 } 40 }
  41 +
  42 + @Override
  43 + public String toString() {
  44 + return "OnStreamNoneReaderHookParam{" +
  45 + "schema='" + schema + '\'' +
  46 + ", app='" + app + '\'' +
  47 + ", stream='" + stream + '\'' +
  48 + ", vhost='" + vhost + '\'' +
  49 + '}';
  50 + }
41 } 51 }
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamNotFoundHookParam.java
@@ -81,6 +81,15 @@ public class OnStreamNotFoundHookParam extends HookParam{ @@ -81,6 +81,15 @@ public class OnStreamNotFoundHookParam extends HookParam{
81 81
82 @Override 82 @Override
83 public String toString() { 83 public String toString() {
84 - return String.format("%s://%s:%s/%s/%s?%s", schema, ip, port, app, stream, params); 84 + return "OnStreamNotFoundHookParam{" +
  85 + "id='" + id + '\'' +
  86 + ", app='" + app + '\'' +
  87 + ", stream='" + stream + '\'' +
  88 + ", ip='" + ip + '\'' +
  89 + ", params='" + params + '\'' +
  90 + ", port=" + port +
  91 + ", schema='" + schema + '\'' +
  92 + ", vhost='" + vhost + '\'' +
  93 + '}';
85 } 94 }
86 } 95 }
src/main/java/com/genersoft/iot/vmp/service/IDeviceChannelService.java
@@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.service; @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.service;
2 2
3 import com.genersoft.iot.vmp.gb28181.bean.Device; 3 import com.genersoft.iot.vmp.gb28181.bean.Device;
4 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; 4 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
5 -import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; 5 +import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo;
6 import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; 6 import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
7 7
8 import java.util.List; 8 import java.util.List;
@@ -38,7 +38,7 @@ public interface IDeviceChannelService { @@ -38,7 +38,7 @@ public interface IDeviceChannelService {
38 * 获取统计信息 38 * 获取统计信息
39 * @return 39 * @return
40 */ 40 */
41 - ResourceBaceInfo getOverview(); 41 + ResourceBaseInfo getOverview();
42 42
43 /** 43 /**
44 * 查询所有未分配的通道 44 * 查询所有未分配的通道
src/main/java/com/genersoft/iot/vmp/service/IDeviceService.java
@@ -5,7 +5,7 @@ import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; @@ -5,7 +5,7 @@ import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
5 import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo; 5 import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo;
6 import com.genersoft.iot.vmp.gb28181.bean.SyncStatus; 6 import com.genersoft.iot.vmp.gb28181.bean.SyncStatus;
7 import com.genersoft.iot.vmp.vmanager.bean.BaseTree; 7 import com.genersoft.iot.vmp.vmanager.bean.BaseTree;
8 -import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; 8 +import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo;
9 9
10 import java.util.List; 10 import java.util.List;
11 11
@@ -162,7 +162,7 @@ public interface IDeviceService { @@ -162,7 +162,7 @@ public interface IDeviceService {
162 * 获取统计信息 162 * 获取统计信息
163 * @return 163 * @return
164 */ 164 */
165 - ResourceBaceInfo getOverview(); 165 + ResourceBaseInfo getOverview();
166 166
167 /** 167 /**
168 * 获取所有设备 168 * 获取所有设备
src/main/java/com/genersoft/iot/vmp/service/IInviteStreamService.java
@@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.service; @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.service;
2 2
3 import com.genersoft.iot.vmp.common.InviteInfo; 3 import com.genersoft.iot.vmp.common.InviteInfo;
4 import com.genersoft.iot.vmp.common.InviteSessionType; 4 import com.genersoft.iot.vmp.common.InviteSessionType;
5 -import com.genersoft.iot.vmp.service.bean.InviteErrorCallback; 5 +import com.genersoft.iot.vmp.service.bean.ErrorCallback;
6 6
7 /** 7 /**
8 * 记录国标点播的状态,包括实时预览,下载,录像回放 8 * 记录国标点播的状态,包括实时预览,下载,录像回放
@@ -14,6 +14,8 @@ public interface IInviteStreamService { @@ -14,6 +14,8 @@ public interface IInviteStreamService {
14 */ 14 */
15 void updateInviteInfo(InviteInfo inviteInfo); 15 void updateInviteInfo(InviteInfo inviteInfo);
16 16
  17 + InviteInfo updateInviteInfoForStream(InviteInfo inviteInfo, String stream);
  18 +
17 /** 19 /**
18 * 获取点播的状态信息 20 * 获取点播的状态信息
19 */ 21 */
@@ -54,7 +56,7 @@ public interface IInviteStreamService { @@ -54,7 +56,7 @@ public interface IInviteStreamService {
54 /** 56 /**
55 * 添加一个invite回调 57 * 添加一个invite回调
56 */ 58 */
57 - void once(InviteSessionType type, String deviceId, String channelId, String stream, InviteErrorCallback<Object> callback); 59 + void once(InviteSessionType type, String deviceId, String channelId, String stream, ErrorCallback<Object> callback);
58 60
59 /** 61 /**
60 * 调用一个invite回调 62 * 调用一个invite回调
@@ -65,4 +67,12 @@ public interface IInviteStreamService { @@ -65,4 +67,12 @@ public interface IInviteStreamService {
65 * 清空一个设备的所有invite信息 67 * 清空一个设备的所有invite信息
66 */ 68 */
67 void clearInviteInfo(String deviceId); 69 void clearInviteInfo(String deviceId);
  70 +
  71 + /**
  72 + * 统计同一个zlm下的国标收流个数
  73 + */
  74 + int getStreamInfoCount(String mediaServerId);
  75 +
  76 +
  77 +
68 } 78 }
src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
@@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; @@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device;
7 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 7 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
8 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; 8 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
9 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 9 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
10 -import com.genersoft.iot.vmp.service.bean.InviteErrorCallback; 10 +import com.genersoft.iot.vmp.service.bean.ErrorCallback;
11 import com.genersoft.iot.vmp.service.bean.SSRCInfo; 11 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
12 import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult; 12 import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult;
13 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.AudioBroadcastEvent; 13 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.AudioBroadcastEvent;
@@ -25,8 +25,8 @@ import java.util.Map; @@ -25,8 +25,8 @@ import java.util.Map;
25 public interface IPlayService { 25 public interface IPlayService {
26 26
27 void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, 27 void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
28 - InviteErrorCallback<Object> callback);  
29 - SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId, InviteErrorCallback<Object> callback); 28 + ErrorCallback<Object> callback);
  29 + SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId, ErrorCallback<Object> callback);
30 30
31 StreamInfo onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId); 31 StreamInfo onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId);
32 32
@@ -37,13 +37,13 @@ public interface IPlayService { @@ -37,13 +37,13 @@ public interface IPlayService {
37 */ 37 */
38 MediaServerItem getNewMediaServerItemHasAssist(Device device); 38 MediaServerItem getNewMediaServerItemHasAssist(Device device);
39 39
40 - void playBack(String deviceId, String channelId, String startTime, String endTime, InviteErrorCallback<Object> callback);  
41 - void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, InviteErrorCallback<Object> callback); 40 + void playBack(String deviceId, String channelId, String startTime, String endTime, ErrorCallback<Object> callback);
  41 + void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, ErrorCallback<Object> callback);
42 42
43 void zlmServerOffline(String mediaServerId); 43 void zlmServerOffline(String mediaServerId);
44 44
45 - void download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteErrorCallback<Object> callback);  
46 - void download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteErrorCallback<Object> callback); 45 + void download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, ErrorCallback<Object> callback);
  46 + void download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, ErrorCallback<Object> callback);
47 47
48 StreamInfo getDownLoadInfo(String deviceId, String channelId, String stream); 48 StreamInfo getDownLoadInfo(String deviceId, String channelId, String stream);
49 49
@@ -69,4 +69,6 @@ public interface IPlayService { @@ -69,4 +69,6 @@ public interface IPlayService {
69 void talkCmd(Device device, String channelId, MediaServerItem mediaServerItem, String stream, AudioBroadcastEvent event); 69 void talkCmd(Device device, String channelId, MediaServerItem mediaServerItem, String stream, AudioBroadcastEvent event);
70 70
71 void stopTalk(Device device, String channelId, Boolean streamIsReady); 71 void stopTalk(Device device, String channelId, Boolean streamIsReady);
  72 +
  73 + void getSnap(String deviceId, String channelId, String fileName, ErrorCallback errorCallback);
72 } 74 }
src/main/java/com/genersoft/iot/vmp/service/IRecordInfoServer.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.service;  
2 -  
3 -import com.genersoft.iot.vmp.storager.dao.dto.RecordInfo;  
4 -import com.github.pagehelper.PageInfo;  
5 -  
6 -public interface IRecordInfoServer {  
7 - PageInfo<RecordInfo> getRecordList(int page, int count);  
8 -}  
src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java
1 package com.genersoft.iot.vmp.service; 1 package com.genersoft.iot.vmp.service;
2 2
3 import com.alibaba.fastjson2.JSONObject; 3 import com.alibaba.fastjson2.JSONObject;
  4 +import com.genersoft.iot.vmp.common.GeneralCallback;
4 import com.genersoft.iot.vmp.common.StreamInfo; 5 import com.genersoft.iot.vmp.common.StreamInfo;
5 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 6 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
6 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; 7 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
7 -import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; 8 +import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo;
8 import com.github.pagehelper.PageInfo; 9 import com.github.pagehelper.PageInfo;
9 10
10 public interface IStreamProxyService { 11 public interface IStreamProxyService {
@@ -13,7 +14,7 @@ public interface IStreamProxyService { @@ -13,7 +14,7 @@ public interface IStreamProxyService {
13 * 保存视频代理 14 * 保存视频代理
14 * @param param 15 * @param param
15 */ 16 */
16 - StreamInfo save(StreamProxyItem param); 17 + void save(StreamProxyItem param, GeneralCallback<StreamInfo> callback);
17 18
18 /** 19 /**
19 * 添加视频代理到zlm 20 * 添加视频代理到zlm
@@ -108,6 +109,6 @@ public interface IStreamProxyService { @@ -108,6 +109,6 @@ public interface IStreamProxyService {
108 * 获取统计信息 109 * 获取统计信息
109 * @return 110 * @return
110 */ 111 */
111 - ResourceBaceInfo getOverview(); 112 + ResourceBaseInfo getOverview();
112 113
113 } 114 }
src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
@@ -5,7 +5,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; @@ -5,7 +5,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
5 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 5 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
6 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; 6 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
7 import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis; 7 import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis;
8 -import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; 8 +import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo;
9 import com.github.pagehelper.PageInfo; 9 import com.github.pagehelper.PageInfo;
10 10
11 import java.util.List; 11 import java.util.List;
@@ -113,5 +113,5 @@ public interface IStreamPushService { @@ -113,5 +113,5 @@ public interface IStreamPushService {
113 * 获取统计信息 113 * 获取统计信息
114 * @return 114 * @return
115 */ 115 */
116 - ResourceBaceInfo getOverview(); 116 + ResourceBaseInfo getOverview();
117 } 117 }
src/main/java/com/genersoft/iot/vmp/service/bean/InviteErrorCallback.java renamed to src/main/java/com/genersoft/iot/vmp/service/bean/ErrorCallback.java
1 package com.genersoft.iot.vmp.service.bean; 1 package com.genersoft.iot.vmp.service.bean;
2 2
3 -public interface InviteErrorCallback<T> { 3 +public interface ErrorCallback<T> {
4 4
5 void run(int code, String msg, T data); 5 void run(int code, String msg, T data);
6 } 6 }
src/main/java/com/genersoft/iot/vmp/service/bean/InviteErrorCode.java
@@ -5,6 +5,7 @@ package com.genersoft.iot.vmp.service.bean; @@ -5,6 +5,7 @@ package com.genersoft.iot.vmp.service.bean;
5 */ 5 */
6 public enum InviteErrorCode { 6 public enum InviteErrorCode {
7 SUCCESS(0, "成功"), 7 SUCCESS(0, "成功"),
  8 + FAIL(-100, "失败"),
8 ERROR_FOR_SIGNALLING_TIMEOUT(-1, "信令超时"), 9 ERROR_FOR_SIGNALLING_TIMEOUT(-1, "信令超时"),
9 ERROR_FOR_STREAM_TIMEOUT(-2, "收流超时"), 10 ERROR_FOR_STREAM_TIMEOUT(-2, "收流超时"),
10 ERROR_FOR_RESOURCE_EXHAUSTION(-3, "资源耗尽"), 11 ERROR_FOR_RESOURCE_EXHAUSTION(-3, "资源耗尽"),