hm-ng-video
Version:
(1)引入 npm 包,在==package.json==里面添加:
707 lines • 60.5 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: lib/hm-ng-video.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, ViewChild, Input, ElementRef, ViewEncapsulation, EventEmitter, Output, Renderer2, } from "@angular/core";
// import videojs from "hm-videojs";
import videojs from "video.js";
var HmNgVideoComponent = /** @class */ (function () {
function HmNgVideoComponent(el, renderer) {
this.el = el;
this.renderer = renderer;
this.PauseEventListener = new EventEmitter(); // 暂停回调
// 暂停回调
this.PlayingEventListener = new EventEmitter(); // 开始播放回调
// 开始播放回调
this.WaitingEventListener = new EventEmitter(); // 缓冲回调
// 缓冲回调
this.ErrorEventListener = new EventEmitter(); // 错误回调
// 错误回调
this.DataLoadedEventListener = new EventEmitter(); // 数据加载完成回调
// 数据加载完成回调
this.CanPlayEventListener = new EventEmitter(); // 可以播放回调
// 可以播放回调
this.ReLoadVideoEventListener = new EventEmitter(); // 重新加载
// 重新加载
this.FullScreenToggeleEventListener = new EventEmitter(); // 切换全屏
// 切换全屏
this.liveLoaded = false;
}
/**
* @param {?} type
* @return {?}
*/
HmNgVideoComponent.prototype.createDom = /**
* @param {?} type
* @return {?}
*/
function (type) {
var _this = this;
if (type === "file") {
this.fileVideo.nativeElement.innerHTML = "<video id='" + this.className + "-fileVideo' class='video-js vjs-big-play-centered' controls muted preload='none' x-webkit-airplay='true' webkit-playsinline='isiPhoneShowPlaysinline' playsinline='isiPhoneShowPlaysinline' x5-playsinline='true' x5-video-player-type='h5'></video>";
}
else {
/** @type {?} */
var guide = "<div class='loading " + this.className + "-loading'><img src='" +
(this.loadingSrc || "") +
"' alt='' ></div>";
/** @type {?} */
var error = "<div class='error " + this.className + "-error'><span>" +
(this.errorContent || "") +
"</span></div>";
this.liveVideo.nativeElement.innerHTML =
"<video id='" + this.className + "-liveVideo' class='video-js vjs-big-play-centered' controls muted preload='none' x-webkit-airplay='true' webkit-playsinline='isiPhoneShowPlaysinline' playsinline='isiPhoneShowPlaysinline' x5-playsinline='true' x5-video-player-type='h5'></video>" +
guide +
error;
this.el.nativeElement
.querySelector("." + this.className + "-error")
.addEventListener("click", (/**
* @return {?}
*/
function () {
_this.setBgVisible("error", false);
_this.createLivePlayer(true);
}));
}
};
/**
* @return {?}
*/
HmNgVideoComponent.prototype.init = /**
* @return {?}
*/
function () {
var _this = this;
this.liveLoaded = false;
// 只播放其中一种就传一种类型的option
if (this.fileOptions) {
this.createDom("file");
/** @type {?} */
var fileVideoEl = this.el.nativeElement.querySelector("#" + this.className + "-fileVideo");
this.filePlayer = videojs(fileVideoEl, Object.assign(this.fileOptions, {
autoplay: this.autoplay,
errorDisplay: false,
controlBar: {
playToggle: true,
volumePanel: false,
// 不需要静音按钮
pictureInPictureToggle: false,
// 不需要画中画
fullscreenToggle: false,
},
}));
this.setDefaultProperty(this.filePlayer);
this.filePlayer.on("error", (/**
* @param {?} $event
* @return {?}
*/
function ($event) {
_this.ErrorEventListener.emit($event);
console.log("文件流出错了!");
_this.dispose(_this.filePlayer);
_this.fileOptions = null;
_this.createLivePlayer(true, true);
}));
this.filePlayer.on("playing", (/**
* @param {?} $event
* @return {?}
*/
function ($event) {
_this.PlayingEventListener.emit($event);
if (!_this.livePlayer) {
_this.createLivePlayer(true); // 文件流和直播流都存在的情况下,如果不是自动播放,则强行创造自动播放的直播流
}
}));
this.filePlayer.on("pause", (/**
* @param {?} $event
* @return {?}
*/
function ($event) {
_this.PauseEventListener.emit($event);
}));
}
else {
this.createLivePlayer(); // 如果没有文件流,则按照设置的是否自动播放执行
}
};
// 创建直播流 ,内部传就按照内部传的,不传则根据调用的决定
// 创建直播流 ,内部传就按照内部传的,不传则根据调用的决定
/**
* @param {?=} isAutoPlay
* @param {?=} isLoading
* @return {?}
*/
HmNgVideoComponent.prototype.createLivePlayer =
// 创建直播流 ,内部传就按照内部传的,不传则根据调用的决定
/**
* @param {?=} isAutoPlay
* @param {?=} isLoading
* @return {?}
*/
function (isAutoPlay, isLoading) {
var _this = this;
if (!this.liveOptions) {
return;
}
this.createDom("live");
if (isLoading) {
this.setBgVisible("loading", true);
}
/** @type {?} */
var liveVideoEl = this.el.nativeElement.querySelector("#" + this.className + "-liveVideo");
/** @type {?} */
var startTime = 0;
/** @type {?} */
var endTime = 0;
this.livePlayer = videojs(liveVideoEl, Object.assign(this.liveOptions, {
autoplay: isAutoPlay ? isAutoPlay : this.autoplay,
errorDisplay: false,
liveui: true,
controlBar: {
playToggle: true,
volumePanel: false,
// 不需要静音按钮
pictureInPictureToggle: false,
// 不需要画中画
fullscreenToggle: false,
},
}));
this.addFullScreen();
this.setDefaultProperty(this.livePlayer);
this.livePlayer.on("loadstart", (/**
* @param {?} $event
* @return {?}
*/
function ($event) {
console.log("直播流开始load");
startTime = new Date().getTime();
// this.setBgVisible("loading", true);
if (!_this.isVideoLoadingTimeout) {
_this.isVideoLoadingTimeout = setTimeout((/**
* @return {?}
*/
function () {
if (_this.livePlayer &&
_this.livePlayer.readyState() !== 3 &&
_this.livePlayer.readyState() !== 4) {
_this.openModal();
_this.ErrorEventListener.emit("overtime");
console.log("加载超时!");
}
}), _this.maxLoadTime || 15000);
}
}));
this.livePlayer.on("loadedmetadata", (/**
* @param {?} $event
* @return {?}
*/
function ($event) {
endTime = new Date().getTime();
console.log("直播流加载成功");
_this.setBgVisible("loading", false);
_this.DataLoadedEventListener.emit(Object.assign($event, { bufferTime: endTime - startTime }));
}));
this.livePlayer.on("canplaythrough", (/**
* @param {?} $event
* @return {?}
*/
function ($event) {
if (_this.livePlayer.readyState() === 3 ||
_this.livePlayer.readyState() === 4) {
setTimeout((/**
* @return {?}
*/
function () {
if (_this.filePlayer) {
_this.dispose(_this.filePlayer);
}
_this.liveLoaded = true;
_this.setBgVisible("loading", false);
}), 1000);
_this.CanPlayEventListener.emit($event);
}
console.log(_this.livePlayer.readyState(), "canplaythrough");
}));
this.livePlayer.on("playing", (/**
* @param {?} $event
* @return {?}
*/
function ($event) {
console.log("直播流正在播放!");
_this.destroyTimeout();
_this.setBgVisible("loading", false);
_this.PlayingEventListener.emit($event);
}));
this.livePlayer.on("error", (/**
* @param {?} $event
* @return {?}
*/
function ($event) {
_this.ErrorEventListener.emit($event);
console.log("直播流出错了!");
_this.openModal();
}));
this.livePlayer.on("pause", (/**
* @param {?} $event
* @return {?}
*/
function ($event) {
_this.PauseEventListener.emit($event);
}));
this.livePlayer.on("timeupdate", (/**
* @param {?} $event
* @return {?}
*/
function ($event) {
if (!_this.isVideoBreak) {
if (_this.livePlayer.readyState() !== 3 &&
_this.livePlayer.readyState() !== 4) {
_this.WaitingEventListener.emit($event);
_this.isVideoBreak = setTimeout((/**
* @return {?}
*/
function () {
if (_this.livePlayer &&
_this.livePlayer.readyState() !== 3 &&
_this.livePlayer.readyState() !== 4) {
_this.openModal();
_this.ErrorEventListener.emit("overtime");
console.log("缓冲超时!");
}
}), _this.maxLoadTime || 15000);
}
}
}));
};
// 获取player实例
// 获取player实例
/**
* @return {?}
*/
HmNgVideoComponent.prototype.getFilePlayer =
// 获取player实例
/**
* @return {?}
*/
function () {
return this.filePlayer || undefined;
};
/**
* @return {?}
*/
HmNgVideoComponent.prototype.getLivePlayer = /**
* @return {?}
*/
function () {
return this.livePlayer || undefined;
};
// 默认配置
// 默认配置
/**
* @param {?} player
* @return {?}
*/
HmNgVideoComponent.prototype.setDefaultProperty =
// 默认配置
/**
* @param {?} player
* @return {?}
*/
function (player) {
player.playsinline(true);
//player.crossOrigin("anonymous");
};
// 销毁
// 销毁
/**
* @param {?} player
* @return {?}
*/
HmNgVideoComponent.prototype.dispose =
// 销毁
/**
* @param {?} player
* @return {?}
*/
function (player) {
if (!player) {
return;
}
if (!player.isDisposed()) {
player.dispose();
player = undefined;
}
};
// 销毁定时器
// 销毁定时器
/**
* @return {?}
*/
HmNgVideoComponent.prototype.destroyTimeout =
// 销毁定时器
/**
* @return {?}
*/
function () {
clearTimeout(this.isVideoBreak);
clearTimeout(this.isVideoLoadingTimeout);
clearInterval(this.fullScreenTimer);
this.isVideoBreak = undefined;
this.isVideoLoadingTimeout = undefined;
this.fullScreenTimer = undefined;
};
// 全部销毁
// 全部销毁
/**
* @return {?}
*/
HmNgVideoComponent.prototype.destroy =
// 全部销毁
/**
* @return {?}
*/
function () {
this.destroyTimeout();
this.dispose(this.filePlayer);
this.dispose(this.livePlayer);
};
// 绑定错误事件
// 自定义错误显示方式
// 0,1,2,3,4,5
// MEDIA_ERR_CUSTOM、
// MEDIA_ERR_ABORTED、取回过程被用户中止
// MEDIA_ERR_NETWORK、当下载时发生错误
// MEDIA_ERR_DECODE、当解码时发生错误
// MEDIA_ERR_SRC_NOT_SUPPORTED、不支持音频/视频
// MEDIA_ERR_ENCRYPTED // 被加密
// 错误弹窗
// 绑定错误事件
// 自定义错误显示方式
// 0,1,2,3,4,5
// MEDIA_ERR_CUSTOM、
// MEDIA_ERR_ABORTED、取回过程被用户中止
// MEDIA_ERR_NETWORK、当下载时发生错误
// MEDIA_ERR_DECODE、当解码时发生错误
// MEDIA_ERR_SRC_NOT_SUPPORTED、不支持音频/视频
// MEDIA_ERR_ENCRYPTED // 被加密
// 错误弹窗
/**
* @return {?}
*/
HmNgVideoComponent.prototype.openModal =
// 绑定错误事件
// 自定义错误显示方式
// 0,1,2,3,4,5
// MEDIA_ERR_CUSTOM、
// MEDIA_ERR_ABORTED、取回过程被用户中止
// MEDIA_ERR_NETWORK、当下载时发生错误
// MEDIA_ERR_DECODE、当解码时发生错误
// MEDIA_ERR_SRC_NOT_SUPPORTED、不支持音频/视频
// MEDIA_ERR_ENCRYPTED // 被加密
// 错误弹窗
/**
* @return {?}
*/
function () {
this.fileOptions = null;
this.destroy();
this.setBgVisible("loading", false);
this.setBgVisible("error", true);
};
// 设置加载背景/错误背景显示隐藏
// 设置加载背景/错误背景显示隐藏
/**
* @param {?} type
* @param {?} isShow
* @return {?}
*/
HmNgVideoComponent.prototype.setBgVisible =
// 设置加载背景/错误背景显示隐藏
/**
* @param {?} type
* @param {?} isShow
* @return {?}
*/
function (type, isShow) {
/** @type {?} */
var el = type === "loading"
? this.el.nativeElement.querySelector("." + this.className + "-loading")
: this.el.nativeElement.querySelector("." + this.className + "-error");
this.renderer.setStyle(el, "display", isShow ? "block" : "none");
};
// 判断是ios设备
// 判断是ios设备
/**
* @return {?}
*/
HmNgVideoComponent.prototype.isIOS =
// 判断是ios设备
/**
* @return {?}
*/
function () {
/** @type {?} */
var u = navigator.userAgent;
/** @type {?} */
var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
console.log("ios", isIOS);
return isIOS;
};
// 添加自定义全屏和播放按钮
// 添加自定义全屏和播放按钮
/**
* @return {?}
*/
HmNgVideoComponent.prototype.addFullScreen =
// 添加自定义全屏和播放按钮
/**
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var vjsButtonComponent = videojs.getComponent("Button");
videojs.registerComponent("FullScreenButton", videojs.extend(vjsButtonComponent, {
handleClick: (/**
* @return {?}
*/
function () {
if (!_this.livePlayer.isFullscreen()) {
try {
_this.toFullScreen();
if (_this.isIOS()) {
_this.fullScreenTimer = setInterval((/**
* @return {?}
*/
function () {
if (!_this.livePlayer.isFullscreen()) {
// 退出了全屏
_this.FullScreenToggeleEventListener.emit(false);
_this.destroy();
_this.createLivePlayer(true);
// clearInterval(this.fullScreenTimer);
// setTimeout(() => {
// this.livePlayer.play();
// }, 1000);
}
}), 1000);
}
}
catch (error) {
console.warn(error);
}
}
else {
_this.FullScreenToggeleEventListener.emit(false);
_this.livePlayer.exitFullscreen();
}
}),
buildCSSClass: (/**
* @return {?}
*/
function () {
return "my_fullscreen";
}),
}));
this.livePlayer.getChild("controlBar").addChild("FullScreenButton", {});
};
// 自定义全屏
// 自定义全屏
/**
* @return {?}
*/
HmNgVideoComponent.prototype.toFullScreen =
// 自定义全屏
/**
* @return {?}
*/
function () {
this.FullScreenToggeleEventListener.emit(true);
if (this.livePlayer.requestFullscreen) {
return this.livePlayer.requestFullscreen();
}
else if (this.livePlayer.webkitRequestFullScreen) {
return this.livePlayer.webkitRequestFullScreen();
}
else if (this.livePlayer.mozRequestFullScreen) {
return this.livePlayer.mozRequestFullScreen();
}
else {
return this.livePlayer.msRequestFullscreen();
}
};
/**
* @return {?}
*/
HmNgVideoComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
console.log("hm-ng-video 1.5.6");
};
/**
* @param {?} changes
* @return {?}
*/
HmNgVideoComponent.prototype.ngOnChanges = /**
* @param {?} changes
* @return {?}
*/
function (changes) {
var _this = this;
if (this.exitFullScreen) {
console.log("按返回键退出全屏");
this.FullScreenToggeleEventListener.emit(false);
this.livePlayer.exitFullscreen();
}
if ((changes.fileOptions &&
changes.fileOptions.firstChange &&
changes.fileOptions.currentValue) ||
(changes.liveOptions &&
changes.liveOptions.firstChange &&
changes.liveOptions.currentValue)) {
this.init();
}
if ((changes.fileOptions &&
changes.fileOptions.currentValue &&
!changes.fileOptions.firstChange) ||
(changes.liveOptions &&
changes.liveOptions.currentValue &&
!changes.liveOptions.firstChange)) {
this.destroy();
setTimeout((/**
* @return {?}
*/
function () {
_this.init();
}), 1000);
}
};
/**
* @return {?}
*/
HmNgVideoComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.destroy();
};
HmNgVideoComponent.decorators = [
{ type: Component, args: [{
selector: "hm-ng-video",
template: "<!--\r\n * @Descripttion:\r\n * @version:\r\n * @Author: yding\r\n * @Date: 2020-05-08 19:05:06\r\n * @LastEditors: yding\r\n * @LastEditTime: 2020-06-19 10:44:58\r\n-->\r\n<!-- <button\r\n class=\"button\"\r\n style=\"background: red;\"\r\n (click)=\"fullScreen()\"\r\n value=\"\u5168\u5C4F\"\r\n>\r\n \u5168\u5C4F\r\n</button> -->\r\n<div\r\n class=\"vjs-video\"\r\n #fileVideoEl\r\n [ngStyle]=\"{\r\n height: videoHeight + 'px',\r\n width: videoWidth + 'px',\r\n position: 'relative'\r\n }\"\r\n [hidden]=\"(liveLoaded && liveOptions && fileOptions) || !fileOptions\"\r\n></div>\r\n<div\r\n class=\"vjs-video\"\r\n #liveVideoEl\r\n [ngStyle]=\"{\r\n height: videoHeight + 'px',\r\n width: videoWidth + 'px',\r\n position: 'relative'\r\n }\"\r\n [hidden]=\"(!liveLoaded && liveOptions && fileOptions) || !liveOptions\"\r\n></div>\r\n",
encapsulation: ViewEncapsulation.None,
styles: [".video-js{width:100%;height:100%}.retry:focus,.vjs-big-play-button:focus,video:focus{outline:0}.vjs-paused .vjs-big-play-button,.vjs-paused.vjs-has-started .vjs-big-play-button{display:none}.video-js .vjs-big-play-button{font-size:2.5em;line-height:2.3em;height:2.5em;width:2.5em;border-radius:2.5em;background-color:rgba(115,133,159,.5);border-width:.15em;margin-top:-1.25em;margin-left:-1.75em}.vjs-big-play-button .vjs-icon-placeholder{font-size:1.63em}.vjs-progress-control.vjs-control,.vjs-remaining-time.vjs-time-control.vjs-control{display:none}.vjs-loading-spinner{border:none;visibility:visible;border-radius:0}.vjs-waiting .vjs-loading-spinner{-webkit-animation:none!important;animation:none!important}.video-js .vjs-control.vjs-close-button{display:none}.loading{width:100%;height:100%;top:0;left:0;position:absolute;pointer-events:none;z-index:71;background:#000;display:none}.loading img{width:35px;height:35px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.error{width:100%;height:100%;top:0;left:0;position:absolute;background:#000;cursor:pointer;z-index:70;display:none}.error span{display:block;text-align:center;padding-top:30%;color:#fff}.vjs-control-bar>button.my_fullscreen::before{display:block!important;content:\"\u5168\u5C4F/\u9000\u51FA\";cursor:pointer}"]
}] }
];
/** @nocollapse */
HmNgVideoComponent.ctorParameters = function () { return [
{ type: ElementRef },
{ type: Renderer2 }
]; };
HmNgVideoComponent.propDecorators = {
fileVideo: [{ type: ViewChild, args: ["fileVideoEl",] }],
liveVideo: [{ type: ViewChild, args: ["liveVideoEl",] }],
fileOptions: [{ type: Input }],
liveOptions: [{ type: Input }],
autoplay: [{ type: Input }],
videoHeight: [{ type: Input }],
videoWidth: [{ type: Input }],
className: [{ type: Input }],
loadingSrc: [{ type: Input }],
maxReloadTimes: [{ type: Input }],
errorContent: [{ type: Input }],
maxLoadTime: [{ type: Input }],
exitFullScreen: [{ type: Input }],
PauseEventListener: [{ type: Output }],
PlayingEventListener: [{ type: Output }],
WaitingEventListener: [{ type: Output }],
ErrorEventListener: [{ type: Output }],
DataLoadedEventListener: [{ type: Output }],
CanPlayEventListener: [{ type: Output }],
ReLoadVideoEventListener: [{ type: Output }],
FullScreenToggeleEventListener: [{ type: Output }]
};
return HmNgVideoComponent;
}());
export { HmNgVideoComponent };
if (false) {
/** @type {?} */
HmNgVideoComponent.prototype.fileVideo;
/** @type {?} */
HmNgVideoComponent.prototype.liveVideo;
/** @type {?} */
HmNgVideoComponent.prototype.fileOptions;
/** @type {?} */
HmNgVideoComponent.prototype.liveOptions;
/** @type {?} */
HmNgVideoComponent.prototype.autoplay;
/** @type {?} */
HmNgVideoComponent.prototype.videoHeight;
/** @type {?} */
HmNgVideoComponent.prototype.videoWidth;
/** @type {?} */
HmNgVideoComponent.prototype.className;
/** @type {?} */
HmNgVideoComponent.prototype.loadingSrc;
/** @type {?} */
HmNgVideoComponent.prototype.maxReloadTimes;
/** @type {?} */
HmNgVideoComponent.prototype.errorContent;
/** @type {?} */
HmNgVideoComponent.prototype.maxLoadTime;
/** @type {?} */
HmNgVideoComponent.prototype.exitFullScreen;
/** @type {?} */
HmNgVideoComponent.prototype.PauseEventListener;
/** @type {?} */
HmNgVideoComponent.prototype.PlayingEventListener;
/** @type {?} */
HmNgVideoComponent.prototype.WaitingEventListener;
/** @type {?} */
HmNgVideoComponent.prototype.ErrorEventListener;
/** @type {?} */
HmNgVideoComponent.prototype.DataLoadedEventListener;
/** @type {?} */
HmNgVideoComponent.prototype.CanPlayEventListener;
/** @type {?} */
HmNgVideoComponent.prototype.ReLoadVideoEventListener;
/** @type {?} */
HmNgVideoComponent.prototype.FullScreenToggeleEventListener;
/** @type {?} */
HmNgVideoComponent.prototype.liveLoaded;
/**
* @type {?}
* @private
*/
HmNgVideoComponent.prototype.filePlayer;
/**
* @type {?}
* @private
*/
HmNgVideoComponent.prototype.livePlayer;
/**
* @type {?}
* @private
*/
HmNgVideoComponent.prototype.isVideoBreak;
/**
* @type {?}
* @private
*/
HmNgVideoComponent.prototype.isVideoLoadingTimeout;
/**
* @type {?}
* @private
*/
HmNgVideoComponent.prototype.fullScreenTimer;
/**
* @type {?}
* @private
*/
HmNgVideoComponent.prototype.el;
/** @type {?} */
HmNgVideoComponent.prototype.renderer;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG0tbmctdmlkZW8uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vaG0tbmctdmlkZW8vIiwic291cmNlcyI6WyJsaWIvaG0tbmctdmlkZW8uY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUNMLFNBQVMsRUFFVCxTQUFTLEVBQ1QsS0FBSyxFQUNMLFVBQVUsRUFDVixpQkFBaUIsRUFFakIsWUFBWSxFQUNaLE1BQU0sRUFHTixTQUFTLEdBQ1YsTUFBTSxlQUFlLENBQUM7O0FBRXZCLE9BQU8sT0FBTyxNQUFNLFVBQVUsQ0FBQztBQUMvQjtJQXlERSw0QkFBb0IsRUFBYyxFQUFTLFFBQW1CO1FBQTFDLE9BQUUsR0FBRixFQUFFLENBQVk7UUFBUyxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBbEJwRCx1QkFBa0IsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDLENBQUMsT0FBTzs7UUFDeEQseUJBQW9CLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQyxDQUFDLFNBQVM7O1FBQzVELHlCQUFvQixHQUFHLElBQUksWUFBWSxFQUFVLENBQUMsQ0FBQyxPQUFPOztRQUMxRCx1QkFBa0IsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDLENBQUMsT0FBTzs7UUFDeEQsNEJBQXVCLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQyxDQUFDLFdBQVc7O1FBQ2pFLHlCQUFvQixHQUFHLElBQUksWUFBWSxFQUFVLENBQUMsQ0FBQyxTQUFTOztRQUM1RCw2QkFBd0IsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDLENBQUMsT0FBTzs7UUFFOUQsbUNBQThCLEdBQUcsSUFBSSxZQUFZLEVBQVcsQ0FBQyxDQUFDLE9BQU87O1FBRXhFLGVBQVUsR0FBRyxLQUFLLENBQUM7SUFRdUMsQ0FBQzs7Ozs7SUFFM0Qsc0NBQVM7Ozs7SUFBaEIsVUFBaUIsSUFBcUI7UUFBdEMsaUJBdUJDO1FBdEJDLElBQUksSUFBSSxLQUFLLE1BQU0sRUFBRTtZQUNuQixJ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OzJCQVNMLEtBQUs7OEJBQ0wsS0FBSzs2QkFDTCxLQUFLOzRCQUNMLEtBQUs7NkJBQ0wsS0FBSztpQ0FDTCxLQUFLOytCQUNMLEtBQUs7OEJBQ0wsS0FBSztpQ0FFTCxLQUFLO3FDQUVMLE1BQU07dUNBQ04sTUFBTTt1Q0FDTixNQUFNO3FDQUNOLE1BQU07MENBQ04sTUFBTTt1Q0FDTixNQUFNOzJDQUNOLE1BQU07aURBRU4sTUFBTTs7SUE0VlQseUJBQUM7Q0FBQSxBQTNZRCxJQTJZQztTQXJZWSxrQkFBa0I7OztJQUM3Qix1Q0FBZ0Q7O0lBQ2hELHVDQUFnRDs7SUFDaEQseUNBU0U7O0lBQ0YseUNBUUU7O0lBQ0Ysc0NBQTJCOztJQUMzQix5Q0FBNkI7O0lBQzdCLHdDQUE0Qjs7SUFDNUIsdUNBQTJCOztJQUMzQix3Q0FBNEI7O0lBQzVCLDRDQUFpQzs7SUFDakMsMENBQStCOztJQUMvQix5Q0FBOEI7O0lBRTlCLDRDQUFrQzs7SUFFbEMsZ0RBQTBEOztJQUMxRCxrREFBNEQ7O0lBQzVELGtEQUE0RDs7SUFDNUQsZ0RBQTBEOztJQUMxRCxxREFBK0Q7O0lBQy9ELGtEQUE0RDs7SUFDNUQsc0RBQWdFOztJQUVoRSw0REFBdUU7O0lBRXZFLHdDQUEwQjs7Ozs7SUFDMUIsd0NBQW1DOzs7OztJQUNuQyx3Q0FBbUM7Ozs7O0lBQ25DLDBDQUEwQjs7Ozs7SUFDMUIsbURBQW1DOzs7OztJQUVuQyw2Q0FBNkI7Ozs7O0lBRWpCLGdDQUFzQjs7SUFBRSxzQ0FBMEIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIE9uSW5pdCxcbiAgVmlld0NoaWxkLFxuICBJbnB1dCxcbiAgRWxlbWVudFJlZixcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG4gIE9uRGVzdHJveSxcbiAgRXZlbnRFbWl0dGVyLFxuICBPdXRwdXQsXG4gIE9uQ2hhbmdlcyxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgUmVuZGVyZXIyLFxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuLy8gaW1wb3J0IHZpZGVvanMgZnJvbSBcImhtLXZpZGVvanNcIjtcbmltcG9ydCB2aWRlb2pzIGZyb20gXCJ2aWRlby5qc1wiO1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiBcImhtLW5nLXZpZGVvXCIsXG4gIHRlbXBsYXRlVXJsOiBcIi4vaG0tbmctdmlkZW8uY29tcG9uZW50Lmh0bWxcIixcbiAgc3R5bGVVcmxzOiBbXCIuL2htLW5nLXZpZGVvLmNvbXBvbmVudC5jc3NcIl0sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG59KVxuZXhwb3J0IGNsYXNzIEhtTmdWaWRlb0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBPbkNoYW5nZXMge1xuICBAVmlld0NoaWxkKFwiZmlsZVZpZGVvRWxcIikgZmlsZVZpZGVvOiBFbGVtZW50UmVmO1xuICBAVmlld0NoaWxkKFwibGl2ZVZpZGVvRWxcIikgbGl2ZVZpZGVvOiBFbGVtZW50UmVmO1xuICBASW5wdXQoKSBmaWxlT3B0aW9ucz86IHtcbiAgICBsb29wOiBib29sZWFuO1xuICAgIGNvbnRyb2xzOiBib29sZWFuO1xuICAgIHBvc3Rlcjogc3RyaW5nO1xuICAgIHByZWxvYWQ6IFwiYXV0b1wiIHwgXCJtZXRhZGF0YVwiIHwgXCJub25lXCI7XG4gICAgc291cmNlczoge1xuICAgICAgc3JjOiBzdHJpbmc7XG4gICAgICB0eXBlOiBzdHJpbmc7XG4gICAgfVtdO1xuICB9O1xuICBASW5wdXQoKSBsaXZlT3B0aW9ucz86IHtcbiAgICBjb250cm9sczogYm9vbGVhbjtcbiAgICBwb3N0ZXI6IHN0cmluZztcbiAgICBwcmVsb2FkOiBcImF1dG9cIiB8IFwibWV0YWRhdGFcIiB8IFwibm9uZVwiO1xuICAgIHNvdXJjZXM6IHtcbiAgICAgIHNyYzogc3RyaW5nO1xuICAgICAgdHlwZTogc3RyaW5nO1xuICAgIH1bXTtcbiAgfTtcbiAgQElucHV0KCkgYXV0b3BsYXk6IGJvb2xlYW47XG4gIEBJbnB1dCgpIHZpZGVvSGVpZ2h0OiBudW1iZXI7XG4gIEBJbnB1dCgpIHZpZGVvV2lkdGg6IG51bWJlcjtcbiAgQElucHV0KCkgY2xhc3NOYW1lOiBzdHJpbmc7XG4gIEBJbnB1dCgpIGxvYWRpbmdTcmM6IHN0cmluZztcbiAgQElucHV0KCkgbWF4UmVsb2FkVGltZXM/OiBudW1iZXI7XG4gIEBJbnB1dCgpIGVycm9yQ29udGVudD86IHN0cmluZztcbiAgQElucHV0KCkgbWF4TG9hZFRpbWU/OiBudW1iZXI7XG5cbiAgQElucHV0KCkgZXhpdEZ1bGxTY3JlZW4/OiBib29sZWFuO1xuXG4gIEBPdXRwdXQoKSBQYXVzZUV2ZW50TGlzdGVuZXIgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTsgLy8g5pqC5YGc5Zue6LCDXG4gIEBPdXRwdXQoKSBQbGF5aW5nRXZlbnRMaXN0ZW5lciA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpOyAvLyDlvIDlp4vmkq3mlL7lm57osINcbiAgQE91dHB1dCgpIFdhaXRpbmdFdmVudExpc3RlbmVyID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7IC8vIOe8k+WGsuWbnuiwg1xuICBAT3V0cHV0KCkgRXJyb3JFdmVudExpc3RlbmVyID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7IC8vIOmUmeivr+Wbnuiwg1xuICBAT3V0cHV0KCkgRGF0YUxvYWRlZEV2ZW50TGlzdGVuZXIgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTsgLy8g5pWw5o2u5Yqg6L295a6M5oiQ5Zue6LCDXG4gIEBPdXRwdXQoKSBDYW5QbGF5RXZlbnRMaXN0ZW5lciA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpOyAvLyDlj6/ku6Xmkq3mlL7lm57osINcbiAgQE91dHB1dCgpIFJlTG9hZFZpZGVvRXZlbnRMaXN0ZW5lciA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpOyAvLyDph43mlrDliqDovb1cblxuICBAT3V0cHV0KCkgRnVsbFNjcmVlblRvZ2dlbGVFdmVudExpc3RlbmVyID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpOyAvLyDliIfmjaLlhajlsY9cblxuICBwdWJsaWMgbGl2ZUxvYWRlZCA9IGZhbHNlO1xuICBwcml2YXRlIGZpbGVQbGF5ZXI6IHZpZGVvanMuUGxheWVyO1xuICBwcml2YXRlIGxpdmVQbGF5ZXI6IHZpZGVvanMuUGxheWVyO1xuICBwcml2YXRlIGlzVmlkZW9CcmVhazogYW55O1xuICBwcml2YXRlIGlzVmlkZW9Mb2FkaW5nVGltZW91dDogYW55O1xuXG4gIHByaXZhdGUgZnVsbFNjcmVlblRpbWVyOiBhbnk7IC8vIOebkeWQrOWFqOWxj1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZWw6IEVsZW1lbnRSZWYsIHB1YmxpYyByZW5kZXJlcjogUmVuZGVyZXIyKSB7fVxuXG4gIHB1YmxpYyBjcmVhdGVEb20odHlwZTogXCJmaWxlXCIgfCBcImxpdmVcIikge1xuICAgIGlmICh0eXBlID09PSBcImZpbGVcIikge1xuICAgICAgdGhpcy5maWxlVmlkZW8ubmF0aXZlRWxlbWVudC5pbm5lckhUTUwgPSBgPHZpZGVvIGlkPScke3RoaXMuY2xhc3NOYW1lfS1maWxlVmlkZW8nIGNsYXNzPSd2aWRlby1qcyB2anMtYmlnLXBsYXktY2VudGVyZWQnICBjb250cm9scyBtdXRlZCBwcmVsb2FkPSdub25lJyB4LXdlYmtpdC1haXJwbGF5PSd0cnVlJyB3ZWJraXQtcGxheXNpbmxpbmU9J2lzaVBob25lU2hvd1BsYXlzaW5saW5lJyBwbGF5c2lubGluZT0naXNpUGhvbmVTaG93UGxheXNpbmxpbmUnIHg1LXBsYXlzaW5saW5lPSd0cnVlJyB4NS12aWRlby1wbGF5ZXItdHlwZT0naDUnPjwvdmlkZW8+YDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgZ3VpZGUgPVxuICAgICAgICBgPGRpdiBjbGFzcz0nbG9hZGluZyAke3RoaXMuY2xhc3NOYW1lfS1sb2FkaW5nJz48aW1nIHNyYz0nYCArXG4gICAgICAgICh0aGlzLmxvYWRpbmdTcmMgfHwgXCJcIikgK1xuICAgICAgICBgJyBhbHQ9JycgPjwvZGl2PmA7XG4gICAgICBjb25zdCBlcnJvciA9XG4gICAgICAgIGA8ZGl2IGNsYXNzPSdlcnJvciAke3RoaXMuY2xhc3NOYW1lfS1lcnJvcic+PHNwYW4+YCArXG4gICAgICAgICh0aGlzLmVycm9yQ29udGVudCB8fCBcIlwiKSArXG4gICAgICAgIGA8L3NwYW4+PC9kaXY+YDtcbiAgICAgIHRoaXMubGl2ZVZpZGVvLm5hdGl2ZUVsZW1lbnQuaW5uZXJIVE1MID1cbiAgICAgICAgYDx2aWRlbyBpZD0nJHt0aGlzLmNsYXNzTmFtZX0tbGl2ZVZpZGVvJyBjbGFzcz0ndmlkZW8tanMgdmpzLWJpZy1wbGF5LWNlbnRlcmVkJyAgY29udHJvbHMgbXV0ZWQgcHJlbG9hZD0nbm9uZScgeC13ZWJraXQtYWlycGxheT0ndHJ1ZScgd2Via2l0LXBsYXlzaW5saW5lPSdpc2lQaG9uZVNob3dQbGF5c2lubGluZScgcGxheXNpbmxpbmU9J2lzaVBob25lU2hvd1BsYXlzaW5saW5lJyB4NS1wbGF5c2lubGluZT0ndHJ1ZScgeDUtdmlkZW8tcGxheWVyLXR5cGU9J2g1Jz48L3ZpZGVvPmAgK1xuICAgICAgICBndWlkZSArXG4gICAgICAgIGVycm9yO1xuICAgICAgdGhpcy5lbC5uYXRpdmVFbGVtZW50XG4gICAgICAgIC5xdWVyeVNlbGVjdG9yKGAuJHt0aGlzLmNsYXNzTmFtZX0tZXJyb3JgKVxuICAgICAgICAuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsICgpID0+IHtcbiAgICAgICAgICB0aGlzLnNldEJnVmlzaWJsZShcImVycm9yXCIsIGZhbHNlKTtcbiAgICAgICAgICB0aGlzLmNyZWF0ZUxpdmVQbGF5ZXIodHJ1ZSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgfVxuICBwdWJsaWMgaW5pdCgpIHtcbiAgICB0aGlzLmxpdmVMb2FkZWQgPSBmYWxzZTtcbiAgICAvLyDlj6rmkq3mlL7lhbbkuK3kuIDnp43lsLHkvKDkuIDnp43nsbvlnovnmoRvcHRpb25cbiAgICBpZiAodGhpcy5maWxlT3B0aW9ucykge1xuICAgICAgdGhpcy5jcmVhdGVEb20oXCJmaWxlXCIpO1xuICAgICAgY29uc3QgZmlsZVZpZGVvRWwgPSB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICAgYCMke3RoaXMuY2xhc3NOYW1lfS1maWxlVmlkZW9gXG4gICAgICApO1xuICAgICAgdGhpcy5maWxlUGxheWVyID0gdmlkZW9qcyhcbiAgICAgICAgZmlsZVZpZGVvRWwsXG4gICAgICAgIE9iamVjdC5hc3NpZ24odGhpcy5maWxlT3B0aW9ucywge1xuICAgICAgICAgIGF1dG9wbGF5OiB0aGlzLmF1dG9wbGF5LFxuICAgICAgICAgIGVycm9yRGlzcGxheTogZmFsc2UsXG4gICAgICAgICAgY29udHJvbEJhcjoge1xuICAgICAgICAgICAgcGxheVRvZ2dsZTogdHJ1ZSxcbiAgICAgICAgICAgIHZvbHVtZVBhbmVsOiBmYWxzZSwgLy8g5LiN6ZyA6KaB6Z2Z6Z+z5oyJ6ZKuXG4gICAgICAgICAgICBwaWN0dXJlSW5QaWN0dXJlVG9nZ2xlOiBmYWxzZSwgLy8g5LiN6ZyA6KaB55S75Lit55S7XG4gICAgICAgICAgICBmdWxsc2NyZWVuVG9nZ2xlOiBmYWxzZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgKTtcblxuICAgICAgdGhpcy5zZXREZWZhdWx0UHJvcGVydHkodGhpcy5maWxlUGxheWVyKTtcbiAgICAgIHRoaXMuZmlsZVBsYXllci5vbihcImVycm9yXCIsICgkZXZlbnQpID0+IHtcbiAgICAgICAgdGhpcy5FcnJvckV2ZW50TGlzdGVuZXIuZW1pdCgkZXZlbnQpO1xuICAgICAgICBjb25zb2xlLmxvZyhcIuaWh+S7tua1geWHuumUmeS6hu+8gVwiKTtcbiAgICAgICAgdGhpcy5kaXNwb3NlKHRoaXMuZmlsZVBsYXllcik7XG4gICAgICAgIHRoaXMuZmlsZU9wdGlvbnMgPSBudWxsO1xuICAgICAgICB0aGlzLmNyZWF0ZUxpdmVQbGF5ZXIodHJ1ZSwgdHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgdGhpcy5maWxlUGxheWVyLm9uKFwicGxheWluZ1wiLCAoJGV2ZW50KSA9PiB7XG4gICAgICAgIHRoaXMuUGxheWluZ0V2ZW50TGlzdGVuZXIuZW1pdCgkZXZlbnQpO1xuICAgICAgICBpZiAoIXRoaXMubGl2ZVBsYXllcikge1xuICAgICAgICAgIHRoaXMuY3JlYXRlTGl2ZVBsYXllcih0cnVlKTsgLy8g5paH5Lu25rWB5ZKM55u05pKt5rWB6YO95a2Y5Zyo55qE5oOF5Ya15LiL77yM5aaC5p6c5LiN5piv6Ieq5Yqo5pKt5pS+77yM5YiZ5by66KGM5Yib6YCg6Ieq5Yqo5pKt5pS+55qE55u05pKt5rWBXG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdGhpcy5maWxlUGxheWVyLm9uKFwicGF1c2VcIiwgKCRldmVudCkgPT4ge1xuICAgICAgICB0aGlzLlBhdXNlRXZlbnRMaXN0ZW5lci5lbWl0KCRldmVudCk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jcmVhdGVMaXZlUGxheWVyKCk7IC8vIOWmguaenOayoeacieaWh+S7tua1ge+8jOWImeaMieeFp+iuvue9rueahOaYr+WQpuiHquWKqOaSreaUvuaJp+ihjFxuICAgIH1cbiAgfVxuXG4gIC8vIOWIm+W7uuebtOaSrea1gSAs5YaF6YOo5Lyg5bCx5oyJ54Wn5YaF6YOo5Lyg55qE77yM5LiN5Lyg5YiZ5qC55o2u6LCD55So55qE5Yaz5a6aXG4gIHB1YmxpYyBjcmVhdGVMaXZlUGxheWVyKGlzQXV0b1BsYXk/LCBpc0xvYWRpbmc/KSB7XG4gICAgaWYgKCF0aGlzLmxpdmVPcHRpb25zKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuY3JlYXRlRG9tKFwibGl2ZVwiKTtcbiAgICBpZiAoaXNMb2FkaW5nKSB7XG4gICAgICB0aGlzLnNldEJnVmlzaWJsZShcImxvYWRpbmdcIiwgdHJ1ZSk7XG4gICAgfVxuICAgIGNvbnN0IGxpdmVWaWRlb0VsID0gdGhpcy5lbC5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICBgIyR7dGhpcy5jbGFzc05hbWV9LWxpdmVWaWRlb2BcbiAgICApO1xuICAgIGxldCBzdGFydFRpbWUgPSAwLFxuICAgICAgZW5kVGltZSA9IDA7XG4gICAgdGhpcy5saXZlUGxheWVyID0gdmlkZW9qcyhcbiAgICAgIGxpdmVWaWRlb0VsLFxuICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLmxpdmVPcHRpb25zLCB7XG4gICAgICAgIGF1dG9wbGF5OiBpc0F1dG9QbGF5ID8gaXNBdXRvUGxheSA6IHRoaXMuYXV0b3BsYXksXG4gICAgICAgIGVycm9yRGlzcGxheTogZmFsc2UsXG4gICAgICAgIGxpdmV1aTogdHJ1ZSxcbiAgICAgICAgY29udHJvbEJhcjoge1xuICAgICAgICAgIHBsYXlUb2dnbGU6IHRydWUsXG4gICAgICAgICAgdm9sdW1lUGFuZWw6IGZhbHNlLCAvLyDkuI3pnIDopoHpnZnpn7PmjInpkq5cbiAgICAgICAgICBwaWN0dXJlSW5QaWN0dXJlVG9nZ2xlOiBmYWxzZSwgLy8g5LiN6ZyA6KaB55S75Lit55S7XG4gICAgICAgICAgZnVsbHNjcmVlblRvZ2dsZTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgICk7XG4gICAgdGhpcy5hZGRGdWxsU2NyZWVuKCk7XG4gICAgdGhpcy5zZXREZWZhdWx0UHJvcGVydHkodGhpcy5saXZlUGxheWVyKTtcbiAgICB0aGlzLmxpdmVQbGF5ZXIub24oXCJsb2Fkc3RhcnRcIiwgKCRldmVudCkgPT4ge1xuICAgICAgY29uc29sZS5sb2coXCLnm7Tmkq3mtYHlvIDlp4tsb2FkXCIpO1xuICAgICAgc3RhcnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAvLyB0aGlzLnNldEJnVmlzaWJsZShcImxvYWRpbmdcIiwgdHJ1ZSk7XG4gICAgICBpZiAoIXRoaXMuaXNWaWRlb0xvYWRpbmdUaW1lb3V0KSB7XG4gICAgICAgIHRoaXMuaXNWaWRlb0xvYWRpbmdUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5saXZlUGxheWVyICYmXG4gICAgICAgICAgICB0aGlzLmxpdmVQbGF5ZXIucmVhZHlTdGF0ZSgpICE9PSAzICYmXG4gICAgICAgICAgICB0aGlzLmxpdmVQbGF5ZXIucmVhZHlTdGF0ZSgpICE9PSA0XG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aGlzLm9wZW5Nb2RhbCgpO1xuICAgICAgICAgICAgdGhpcy5FcnJvckV2ZW50TGlzdGVuZXIuZW1pdChcIm92ZXJ0aW1lXCIpO1xuICAgICAgICAgICAgY29uc29sZS5sb2coXCLliqDovb3otoXml7bvvIFcIik7XG4gICAgICAgICAgfVxuICAgICAgICB9LCB0aGlzLm1heExvYWRUaW1lIHx8IDE1MDAwKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLmxpdmVQbGF5ZXIub24oXCJsb2FkZWRtZXRhZGF0YVwiLCAoJGV2ZW50KSA9PiB7XG4gICAgICBlbmRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICBjb25zb2xlLmxvZyhcIuebtOaSrea1geWKoOi9veaIkOWKn1wiKTtcbiAgICAgIHRoaXMuc2V0QmdWaXNpYmxlKFwibG9hZGluZ1wiLCBmYWxzZSk7XG4gICAgICB0