@rongcloud/plugin-call-plus 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +0 -0
- package/dist/index.d.ts +3134 -0
- package/dist/index.esm.js +3677 -0
- package/dist/index.umd.js +2 -0
- package/package.json +33 -0
|
@@ -0,0 +1,3677 @@
|
|
|
1
|
+
var De = Object.defineProperty;
|
|
2
|
+
var ye = (t, s, e) => s in t ? De(t, s, { enumerable: !0, configurable: !0, writable: !0, value: e }) : t[s] = e;
|
|
3
|
+
var l = (t, s, e) => (ye(t, typeof s != "symbol" ? s + "" : s, e), e);
|
|
4
|
+
import { isNumber as H, EventEmitter as oe, ErrorCode as se, getUUID22 as Ve, RCConnectionStatus as W, isNull as Pe, isString as Oe, isBoolean as ue, RTCMode as Ge, notEmptyArray as j, notEmptyString as G, isUndefined as K, getUUID as ve, isObject as de, isFunction as be, LogL as we } from "@rongcloud/engine";
|
|
5
|
+
import { RCResolution as ee, RCFrameRate as _e, RCRTCCode as D, RCKickReason as Q, helper as Be, RCLocalTrack as $e, device as he } from "@rongcloud/plugin-rtc";
|
|
6
|
+
import { RCFrameRate as S_, RCResolution as l_ } from "@rongcloud/plugin-rtc";
|
|
7
|
+
const E = {
|
|
8
|
+
/**
|
|
9
|
+
* 成功
|
|
10
|
+
*/
|
|
11
|
+
SUCCESS: 0,
|
|
12
|
+
/**
|
|
13
|
+
* 参数错误
|
|
14
|
+
*/
|
|
15
|
+
PARAM_ERROR: 80001,
|
|
16
|
+
/**
|
|
17
|
+
* 存在未结束的 session
|
|
18
|
+
*/
|
|
19
|
+
SESSION_EXIST: 80002,
|
|
20
|
+
/**
|
|
21
|
+
* 未加入通话
|
|
22
|
+
*/
|
|
23
|
+
NOT_IN_CALL: 80003,
|
|
24
|
+
/**
|
|
25
|
+
* 媒体类型被禁止
|
|
26
|
+
*/
|
|
27
|
+
MEDIATYPE_INVALID: 80004,
|
|
28
|
+
/**
|
|
29
|
+
* 当前不是视频通话
|
|
30
|
+
*/
|
|
31
|
+
NOT_VIDEO_CALL: 80005,
|
|
32
|
+
/**
|
|
33
|
+
* 开通的音视频服务没有及时生效或音视频服务已关闭
|
|
34
|
+
*/
|
|
35
|
+
RTC_SERVICE_UNAVAILABLE: 80006,
|
|
36
|
+
/**
|
|
37
|
+
* 调用函数时,传入的用户列表为空错误
|
|
38
|
+
*/
|
|
39
|
+
USER_LIST_INVAILD: 80007,
|
|
40
|
+
/**
|
|
41
|
+
* 调用函数时,传入的通话 Id 为空错误
|
|
42
|
+
*/
|
|
43
|
+
CALL_ID_INVALID: 80008,
|
|
44
|
+
/**
|
|
45
|
+
* 事务 Id 为空错误
|
|
46
|
+
*/
|
|
47
|
+
TRANSACTION_ID_INVALID: 80009,
|
|
48
|
+
/**
|
|
49
|
+
* 调用函数时,传入的用户 Id 为空错误
|
|
50
|
+
*/
|
|
51
|
+
USER_ID_INVALID: 80010,
|
|
52
|
+
/**
|
|
53
|
+
* 发起单人呼叫时,人员列表中只能有一个人
|
|
54
|
+
*/
|
|
55
|
+
SINGLE_CALL_NOT_SUPPORT_MULTI_PERSON: 80011,
|
|
56
|
+
/**
|
|
57
|
+
* im 未连接
|
|
58
|
+
*/
|
|
59
|
+
SIGNAL_DISCONNECTED: 80012,
|
|
60
|
+
/**
|
|
61
|
+
* 摄像头未打开
|
|
62
|
+
*/
|
|
63
|
+
CAMERA_CLOSED: 80100,
|
|
64
|
+
/**
|
|
65
|
+
* 麦克风未打开
|
|
66
|
+
*/
|
|
67
|
+
MICROPHONE_CLOSED: 80101,
|
|
68
|
+
/**
|
|
69
|
+
* 无媒体资源
|
|
70
|
+
*/
|
|
71
|
+
MEDIA_RESOURCE_INVALIED: 80102,
|
|
72
|
+
/**
|
|
73
|
+
* 未 install RTC 插件
|
|
74
|
+
*/
|
|
75
|
+
NOT_INSTALL_RTC_PLUGIN: 80103,
|
|
76
|
+
/**
|
|
77
|
+
* 播放异常
|
|
78
|
+
*/
|
|
79
|
+
PLAY_MEDIA_FAILED: 80104,
|
|
80
|
+
/**
|
|
81
|
+
* 播放视频需要 video 元素
|
|
82
|
+
*/
|
|
83
|
+
VIDEO_VIEW_NOT_SET: 80105
|
|
84
|
+
};
|
|
85
|
+
var r = /* @__PURE__ */ ((t) => (t.L_INDEX_INSTALL_CALL_PLUS_PLUGIN_O = "L-index_install_call_plus_plugin-O", t.L_CALLPLUS_CLIENT_SET_EVENT_LISTENER_O = "L-callplus_client_set_event_listener-O", t.L_CALLPLUS_CLIENT_CALL_EVENT_LISTENER_O = "L-callplus_client_call_event_listener-O", t.L_CALLPLUS_CLIENT_SET_STATUS_REPORT_LISTENER_O = "L-callplus_client_set_status_report_listener-O", t.L_CALLPLUS_CLIENT_CALL_STATUS_REPORT_LISTENER_O = "L-callplus_client_call_status_report_listener-O", t.L_CALLPLUS_CLIENT_SET_VIDEO_CONFIG_T = "L-callplus_client_set_video_config-T", t.L_CALLPLUS_CLIENT_SET_VIDEO_CONFIG_R = "L-callplus_client_set_video_config-R", t.L_CALLPLUS_VIDEO_CONFIG_SET_FRAME_RATE_O = "L-callplus_video_config_set_frame_rate-O", t.L_CALLPLUS_VIDEO_CONFIG_SET_RESOLUTION_O = "L-callplus_video_config_set_resolution-O", t.L_CALLPLUS_VIDEO_CONFIG_SET_BITRATE_O = "L-callplus_video_config_set_bitrate-O", t.L_CALLPLUS_CLIENT_SET_AUDIO_CONFIG_T = "L-callplus_client_set_audio_config-T", t.L_CALLPLUS_CLIENT_SET_AUDIO_CONFIG_R = "L-callplus_client_set_audio_config-R", t.L_CALLPLUS_AUDIO_CONFIG_SET_BITRATE_O = "L-callplus_audio_config_set_bitrate-O", t.L_CALLPLUS_AUDIO_CONFIG_SET_SAMPLE_RATE_O = "L-callplus_audio_config_set_sample_rate-O", t.L_CALLPLUS_CLIENT_PREVIEW_T = "L-callplus_client_preview-T", t.L_CALLPLUS_CLIENT_PREVIEW_R = "L-callplus_client_preview-R", t.L_CALLPLUS_CLIENT_START_CALL_T = "L-callplus_client_start_call-T", t.L_CALLPLUS_CLIENT_START_CALL_R = "L-callplus_client_start_call-R", t.L_CALLPLUS_CLIENT_JOIN_MULTI_CALL_T = "L-callplus_client_join_multi_call-T", t.L_CALLPLUS_CLIENT_JOIN_MULTI_CALL_R = "L-callplus_client_join_multi_call-R", t.L_CALLPLUS_CLIENT_ACCEPT_T = "L-callplus_client_accept-T", t.L_CALLPLUS_CLIENT_ACCEPT_R = "L-callplus_client_accept-R", t.L_CALLPLUS_CLIENT_HANGUP_T = "L-callplus_client_hangup-T", t.L_CALLPLUS_CLIENT_HANGUP_R = "L-callplus_client_hangup-R", t.L_CALLPLUS_CLIENT_INVITE_T = "L-callplus_client_invite-T", t.L_CALLPLUS_CLIENT_INVITE_R = "L-callplus_client_invite-R", t.L_CALLPLUS_CLIENT_REQUEST_CHANGE_MEDIA_TYPE_T = "L-callplus_client_request_change_media_type-T", t.L_CALLPLUS_CLIENT_REQUEST_CHANGE_MEDIA_TYPE_R = "L-callplus_client_request_change_media_type-R", t.L_CALLPLUS_CLIENT_CANCEL_CHANGE_MEDIA_TYPE_T = "L-callplus_client_cancel_change_media_type-T", t.L_CALLPLUS_CLIENT_CANCEL_CHANGE_MEDIA_TYPE_R = "L-callplus_client_cancel_change_media_type-R", t.L_CALLPLUS_CLIENT_REPLY_CHANGE_MEDIA_TYPE_T = "L-callplus_client_reply_change_media_type-T", t.L_CALLPLUS_CLIENT_REPLY_CHANGE_MEDIA_TYPE_R = "L-callplus_client_reply_change_media_type-R", t.L_CALLPLUS_CLIENT_GET_CURRENT_CALL_SESSION_T = "L-callplus_client_get_current_call_session-T", t.L_CALLPLUS_CLIENT_GET_CURRENT_CALL_SESSION_R = "L-callplus_client_get_current_call_session-R", t.L_CALLPLUS_CLIENT_GET_AVAILABLE_CALL_RECORDS_FROM_SERVER_T = "L-callplus_client_get_available_call_sessions_from_server-T", t.L_CALLPLUS_CLIENT_GET_AVAILABLE_CALL_RECORDS_FROM_SERVER_R = "L-callplus_client_get_available_call_sessions_from_server-R", t.L_CALLPLUS_CLIENT_GET_CALL_RECORDS_T = "L-callplus_client_get_call_records-T", t.L_CALLPLUS_CLIENT_GET_CALL_RECORDS_R = "L-callplus_client_get_call_records-R", t.L_CALLPLUS_CLIENT_DELETE_CALL_RECORDS_BY_CALLID_T = "L-callplus_client_delete_call_records_by_callId-T", t.L_CALLPLUS_CLIENT_DELETE_CALL_RECORDS_BY_CALLID_R = "L-callplus_client_delete_call_records_by_callId-R", t.L_CALLPLUS_CLIENT_DELETE_ALL_CALL_RECORDS_FROM_SERVER_T = "L-callplus_client_delete_all_call_records_from_server-T", t.L_CALLPLUS_CLIENT_DELETE_ALL_CALL_RECORDS_FROM_SERVER_R = "L-callplus_client_delete_all_call_records_from_server-R", t.L_CALLPLUS_CLIENT_START_CAMERA_T = "L-callplus_client_start_camera-T", t.L_CALLPLUS_CLIENT_START_CAMERA_R = "L-callplus_client_start_camera-R", t.L_CALLPLUS_CLIENT_STOP_CAMERA_T = "L-callplus_client_stop_camera-T", t.L_CALLPLUS_CLIENT_STOP_CAMERA_R = "L-callplus_client_stop_camera-R", t.L_CALLPLUS_CLIENT_SWITCH_CAMERA_T = "L-callplus_client_switch_camera-T", t.L_CALLPLUS_CLIENT_SWITCH_CAMERA_R = "L-callplus_client_switch_camera-R", t.L_CALLPLUS_CLIENT_START_MICROPHONE_T = "L-callplus_client_start_microphone-T", t.L_CALLPLUS_CLIENT_START_MICROPHONE_R = "L-callplus_client_start_microphone-R", t.L_CALLPLUS_CLIENT_STOP_MICROPHONE_T = "L-callplus_client_stop_microphone-T", t.L_CALLPLUS_CLIENT_STOP_MICROPHONE_R = "L-callplus_client_stop_microphone-R", t.L_CALLPLUS_CLIENT_SET_VIDEO_VIEW_T = "L-callplus_client_set_video_view-T", t.L_CALLPLUS_CLIENT_SET_VIDEO_VIEW_R = "L-callplus_client_set_video_view-R", t.L_RTC_MODULE_SET_VIDEO_VIEW_O = "L-rtc_module_set_video_view-O", t.L_CALLPLUS_CLIENT_REMOVE_VIDEO_VIEW_T = "L-callplus_client_remove_video_view-T", t.L_CALLPLUS_CLIENT_REMOVE_VIDEO_VIEW_R = "L-callplus_client_remove_video_view-R", t.L_RTC_MODULE_REMOVE_VIDEO_VIEW_O = "L-rtc_module_remove_video_view-O", t.L_CALLPLUS_CLIENT_PLAY_MEDIA_T = "L-callplus_client_play_media-T", t.L_CALLPLUS_CLIENT_PLAY_MEDIA_R = "L-callplus_client_play_media-R", t.L_RTC_MODULE_PLAY_MEDIA_T = "L-rtc_module_play_media-T", t.L_RTC_MODULE_PLAY_MEDIA_R = "L-rtc_module_play_media-R", t.L_RTC_MODULE_SET_ALL_REMOTE_AUDIO_ENABLE_T = "L-rtc_module_set_all_remote_audio_enbale-T", t.L_RTC_MODULE_SET_ALL_REMOTE_AUDIO_ENABLE_R = "L-rtc_module_set_all_remote_audio_enable-R", t.L_RTC_MODULE_SUBSCRIBE_T = "L-rtc_module_subscribe-T", t.L_RTC_MODULE_SUBSCRIBE_R = "L-rtc_module_subscribe-R", t.L_RTC_MODULE_UNSUBSCRIBE_T = "L-rtc_module_unsubscribe-T", t.L_RTC_MODULE_UNSUBSCRIBE_R = "L-rtc_module_unsubscribe-R", t.L_RTC_MODULE_PUBLISH_T = "L-rtc_module_publish-T", t.L_RTC_MODULE_PUBLISH_R = "L-rtc_module_publish-R", t.L_RTC_MODULE_UNPUBLISH_T = "L-rtc_module_unpublish-T", t.L_RTC_MODULE_UNPUBLISH_R = "L-rtc_module_unpublish-R", t.L_RTC_MODULE_DESTROY_ALL_TRACKS_O = "L-rtc_module_destroy_all_tracks-O", t.L_RTC_MODULE_SESSION_CONNECT_T = "L-rtc_module_session_connect-T", t.L_RTC_MODULE_SESSION_CONNECT_P = "L-rtc_module_session_connect-P", t.L_RTC_MODULE_SESSION_CONNECT_R = "L-rtc_module_session_connect-R", t.L_RTC_MODULE_SESSION_CLOSE_T = "L-rtc_module_session_close-T", t.L_RTC_MODULE_SESSION_CLOSE_P = "L-rtc_module_session_close-P", t.L_RTC_MODULE_SESSION_CLOSE_R = "L-rtc_module_session_close-R", t.L_RTC_MODULE_CREATE_VIDEO_TRACK_T = "L-rtc_module_create_video_track-T", t.L_RTC_MODULE_CREATE_VIDEO_TRACK_R = "L-rtc_module_create_video_track-R", t.L_RTC_MODULE_CREATE_AUDIO_TRACK_T = "L-rtc_module_create_audio_track-T", t.L_RTC_MODULE_CREATE_AUDIO_TRACK_R = "L-rtc_module_create_audio_track-R", t.L_RTC_MODULE_RECEIVE_TRACK_PUBLISH_O = "L-rtc_module_receive_track_publish-O", t.L_RTC_MODULE_RECEIVE_TRACK_UNPUBLISH_O = "L-rtc_module_receive_track_unpublish-O", t.L_RTC_MODULE_RECEIVE_TRACK_ENABLE_CHANGE_O = "L-rtc_module_receive_track_enable_change-O", t.L_RTC_MODULE_RECEIVE_KICK_OFF_O = "L-rtc_module_receive_kick_off-O", t.L_RTC_MODULE_RECEIVE_PEERCONNECTION_EXCEPT_CLOSE_O = "L-rtc_module_receive_peerconnection_except_close-O", t.L_RTC_MODULE_CHANGE_MEDIA_TYPE_T = "L-rtc_module_change_media_type-T", t.L_RTC_MODULE_CHANGE_MEDIA_TYPE_R = "L-rtc_module_change_media_type-R", t.L_RTC_MODULE_JOIN_RTC_ROOM_T = "L-rtc_module_join_rtc_room-T", t.L_RTC_MODULE_JOIN_RTC_ROOM_R = "L-rtc_module_join_rtc_room-R", t.L_RTC_MODULE_QUIT_RTC_ROOM_T = "L-rtc_module_quit_rtc_room-T", t.L_RTC_MODULE_QUIT_RTC_ROOM_R = "L-rtc_module_quit_rtc_room-R", t.L_SIGNAL_TRANSPORTER_SINGLE_CALL_T = "L-signal_transporter_single_call-T", t.L_SIGNAL_TRANSPORTER_GROUP_CALL_T = "L-signal_transporter_group_call-T", t.L_SIGNAL_TRANSPORTER_INVITE_T = "L-signal_transporter_invite-T", t.L_SIGNAL_TRANSPORTER_RING_T = "L-signal_transporter_ring-T", t.L_SIGNAL_TRANSPORTER_ACCEPT_T = "L-signal_transporter_accept-T", t.L_SIGNAL_TRANSPORTER_ACCEPT_R = "L-signal_transporter_accept-R", t.L_SIGNAL_TRANSPORTER_JOIN_CALL_T = "L-signal_transporter_join_call-T", t.L_SIGNAL_TRANSPORTER_HANGUP_T = "L-signal_transporter_hangup-T", t.L_SIGNAL_TRANSPORTER_CALL_STATUS_UP_T = "L-signal_transporter_call_status_up-T", t.L_SIGNAL_TRANSPORTER_CALL_EVENT_UP_T = "L-signal_transporter_call_event_up-T", t.L_SIGNAL_TRANSPORTER_CALL_DIALOG_UP_T = "L-signal_transporter_call_dialog_up-T", t.L_SIGNAL_TRANSPORTER_DELETE_CALL_RECORD_T = "L-signal_transporter_delete_call_record-T", t.L_SIGNAL_TRANSPORTER_GET_CALL_RECORD_T = "L-signal_transporter_get_call_record-T", t.L_SIGNAL_TRANSPORTER_GET_CALL_SERVER_TIME_T = "L-signal_transporter_get_call_server_time-T", t.L_SIGNAL_TRANSPORTER_GET_CALL_TIME_INFO_T = "L-signal_transporter_get_call_time_info-T", t.L_SIGNAL_TRANSPORTER_GET_AVAILABLE_CALL_LIST_T = "L-signal_transporter_get_available_call_list-T", t.L_SIGNAL_TRANSPORTER_CLEAR_CALL_RECORD_T = "L-signal_transporter_clear_call_record-T", t.L_SIGNAL_TRANSPORTER_GET_CALL_INFO_BY_CALLID_T = "L-signal_transporter_get_call_info_by_callId-T", t.L_SIGNAL_TRANSPORTER_USER_SYSTEM_STATE_UP_T = "L-signal_transporter_user_system_state_up-T", t.L_SIGNAL_TRANSPORTER_RECEIVE_CALL_SIGNAL_DATA_O = "L-signal_transporter_receive_call_signal_data-O", t.L_SIGNAL_TRANSPORTER_IM_STATE_CHANGE_O = "L-signal_transporter_im_state_change-O", t.L_SIGNAL_TRANSPORTER_RECEIVE_INVITE_O = "L-signal_transporter_receive_invite-O", t.L_SIGNAL_TRANSPORTER_RECEIVE_CALL_STATUS_O = "L-signal_transporter_receive_call_status-O", t.L_CALL_ENGINE_UPDATE_USERS_STATE_O = "L-call_engine_update_users_state-O", t.L_CALL_ENGINE_IM_STATE_CHANGE_O = "L-call_engine_im_state_change-O", t.L_CALL_ENGINE_CALL_TIMEOUT_O = "L-call_engine_call_timeout-O", t.L_CALL_ENGINE_START_CALL_TIMER_O = "L-call_engine_start_call_timer-O", t.L_CALL_ENGINE_STOP_CALL_TIMER_O = "L-call_engine_stop_call_timer-O", t.L_CALL_ENGINE_UP_ON_PHONE_END_T = "L-call_engine_up_on_phone_end-T", t.L_CALL_ENGINE_UP_ON_PHONE_END_R = "L-call_engine_up_on_phone_end-R", t.L_CALL_ENGINE_RECEIVE_FIRST_FRAME_TIME_O = "L-call_engine_receive_first_frame_time-O", t.L_CALL_ENGINE_RECEIVE_MEDIATYPE_CHANGE_O = "L-call_engine_receive_mediatype_change-O", t.L_CALL_ENGINE_RECEIVE_CLOSE_SESSION_O = "L-call_engine_receive_close_session-O", t.L_CALL_ENGINE_RECEIVE_CALL_RECORD_O = "L-call_engine_receive_call_record-O", t.L_CALL_ENGINE_RECEIVE_COMPLEMENTARY_DATA_O = "L-call_engine_receive_complementary_data-O", t.L_CALL_ENGINE_CREATE_SESSION_BY_SERVER_T = "L-call_engine_create_session_by_server-T", t.L_CALL_ENGINE_CREATE_SESSION_BY_SERVER_R = "L-call_engine_create_session_by_server-R", t.L_CALL_ENGINE_UP_FIRST_FRAME_TIME_T = "L-call_engine_up_first_frame_time-T", t.L_CALL_ENGINE_UP_FIRST_FRAME_TIME_R = "L-call_engine_up_first_frame_time-R", t.L_TIME_CORRECT_START_O = "L-time_correct_start-O", t.L_TIME_CORRECT_STOP_O = "L-time_correct_stop-O", t.L_TIME_CORRECT_RESTART_O = "L-time_correct_restart-O", t.L_TIME_CORRECT_GET_CALL_CLIENT_TIME_BY_SERVER_T = "L-time_correct_get_call_client_time_by_server-T", t.L_TIME_CORRECT_GET_CALL_CLIENT_TIME_BY_SERVER_P = "L-time_correct_get_call_client_time_by_server-P", t.L_TIME_CORRECT_GET_CALL_CLIENT_TIME_BY_SERVER_R = "L-time_correct_get_call_client_time_by_server-R", t.L_TIME_CORRECT_CALC_CLIENT_START_TIME_T = "L-time_correct_calc_client_start_time-T", t.L_TIME_CORRECT_CALC_CLIENT_START_TIME_R = "L-time_correct_calc_client_start_time-R", t.L_TIME_CORRECT_SET_DELTA_TIME_O = "L-time_correct_set_delta_time-O", t.L_TIME_CORRECT_LOOP_CORRECT_CLINET_TIME_T = "L-time_correct_loop_correct_client_time-T", t.L_TIME_CORRECT_LOOP_CORRECT_CLINET_TIME_R = "L-time_correct_loop_correct_client_time-R", t.L_INNER_SESSION_UPDATE_USER_STATE_O = "L-inner_session_update_user_state-O", t.L_INNER_SESSION_SET_USER_DEVICE_ENABLE_O = "L-inner_session_set_user_device_enable-O", t.L_CALL_PLUS_SESSION_GET_CREATE_TIME_T = "L-call_plus_session_get_create_time-T", t.L_CALL_PLUS_SESSION_GET_CREATE_TIME_R = "L-call_plus_session_get_create_time-R", t.L_CALL_PLUS_SESSION_GET_DURATION_T = "L-call_plus_session_get_duration-T", t.L_CALL_PLUS_SESSION_GET_DURATION_R = "L-call_plus_session_get_duration-R", t))(r || {});
|
|
86
|
+
class ie {
|
|
87
|
+
constructor(s, e, _) {
|
|
88
|
+
l(this, "_startTime", 0);
|
|
89
|
+
l(this, "_duration", 0);
|
|
90
|
+
l(this, "_callId", "");
|
|
91
|
+
this._session = s, this._callEngine = e, this._logger = _, this._callId = this._session.getCallId();
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 获取 CallId
|
|
95
|
+
*/
|
|
96
|
+
getCallId() {
|
|
97
|
+
return this._callId;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* 获取 session 状态
|
|
101
|
+
*/
|
|
102
|
+
getState() {
|
|
103
|
+
return this._session.getSessionState();
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 获取通话类型
|
|
107
|
+
*/
|
|
108
|
+
getCallType() {
|
|
109
|
+
return this._session.getCallType();
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* 获取通话媒体类型
|
|
113
|
+
*/
|
|
114
|
+
getMediaType() {
|
|
115
|
+
return this._session.getMediaType();
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* 获取通话人员列表
|
|
119
|
+
*/
|
|
120
|
+
getUserList() {
|
|
121
|
+
return this._session.getUserList().map((s) => {
|
|
122
|
+
const {
|
|
123
|
+
userId: e,
|
|
124
|
+
userState: _,
|
|
125
|
+
cameraEnable: i,
|
|
126
|
+
microphoneEnable: n
|
|
127
|
+
} = s;
|
|
128
|
+
return {
|
|
129
|
+
userId: e,
|
|
130
|
+
state: _,
|
|
131
|
+
cameraEnable: i,
|
|
132
|
+
microphoneEnable: n
|
|
133
|
+
};
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* 获取通话发起者 userId
|
|
138
|
+
*/
|
|
139
|
+
getCreatorUserId() {
|
|
140
|
+
return this._session.getStartCallerId();
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* 获取通话邀请者 userId
|
|
144
|
+
* 呼入有值,呼出时,值为本地用户 UserId
|
|
145
|
+
*/
|
|
146
|
+
getInviterUserId() {
|
|
147
|
+
return this._session.getCallerId();
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* 获取通话起始时间
|
|
151
|
+
*/
|
|
152
|
+
async getCreateTimestamp() {
|
|
153
|
+
const s = this._logger.createTraceId();
|
|
154
|
+
if (this._logger.info(r.L_CALL_PLUS_SESSION_GET_CREATE_TIME_T, "", s), this._startTime)
|
|
155
|
+
return { code: E.SUCCESS, startTime: this._startTime };
|
|
156
|
+
const { code: e, clientStartTime: _ } = await this._callEngine.getCallStaringTime({ callId: this._callId }, s);
|
|
157
|
+
return e !== E.SUCCESS ? (this._logger.error(r.L_CALL_PLUS_SESSION_GET_CREATE_TIME_R, `errCode: ${e}`, s), { code: e }) : (this._logger.info(r.L_CALL_PLUS_SESSION_GET_CREATE_TIME_R, "success", s), this._startTime = _, {
|
|
158
|
+
code: E.SUCCESS,
|
|
159
|
+
startTime: this._startTime
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* 获取通话时长
|
|
164
|
+
* 通话未结束前,值为 0
|
|
165
|
+
*/
|
|
166
|
+
async getDuration() {
|
|
167
|
+
const s = this._logger.createTraceId();
|
|
168
|
+
if (this._logger.info(r.L_CALL_PLUS_SESSION_GET_DURATION_T, "", s), this._duration)
|
|
169
|
+
return this._logger.info(r.L_CALL_PLUS_SESSION_GET_DURATION_R, `code: ${E.SUCCESS}, duration: ${this._duration}`, s), { code: E.SUCCESS, duration: this._duration };
|
|
170
|
+
const { code: e, data: _ } = await this._callEngine.getCallTimeInfo(this._callId, s);
|
|
171
|
+
return e !== E.SUCCESS ? (this._logger.error(r.L_CALL_PLUS_SESSION_GET_DURATION_R, `code: ${e}`, s), { code: e }) : (this._logger.info(r.L_CALL_PLUS_SESSION_GET_DURATION_R, `code: ${E.SUCCESS}, duration: ${_.duration}`, s), this._duration = _.duration, {
|
|
172
|
+
code: E.SUCCESS,
|
|
173
|
+
duration: this._duration
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
var M = /* @__PURE__ */ ((t) => (t[t.SINGLE = 0] = "SINGLE", t[t.MULTI = 1] = "MULTI", t))(M || {}), C = /* @__PURE__ */ ((t) => (t[t.IDLE = 0] = "IDLE", t[t.CALLING = 100] = "CALLING", t[t.INVITED = 101] = "INVITED", t[t.RINGING = 102] = "RINGING", t[t.BUSYLINE_RINGING = 103] = "BUSYLINE_RINGING", t[t.BUSYLINE_WAIT = 104] = "BUSYLINE_WAIT", t[t.CONNECTING = 200] = "CONNECTING", t[t.ONCALL = 300] = "ONCALL", t[t.ONPHONE = 301] = "ONPHONE", t[t.ENDED = 1e3] = "ENDED", t[t.NO_ANSWER = 1001] = "NO_ANSWER", t[t.MISSED = 1002] = "MISSED", t[t.CANCELLED = 1003] = "CANCELLED", t[t.DECLINED = 1004] = "DECLINED", t[t.ERROR = 2e3] = "ERROR", t))(C || {}), R = /* @__PURE__ */ ((t) => (t[t.AUDIO = 0] = "AUDIO", t[t.AUDIO_VIDEO = 1] = "AUDIO_VIDEO", t[t.VIDEO = 2] = "VIDEO", t))(R || {}), p = /* @__PURE__ */ ((t) => (t[t.IDLE = 0] = "IDLE", t[t.CALLING = 100] = "CALLING", t[t.INVITED = 101] = "INVITED", t[t.RINGING = 102] = "RINGING", t[t.BUSYLINE_RINGING = 103] = "BUSYLINE_RINGING", t[t.BUSYLINE_WAIT = 104] = "BUSYLINE_WAIT", t[t.CONNECTING = 200] = "CONNECTING", t[t.ONCALL = 300] = "ONCALL", t[t.ENDED = 1e3] = "ENDED", t[t.NOANSWER = 1001] = "NOANSWER", t[t.MISSED = 1002] = "MISSED", t[t.CANCELED = 1003] = "CANCELED", t[t.DECLINED = 1004] = "DECLINED", t[t.ERROR = 2e3] = "ERROR", t))(p || {}), F = /* @__PURE__ */ ((t) => (t[t.CANCEL_CHANGE_MEDIA_TYPE = 0] = "CANCEL_CHANGE_MEDIA_TYPE", t[t.REFUSE_CHANGE_MEDIA_TYPE = 1] = "REFUSE_CHANGE_MEDIA_TYPE", t[t.SERVER_ALLOW_MEDIA_TYPE = 2] = "SERVER_ALLOW_MEDIA_TYPE", t[t.CHANGE_MEDIA_TYPE_TIMEOUT = 3] = "CHANGE_MEDIA_TYPE_TIMEOUT", t))(F || {}), h = /* @__PURE__ */ ((t) => (t[t.IDLE = 0] = "IDLE", t[t.CALLING = 100] = "CALLING", t[t.INVITED = 101] = "INVITED", t[t.RINGING = 102] = "RINGING", t[t.BUSYLINE_RINGING = 103] = "BUSYLINE_RINGING", t[t.BUSYLINE_WAIT = 104] = "BUSYLINE_WAIT", t[t.CONNECTING = 200] = "CONNECTING", t[t.ONCALL = 300] = "ONCALL", t[t.ON_PHONE = 301] = "ON_PHONE", t[t.ON_PHONE_END = 302] = "ON_PHONE_END", t[t.ON_DEVICE_DISABLE = 303] = "ON_DEVICE_DISABLE", t[t.ON_DEVICE_ENABLE = 304] = "ON_DEVICE_ENABLE", t[t.ABNORMAL_END = 999] = "ABNORMAL_END", t[t.ENDED = 1e3] = "ENDED", t[t.NO_ANSWER = 1001] = "NO_ANSWER", t[t.MISSED = 1002] = "MISSED", t[t.CANCELLED = 1003] = "CANCELLED", t[t.DECLINED = 1004] = "DECLINED", t[t.OTHER_CLIENT_CALLING = 1010] = "OTHER_CLIENT_CALLING", t[t.OTHER_CLIENT_ACCEPT = 1011] = "OTHER_CLIENT_ACCEPT", t[t.JOIN_ROOM_ERR = 1105] = "JOIN_ROOM_ERR", t[t.PUBLISH_ERR = 1106] = "PUBLISH_ERR", t[t.SUBSCRIBE_ERR = 1107] = "SUBSCRIBE_ERR", t[t.ACCEPT_CARRIER = 1108] = "ACCEPT_CARRIER", t[t.KICKED_BY_SERVER = 1109] = "KICKED_BY_SERVER", t[t.CONNECTION_ERR = 1110] = "CONNECTION_ERR", t[t.LOGOUT = 1111] = "LOGOUT", t[t.OTHER_CLIENT_LOGIN = 1112] = "OTHER_CLIENT_LOGIN", t[t.OTHER_CLIENT_JOINED = 1113] = "OTHER_CLIENT_JOINED", t[t.OTHER_CLIENT_IN_ROOM = 1114] = "OTHER_CLIENT_IN_ROOM", t[t.OTHER_CLIENT_HANGUP = 1151] = "OTHER_CLIENT_HANGUP", t[t.REMOTE_JOIN_RTC_ERROR = 1205] = "REMOTE_JOIN_RTC_ERROR", t[t.REMOTE_PUBLISH_ERROR = 1206] = "REMOTE_PUBLISH_ERROR", t[t.REMOTE_SUBSCRIBE_ERROR = 1207] = "REMOTE_SUBSCRIBE_ERROR", t[t.REMOTE_KICKED_BY_SERVER = 1209] = "REMOTE_KICKED_BY_SERVER", t[t.REMOTE_CONNECTION_ERROR = 1210] = "REMOTE_CONNECTION_ERROR", t[t.REMOTE_LOGOUT = 1211] = "REMOTE_LOGOUT", t[t.REMOTE_OTHER_CLIENT_LOGIN = 1212] = "REMOTE_OTHER_CLIENT_LOGIN", t[t.REMOTE_OTHER_JOINED_RTC = 1213] = "REMOTE_OTHER_JOINED_RTC", t[t.REMOTE_OTHER_CLIENT_IN_RTC = 1214] = "REMOTE_OTHER_CLIENT_IN_RTC", t))(h || {});
|
|
178
|
+
class He {
|
|
179
|
+
constructor(s) {
|
|
180
|
+
l(this, "_audioConfig", {});
|
|
181
|
+
this._logger = s;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* 指定默认麦克风
|
|
185
|
+
* microphoneId 取值可参考 https://doc.rongcloud.cn/rtc/Web/5.X/device#%E8%8E%B7%E5%8F%96%E9%BA%A6%E5%85%8B%E9%A3%8E%E8%AE%BE%E5%A4%87%E5%88%97%E8%A1%A8
|
|
186
|
+
*/
|
|
187
|
+
setDefaultMicrophoneId(s) {
|
|
188
|
+
return this._audioConfig.microphoneId = s, this;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* 设置最小、最大码率
|
|
192
|
+
* 单位 kbps
|
|
193
|
+
* 不设置时,取动态码率计算结果
|
|
194
|
+
* @param min 最小码率
|
|
195
|
+
* @param max 最大码率
|
|
196
|
+
*/
|
|
197
|
+
setBitrate(s, e) {
|
|
198
|
+
return !H(s) || !H(e) || e <= 0 || s <= 0 || e < s ? (this._logger.error(r.L_CALLPLUS_AUDIO_CONFIG_SET_BITRATE_O, `params error -> max: ${e},min: ${s}, max and min is a number > 0, max should > min`), this) : (this._audioConfig.minBitrate = s, this._audioConfig.maxBitrate = e, this);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* 设置音频采样率,不建议自行修改
|
|
202
|
+
* @param sampleRate 采样率
|
|
203
|
+
*/
|
|
204
|
+
setSampleRate(s) {
|
|
205
|
+
return H(s) ? (this._audioConfig.sampleRate = s, this) : (this._logger.error(r.L_CALLPLUS_AUDIO_CONFIG_SET_SAMPLE_RATE_O, `params error -> sampleRate: ${s}`), this);
|
|
206
|
+
}
|
|
207
|
+
/** 构建配置 */
|
|
208
|
+
build() {
|
|
209
|
+
return this._audioConfig;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
class ke {
|
|
213
|
+
constructor(s) {
|
|
214
|
+
l(this, "_videoConfig", {
|
|
215
|
+
resolution: ee.W640_H480,
|
|
216
|
+
frameRate: _e.FPS_15
|
|
217
|
+
});
|
|
218
|
+
this._logger = s;
|
|
219
|
+
}
|
|
220
|
+
/** 针对不同视频流分别配置帧率 */
|
|
221
|
+
setFrameRate(s) {
|
|
222
|
+
return _e[s] ? (this._videoConfig.frameRate = s, this) : (this._logger.error(r.L_CALLPLUS_VIDEO_CONFIG_SET_FRAME_RATE_O, `params error -> fps: ${s}`), this);
|
|
223
|
+
}
|
|
224
|
+
/** 针对不同视频流分别配置分辨率 */
|
|
225
|
+
setVideoResolution(s) {
|
|
226
|
+
return ee[s] ? (this._videoConfig.resolution = s, this) : (this._logger.error(r.L_CALLPLUS_VIDEO_CONFIG_SET_RESOLUTION_O, `params error -> resolution: ${s}`), this);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* 设置默认 cameraId
|
|
230
|
+
* cameraId 取值可参考 https://doc.rongcloud.cn/rtc/Web/5.X/device#%E8%8E%B7%E5%8F%96%E6%91%84%E5%83%8F%E5%A4%B4%E8%AE%BE%E5%A4%87%E5%88%97%E8%A1%A8
|
|
231
|
+
* 作用于预览功能、呼叫取流等
|
|
232
|
+
*/
|
|
233
|
+
setDefaultCameraId(s) {
|
|
234
|
+
return this._videoConfig.cameraId = s, this;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* 设置最小、最大码率
|
|
238
|
+
* 单位 kbps
|
|
239
|
+
* 不设置时,取动态码率计算结果
|
|
240
|
+
* @param min 最小码率
|
|
241
|
+
* @param max 最大码率
|
|
242
|
+
*/
|
|
243
|
+
setBitrate(s, e) {
|
|
244
|
+
return !H(s) || !H(e) || e <= 0 || s <= 0 || e < s ? (this._logger.error(r.L_CALLPLUS_VIDEO_CONFIG_SET_BITRATE_O, `params error -> max: ${e},min: ${s}, max and min is a number > 0, max should > min`), this) : (this._videoConfig.minBitrate = s, this._videoConfig.maxBitrate = e, this);
|
|
245
|
+
}
|
|
246
|
+
// 构建配置
|
|
247
|
+
build() {
|
|
248
|
+
return this._videoConfig;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
const Ne = (t) => {
|
|
252
|
+
const {
|
|
253
|
+
callId: s,
|
|
254
|
+
callType: e,
|
|
255
|
+
callDir: _,
|
|
256
|
+
mediaType: i,
|
|
257
|
+
callingUserId: n,
|
|
258
|
+
callUserIds: o,
|
|
259
|
+
callStatus: a,
|
|
260
|
+
sessionStatus: L,
|
|
261
|
+
startTime: c,
|
|
262
|
+
endTime: T,
|
|
263
|
+
duration: S,
|
|
264
|
+
secretChat: I,
|
|
265
|
+
syncTime: d,
|
|
266
|
+
sysStatus: g,
|
|
267
|
+
crtTime: O
|
|
268
|
+
} = t;
|
|
269
|
+
return {
|
|
270
|
+
callId: s,
|
|
271
|
+
callType: e,
|
|
272
|
+
callDirection: _,
|
|
273
|
+
mediaType: i,
|
|
274
|
+
// isSecretChat: Boolean(secretChat),
|
|
275
|
+
callerUserId: n,
|
|
276
|
+
callUserIds: o,
|
|
277
|
+
sessionState: a,
|
|
278
|
+
userState: L,
|
|
279
|
+
startTimestamp: c,
|
|
280
|
+
endTimestamp: T,
|
|
281
|
+
duration: S,
|
|
282
|
+
syncTimestamp: d,
|
|
283
|
+
systemState: g,
|
|
284
|
+
createTimestamp: O
|
|
285
|
+
};
|
|
286
|
+
}, xe = (t) => {
|
|
287
|
+
const { callId: s, callStatus: e } = t, _ = [], i = [], n = [], o = [];
|
|
288
|
+
return t.callSessionUsers.forEach((a) => {
|
|
289
|
+
const { userId: L, sessionStatus: c, sysStatus: T } = a;
|
|
290
|
+
switch (c) {
|
|
291
|
+
case C.INVITED:
|
|
292
|
+
o.push({
|
|
293
|
+
callId: s,
|
|
294
|
+
userId: L,
|
|
295
|
+
userState: c
|
|
296
|
+
});
|
|
297
|
+
break;
|
|
298
|
+
case C.RINGING:
|
|
299
|
+
_.push({ callId: s, fromUserId: L });
|
|
300
|
+
break;
|
|
301
|
+
case C.CONNECTING:
|
|
302
|
+
n.push({ fromUserId: L });
|
|
303
|
+
break;
|
|
304
|
+
case C.CANCELLED:
|
|
305
|
+
case C.DECLINED:
|
|
306
|
+
case C.ENDED:
|
|
307
|
+
case C.IDLE:
|
|
308
|
+
i.push({
|
|
309
|
+
callId: s,
|
|
310
|
+
fromUserId: L,
|
|
311
|
+
userState: c,
|
|
312
|
+
systemState: T
|
|
313
|
+
});
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
}), {
|
|
317
|
+
ringingData: _,
|
|
318
|
+
hangupData: i,
|
|
319
|
+
acceptData: n,
|
|
320
|
+
otherInvitedData: o
|
|
321
|
+
};
|
|
322
|
+
}, Fe = (t) => t && t.nodeName && t.nodeName.toUpperCase() === "VIDEO", Ye = (t, s) => {
|
|
323
|
+
let e = !1;
|
|
324
|
+
const _ = [
|
|
325
|
+
h.INVITED,
|
|
326
|
+
h.RINGING,
|
|
327
|
+
h.BUSYLINE_RINGING,
|
|
328
|
+
h.BUSYLINE_WAIT,
|
|
329
|
+
h.CONNECTING,
|
|
330
|
+
h.ONCALL
|
|
331
|
+
];
|
|
332
|
+
switch (t) {
|
|
333
|
+
case h.ONCALL:
|
|
334
|
+
_.includes(s) && (e = !0);
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
return e;
|
|
338
|
+
}, Je = (t, s) => {
|
|
339
|
+
let e = !1;
|
|
340
|
+
const _ = [
|
|
341
|
+
C.INVITED,
|
|
342
|
+
C.RINGING,
|
|
343
|
+
C.BUSYLINE_RINGING,
|
|
344
|
+
C.BUSYLINE_WAIT,
|
|
345
|
+
C.CONNECTING,
|
|
346
|
+
C.ONCALL
|
|
347
|
+
];
|
|
348
|
+
switch (t) {
|
|
349
|
+
case C.ONCALL:
|
|
350
|
+
_.includes(s) && (e = !0);
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
return e;
|
|
354
|
+
}, Ke = (t, s) => {
|
|
355
|
+
let e;
|
|
356
|
+
switch (t) {
|
|
357
|
+
case C.CALLING:
|
|
358
|
+
e = h.CANCELLED;
|
|
359
|
+
break;
|
|
360
|
+
case C.RINGING:
|
|
361
|
+
case C.INVITED:
|
|
362
|
+
e = h.DECLINED;
|
|
363
|
+
break;
|
|
364
|
+
case C.CONNECTING:
|
|
365
|
+
e = s ? h.DECLINED : h.CANCELLED;
|
|
366
|
+
break;
|
|
367
|
+
case C.ONCALL:
|
|
368
|
+
e = h.ENDED;
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
371
|
+
return e;
|
|
372
|
+
}, ae = (t) => {
|
|
373
|
+
const { voipCallInfo: s } = t;
|
|
374
|
+
if (!s)
|
|
375
|
+
return !1;
|
|
376
|
+
const { strategy: e } = JSON.parse(s);
|
|
377
|
+
return e === 1;
|
|
378
|
+
}, Ae = (t, s) => (t || t === 0) && (!H(t) || t <= 0) ? { code: E.PARAM_ERROR, errorMsg: `params error -> minBitrate: a number of > 0, value: ${t}` } : (s || s === 0) && (!H(s) || s <= 0) ? { code: E.PARAM_ERROR, errorMsg: `params error -> maxBitrate: a number of > 0, value: ${s}` } : t && s && s < t ? { code: E.PARAM_ERROR, errorMsg: `params error -> maxBitrate: ${s}, minBitrate: ${t}, maxBitrate should > minBitrate` } : { code: E.SUCCESS };
|
|
379
|
+
var k = /* @__PURE__ */ ((t) => (t.L_QS_START_CALL_S = "Call-start-S", t.L_QS_ACCEPT_CALL_S = "Call-accept-S", t.L_QS_HANGUP_CALL_S = "Call-hangup-S", t.L_QS_RECEIVE_CALL_S = "Call-recv-S", t.L_QS_ABNORMAL_HANGUP_S = "Call-interrupt-S", t))(k || {});
|
|
380
|
+
class We {
|
|
381
|
+
constructor(s, e) {
|
|
382
|
+
this._logger = s, this._context = e;
|
|
383
|
+
}
|
|
384
|
+
reportStatisticsData(s, e, _, i, n, o, a) {
|
|
385
|
+
const L = +/* @__PURE__ */ new Date(), { mediaType: c, callType: T, callId: S } = i ? { mediaType: i.getMediaType(), callType: i.getCallType(), callId: i.getCallId() } : a, I = {
|
|
386
|
+
cr: "unknown",
|
|
387
|
+
net: "unknown",
|
|
388
|
+
cod: e,
|
|
389
|
+
mtp: c,
|
|
390
|
+
ctp: T,
|
|
391
|
+
cid: S,
|
|
392
|
+
time: L,
|
|
393
|
+
uid: this._context.getCurrentId()
|
|
394
|
+
};
|
|
395
|
+
n && Object.assign(I, { ccid: n });
|
|
396
|
+
let d = null;
|
|
397
|
+
switch (s) {
|
|
398
|
+
case k.L_QS_RECEIVE_CALL_S:
|
|
399
|
+
d = {
|
|
400
|
+
...I,
|
|
401
|
+
rf: o
|
|
402
|
+
};
|
|
403
|
+
break;
|
|
404
|
+
case k.L_QS_ABNORMAL_HANGUP_S:
|
|
405
|
+
d = {
|
|
406
|
+
...I
|
|
407
|
+
};
|
|
408
|
+
break;
|
|
409
|
+
default:
|
|
410
|
+
d = {
|
|
411
|
+
...I,
|
|
412
|
+
dur: L - _
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
this._logger.info("L-call-plus-statistic", JSON.stringify(d), s), this._logger.__statistics(s, JSON.stringify(d));
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
var b = /* @__PURE__ */ ((t) => (t.REQUEST = "request", t.ACCEPT = "accept", t.REFUSE = "refuse", t.CANCEL = "cancel", t.NOTICE = "notice", t.TIMEOUT = "timeout", t))(b || {}), q = /* @__PURE__ */ ((t) => (t[t.SWITCH_MEDIA_TYPE = 1] = "SWITCH_MEDIA_TYPE", t))(q || {}), ce = /* @__PURE__ */ ((t) => (t[t.NORMAL = 0] = "NORMAL", t[t.SECRET = 1] = "SECRET", t))(ce || {}), Te = /* @__PURE__ */ ((t) => (t.INVITER = "inviter", t.INVITEE = "invitee", t))(Te || {});
|
|
419
|
+
class Le extends oe {
|
|
420
|
+
/**
|
|
421
|
+
* 构造器
|
|
422
|
+
*/
|
|
423
|
+
constructor(e, _, i, n, o, a, L, c) {
|
|
424
|
+
super();
|
|
425
|
+
/**
|
|
426
|
+
* 请求更新的 mediaType
|
|
427
|
+
*/
|
|
428
|
+
l(this, "_reqMediaType");
|
|
429
|
+
/**
|
|
430
|
+
* 邀请者超时计时器
|
|
431
|
+
*/
|
|
432
|
+
l(this, "_inviterTimerId");
|
|
433
|
+
/**
|
|
434
|
+
* 被邀请者超时计时器
|
|
435
|
+
*/
|
|
436
|
+
l(this, "_inviteeTimerId");
|
|
437
|
+
/**
|
|
438
|
+
* 当前 session 人员信息列表
|
|
439
|
+
*/
|
|
440
|
+
// private _callUsers: ISessionUser[] = []
|
|
441
|
+
/**
|
|
442
|
+
* 旧 dialog 数据,用于对比
|
|
443
|
+
*/
|
|
444
|
+
l(this, "_oldDialogData");
|
|
445
|
+
/**
|
|
446
|
+
* 记录是否本地有挂断
|
|
447
|
+
*/
|
|
448
|
+
l(this, "isLocalClientHangup", !1);
|
|
449
|
+
this._callId = e, this._state = _, this._callType = i, this._mediaType = n, this._startCallerId = o, this._callerId = a, this._callUsers = L, this._logger = c;
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* 获取 CallID
|
|
453
|
+
*/
|
|
454
|
+
getCallId() {
|
|
455
|
+
return this._callId;
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* 获取状态
|
|
459
|
+
*/
|
|
460
|
+
getSessionState() {
|
|
461
|
+
return this._state;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* 获取通话类型
|
|
465
|
+
*/
|
|
466
|
+
getCallType() {
|
|
467
|
+
return this._callType;
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* 获取媒体类型
|
|
471
|
+
*/
|
|
472
|
+
getMediaType() {
|
|
473
|
+
return this._mediaType;
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* 获取 session 发起者
|
|
477
|
+
*/
|
|
478
|
+
getStartCallerId() {
|
|
479
|
+
return this._startCallerId;
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* 本次 session 邀请者
|
|
483
|
+
*/
|
|
484
|
+
getCallerId() {
|
|
485
|
+
return this._callerId;
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* 获取 session user list
|
|
489
|
+
*/
|
|
490
|
+
getUserList() {
|
|
491
|
+
return this._callUsers;
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* 请求更新的 mediaType
|
|
495
|
+
*/
|
|
496
|
+
getReqMediaType() {
|
|
497
|
+
return this._reqMediaType;
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* inviterTimerId
|
|
501
|
+
*/
|
|
502
|
+
getInviterTimerId() {
|
|
503
|
+
return this._inviterTimerId;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* inviteeTimerId
|
|
507
|
+
*/
|
|
508
|
+
getInviteeTimerId() {
|
|
509
|
+
return this._inviteeTimerId;
|
|
510
|
+
}
|
|
511
|
+
getAllTimerIds() {
|
|
512
|
+
return [this._inviterTimerId, this._inviteeTimerId];
|
|
513
|
+
}
|
|
514
|
+
setUserDeviceEnable(e, _, i, n) {
|
|
515
|
+
this._logger.info(r.L_INNER_SESSION_SET_USER_DEVICE_ENABLE_O, `userId: ${e}, mediaType: ${_}, enable: ${i}`, n);
|
|
516
|
+
const o = this._callUsers.find((a) => e === a.userId);
|
|
517
|
+
_ === R.AUDIO ? o.microphoneEnable = i : o.cameraEnable = i;
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* 更新人员列表, 并返回更新的人员列表
|
|
521
|
+
* 根据人员状态去添加、删除、更新
|
|
522
|
+
* 根据状态时间,判断是否更新,无时间戳的为本地状态调整,直接更新
|
|
523
|
+
*/
|
|
524
|
+
updateUserList(e, _) {
|
|
525
|
+
const i = [];
|
|
526
|
+
return e.forEach((n) => {
|
|
527
|
+
const {
|
|
528
|
+
userState: o,
|
|
529
|
+
stateTime: a,
|
|
530
|
+
systemState: L
|
|
531
|
+
} = n;
|
|
532
|
+
if ([C.CALLING, C.INVITED, C.BUSYLINE_WAIT].includes(o))
|
|
533
|
+
this._logger.info(r.L_INNER_SESSION_UPDATE_USER_STATE_O, `push user: ${JSON.stringify(n)}`, _), this._callUsers.push(n), i.push(n);
|
|
534
|
+
else {
|
|
535
|
+
let T = !1;
|
|
536
|
+
for (let S = 0; S < this._callUsers.length; S++) {
|
|
537
|
+
const {
|
|
538
|
+
userId: I,
|
|
539
|
+
stateTime: d,
|
|
540
|
+
systemState: g,
|
|
541
|
+
userState: O
|
|
542
|
+
} = this._callUsers[S];
|
|
543
|
+
if (I === n.userId) {
|
|
544
|
+
T = !0;
|
|
545
|
+
const u = Ye(g, L), m = Je(O, o), N = L === h.ON_PHONE_END && g !== h.ON_PHONE && o !== C.IDLE;
|
|
546
|
+
if (a && d && a < d || u && m) {
|
|
547
|
+
try {
|
|
548
|
+
this._logger.warn(r.L_INNER_SESSION_UPDATE_USER_STATE_O, `timeout user state: old:${JSON.stringify({
|
|
549
|
+
userId: I,
|
|
550
|
+
oldStateTime: d,
|
|
551
|
+
oldSystemState: g,
|
|
552
|
+
oldUserState: O
|
|
553
|
+
})}; new:${JSON.stringify(n)}`, _);
|
|
554
|
+
} catch (U) {
|
|
555
|
+
this._logger.error(r.L_INNER_SESSION_UPDATE_USER_STATE_O, `updateUserList err: ${U.message}`, _);
|
|
556
|
+
}
|
|
557
|
+
break;
|
|
558
|
+
} else {
|
|
559
|
+
this._logger.info(r.L_INNER_SESSION_UPDATE_USER_STATE_O, `updateUserList -> cover ${JSON.stringify(n)}`, _), this._callUsers[S] = n, !N && i.push(n);
|
|
560
|
+
break;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
T || (this._logger.info(r.L_INNER_SESSION_UPDATE_USER_STATE_O, `updateUserList -> nouser push ${JSON.stringify(n)}`, _), this._callUsers.push(n), i.push(n));
|
|
565
|
+
}
|
|
566
|
+
}), i;
|
|
567
|
+
}
|
|
568
|
+
setOldDialogData(e) {
|
|
569
|
+
this._oldDialogData = e;
|
|
570
|
+
}
|
|
571
|
+
/** ======私有方法============================================================================================= */
|
|
572
|
+
/**
|
|
573
|
+
* 更新 session 状态
|
|
574
|
+
*/
|
|
575
|
+
updateSessionState(e) {
|
|
576
|
+
this._state = e;
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* 更新通话类型(升降级设置)
|
|
580
|
+
*/
|
|
581
|
+
updateCallType(e) {
|
|
582
|
+
this._callType = e;
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* 更新媒体类型(升降级)
|
|
586
|
+
*/
|
|
587
|
+
updateMediaType(e) {
|
|
588
|
+
this._mediaType = e;
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* 更新请求的媒体类型(升降级)
|
|
592
|
+
*/
|
|
593
|
+
updateReqMediaType(e) {
|
|
594
|
+
this._reqMediaType = e;
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* 更新 invter timer id
|
|
598
|
+
*/
|
|
599
|
+
updateTimerId(e, _) {
|
|
600
|
+
e === "inviter" ? this._inviterTimerId = _ : this._inviteeTimerId = _;
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* 获取
|
|
604
|
+
*/
|
|
605
|
+
getOldDialogData() {
|
|
606
|
+
return this._oldDialogData;
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* 设置是否是己端挂断
|
|
610
|
+
*/
|
|
611
|
+
setIsLocalClientHangup(e) {
|
|
612
|
+
this.isLocalClientHangup = e;
|
|
613
|
+
}
|
|
614
|
+
getIsLocalClientHangup() {
|
|
615
|
+
return this.isLocalClientHangup;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
var A = /* @__PURE__ */ ((t) => (t.START_SINGLE_CALL = "startSingleCall", t.START_GROUP_CALL = "startGroupCall", t.INVITE_CALL = "inviteCall", t.PUB_INVITE_CALL = "pubInviteCall", t.RINGING_CALL = "ringCall", t.ACCEPT_CALL = "acceptCall", t.JOIN_CALL = "joinCall", t.HANGUP_CALL = "hangupCall", t.STATUS_UP_CALL = "statusUpCall", t.STATUS_DOWN_CALL = "statusDownCall", t.EVENT_UP_CALL = "eventUpCall", t.EVENT_DOWN_CALL = "eventDownCall", t.DIALOG_UP_CALL = "dialogUpCall", t.DIALOG_DOWN_CALL = "dialogDownCall", t.GET_CALL_USER_SESSION_LIST = "getCallUSerSessionList", t.SYNC_CALL_LOG = "syncCallLog", t.PUB_CALL_LOG = "pubCallLog", t.DEL_CALL_LOG = "deleteCallLog", t.QRY_CALL_STATE = "queryUserHasCall", t.QRY_SRV_TIMESTAMP = "getCallSrvTimeStamp", t.GET_CALL_STATE_LIST = "getUserCallStateList", t.CLEAR_CALL_LOG = "cleanCallLog", t.GET_CALL_SESSION = "getCallSession", t.GET_CALL_TIME_INFO = "getCallTimeInfo", t.END_ABNORMAL_CALL = "endUserAbnormalCalls", t.SYS_STATUS_UP = "sysStatusUp", t.UP_CALL_LOG_READED = "upCallLogReaded", t.PUB_CALL_LOG_READED = "pubCallLogReaded", t.PUB_NACK_SEQ_ID = "pubNACKSeqId", t.GET_USER_CALL_SESSION_ID_LIST = "getUserCallSessionIdList", t))(A || {});
|
|
619
|
+
const Se = (t, s) => setTimeout(t, s), je = (t) => new Promise((s) => {
|
|
620
|
+
setTimeout(s, t);
|
|
621
|
+
}), Qe = [
|
|
622
|
+
/**
|
|
623
|
+
* IM 底层返回需要重试的错误码
|
|
624
|
+
*/
|
|
625
|
+
se.RC_NET_CHANNEL_INVALID,
|
|
626
|
+
se.RC_NET_UNAVAILABLE,
|
|
627
|
+
se.RC_MSG_RESP_TIMEOUT,
|
|
628
|
+
/**
|
|
629
|
+
* RTC 返回需要重试的错误码
|
|
630
|
+
*/
|
|
631
|
+
D.SIGNAL_DISCONNECTED,
|
|
632
|
+
D.REQUEST_FAILED
|
|
633
|
+
], X = async ({
|
|
634
|
+
asyncFn: t,
|
|
635
|
+
fnArgs: s,
|
|
636
|
+
currentRetryTime: e = Date.now(),
|
|
637
|
+
maxDuration: _ = 60 * 1e3,
|
|
638
|
+
intervals: i = [2 * 1e3, 4 * 1e3, 8 * 1e3, 16 * 1e3, 32 * 1e3, 64 * 1e3],
|
|
639
|
+
index: n = 0,
|
|
640
|
+
onError: o
|
|
641
|
+
}) => {
|
|
642
|
+
const a = await t(...s), L = 2 * 1e3;
|
|
643
|
+
return a.code === E.SUCCESS || !Qe.includes(a.code) || Date.now() + L - e > _ ? a : (o && o(a.code), await je(L), X({
|
|
644
|
+
asyncFn: t,
|
|
645
|
+
fnArgs: s,
|
|
646
|
+
currentRetryTime: e,
|
|
647
|
+
maxDuration: _,
|
|
648
|
+
intervals: i,
|
|
649
|
+
index: n,
|
|
650
|
+
onError: o
|
|
651
|
+
}));
|
|
652
|
+
};
|
|
653
|
+
var x = /* @__PURE__ */ ((t) => (t.onBeforePublish = "onBeforePublish", t.onPublishRes = "onPublishRes", t.onPubInviteCall = "onPubInviteCall", t.onPubInviteCallPullKv = "onPubInviteCallPullKv", t.onPubInviteCallMiss = "onPubInviteCallMiss", t))(x || {}), re = /* @__PURE__ */ ((t) => (t.NOT_CURRENT_DEVICEID = "not current device id", t.SECRET_CALL = "secret call", t.NOT_INVITEE = "not an invitee", t))(re || {}), J = /* @__PURE__ */ ((t) => (t.PUB_INVITE = "pubinvitecall", t.PULL_KV_INVITE = "pullkv_invitecall", t.PUSH = "system_pubsh", t))(J || {});
|
|
654
|
+
class qe extends oe {
|
|
655
|
+
/**
|
|
656
|
+
* constructor
|
|
657
|
+
*/
|
|
658
|
+
constructor(e, _, i, n, o) {
|
|
659
|
+
super();
|
|
660
|
+
/**
|
|
661
|
+
* 监听对象
|
|
662
|
+
*/
|
|
663
|
+
l(this, "_listener");
|
|
664
|
+
/**
|
|
665
|
+
* 需要重试的 action
|
|
666
|
+
*/
|
|
667
|
+
l(this, "_needRetryActions", [
|
|
668
|
+
A.START_SINGLE_CALL,
|
|
669
|
+
A.START_GROUP_CALL,
|
|
670
|
+
A.ACCEPT_CALL,
|
|
671
|
+
A.JOIN_CALL,
|
|
672
|
+
A.EVENT_UP_CALL
|
|
673
|
+
]);
|
|
674
|
+
l(this, "_sessionId", "");
|
|
675
|
+
this._context = e, this._runtime = _, this._initOpts = i, this._timeCorrectioner = n, this._logger = o, this._context.onCallInfo = this._onRecvCallSignal.bind(this), this._context.onconnectionstatechange = this._onIMConnectionStateChange.bind(this), this._sessionId = Ve();
|
|
676
|
+
}
|
|
677
|
+
getSessionId() {
|
|
678
|
+
return this._sessionId;
|
|
679
|
+
}
|
|
680
|
+
registerListener(e) {
|
|
681
|
+
this._listener = e;
|
|
682
|
+
}
|
|
683
|
+
async startCall(e, _) {
|
|
684
|
+
const {
|
|
685
|
+
clientCallId: i,
|
|
686
|
+
callType: n,
|
|
687
|
+
toUsers: o,
|
|
688
|
+
mediaType: a,
|
|
689
|
+
secretChat: L,
|
|
690
|
+
targetType: c,
|
|
691
|
+
targetId: T,
|
|
692
|
+
nickName: S,
|
|
693
|
+
oldRoomId: I
|
|
694
|
+
} = e;
|
|
695
|
+
return n === M.SINGLE ? this.startSingleCall({
|
|
696
|
+
clientCallId: i,
|
|
697
|
+
toUserId: o[0].userId,
|
|
698
|
+
mediaType: a,
|
|
699
|
+
secretChat: L,
|
|
700
|
+
targetType: c,
|
|
701
|
+
targetId: T,
|
|
702
|
+
oldRoomId: I,
|
|
703
|
+
toOrgId: o[0].orgId || ""
|
|
704
|
+
}, _) : this.startGroupCall({
|
|
705
|
+
clientCallId: i,
|
|
706
|
+
toUsers: o,
|
|
707
|
+
mediaType: a,
|
|
708
|
+
targetType: c,
|
|
709
|
+
targetId: T,
|
|
710
|
+
nickName: S,
|
|
711
|
+
oldRoomId: I
|
|
712
|
+
}, _);
|
|
713
|
+
}
|
|
714
|
+
async startSingleCall(e, _) {
|
|
715
|
+
return this._logger.info(r.L_SIGNAL_TRANSPORTER_SINGLE_CALL_T, `params: ${JSON.stringify(e)}`, _), this._sendCallSignal(this._context.getCurrentId(), A.START_SINGLE_CALL, e);
|
|
716
|
+
}
|
|
717
|
+
async startGroupCall(e, _) {
|
|
718
|
+
return this._logger.info(r.L_SIGNAL_TRANSPORTER_GROUP_CALL_T, `params: ${JSON.stringify(e)}`, _), this._sendCallSignal(this._context.getCurrentId(), A.START_GROUP_CALL, e);
|
|
719
|
+
}
|
|
720
|
+
async inviteCall(e, _) {
|
|
721
|
+
return this._logger.info(r.L_SIGNAL_TRANSPORTER_INVITE_T, `params: ${JSON.stringify(e)}`, _), this._sendCallSignal(e.callId, A.INVITE_CALL, e);
|
|
722
|
+
}
|
|
723
|
+
async ringingCall(e, _) {
|
|
724
|
+
return this._logger.info(r.L_SIGNAL_TRANSPORTER_RING_T, `params: ${JSON.stringify(e)}`, _), this._sendCallSignal(e.callId, A.RINGING_CALL, e);
|
|
725
|
+
}
|
|
726
|
+
async acceptCall(e, _) {
|
|
727
|
+
return this._logger.info(r.L_SIGNAL_TRANSPORTER_ACCEPT_T, `params: ${JSON.stringify(e)}`, _), this._sendCallSignal(e.callId, A.ACCEPT_CALL, e);
|
|
728
|
+
}
|
|
729
|
+
async joinCall(e, _) {
|
|
730
|
+
return this._logger.info(r.L_SIGNAL_TRANSPORTER_JOIN_CALL_T, `params: ${JSON.stringify(e)}`, _), this._sendCallSignal(e.callId, A.JOIN_CALL, e);
|
|
731
|
+
}
|
|
732
|
+
async hangupCall(e, _) {
|
|
733
|
+
this._logger.info(r.L_SIGNAL_TRANSPORTER_HANGUP_T, `params: ${JSON.stringify(e)}`, _);
|
|
734
|
+
const { code: i } = await this._sendCallSignal(e.callId, A.HANGUP_CALL, e);
|
|
735
|
+
return i === E.NOT_IN_CALL ? { code: E.SUCCESS } : { code: i };
|
|
736
|
+
}
|
|
737
|
+
async statusUpCall(e, _) {
|
|
738
|
+
return this._logger.info(r.L_SIGNAL_TRANSPORTER_CALL_STATUS_UP_T, `call status up params: ${JSON.stringify(e)}`, _), this._sendCallSignal(e.callId, A.STATUS_UP_CALL, e);
|
|
739
|
+
}
|
|
740
|
+
async eventUpCall(e, _) {
|
|
741
|
+
return this._logger.info(r.L_SIGNAL_TRANSPORTER_CALL_EVENT_UP_T, `params: ${JSON.stringify(e)}`, _), this._sendCallSignal(e.callId, A.EVENT_UP_CALL, e);
|
|
742
|
+
}
|
|
743
|
+
async dialogUpCall(e, _) {
|
|
744
|
+
return this._logger.info(r.L_SIGNAL_TRANSPORTER_CALL_DIALOG_UP_T, `params: ${JSON.stringify(e)}`, _), this._sendCallSignal(e.callId, A.DIALOG_UP_CALL, e);
|
|
745
|
+
}
|
|
746
|
+
async deleteCallRecord(e, _, i) {
|
|
747
|
+
return this._logger.info(r.L_SIGNAL_TRANSPORTER_DELETE_CALL_RECORD_T, `callIds: ${JSON.stringify(_)}`, i), this._sendCallSignal(e, A.DEL_CALL_LOG, {
|
|
748
|
+
callIds: _
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
async syncCallLog(e, _) {
|
|
752
|
+
return this._logger.info(r.L_SIGNAL_TRANSPORTER_GET_CALL_RECORD_T, `params: ${JSON.stringify(e)}`, _), this._sendCallSignal(e.userId, A.SYNC_CALL_LOG, e);
|
|
753
|
+
}
|
|
754
|
+
async queryUserHasCall() {
|
|
755
|
+
const e = this._context.getCurrentId();
|
|
756
|
+
return this._sendCallSignal(e, A.QRY_CALL_STATE, null);
|
|
757
|
+
}
|
|
758
|
+
async getCallServerTimestamp(e) {
|
|
759
|
+
const _ = this._context.getCurrentId();
|
|
760
|
+
return this._logger.info(r.L_SIGNAL_TRANSPORTER_GET_CALL_SERVER_TIME_T, `userId: ${_}`, e), this._sendCallSignal(_, A.QRY_SRV_TIMESTAMP, null);
|
|
761
|
+
}
|
|
762
|
+
async getCallTimeInfo(e, _) {
|
|
763
|
+
return this._logger.info(r.L_SIGNAL_TRANSPORTER_GET_CALL_TIME_INFO_T, `callId: ${e}`, _), this._sendCallSignal(e, A.GET_CALL_TIME_INFO, { callId: e });
|
|
764
|
+
}
|
|
765
|
+
async getUserCallStateList(e) {
|
|
766
|
+
const _ = this._context.getCurrentId();
|
|
767
|
+
return this._logger.info(r.L_SIGNAL_TRANSPORTER_GET_AVAILABLE_CALL_LIST_T, `userId: ${_}`, e), this._sendCallSignal(_, A.GET_CALL_STATE_LIST, null);
|
|
768
|
+
}
|
|
769
|
+
async clearCallRecord(e) {
|
|
770
|
+
const _ = this._context.getCurrentId();
|
|
771
|
+
return this._logger.info(r.L_SIGNAL_TRANSPORTER_CLEAR_CALL_RECORD_T, `userId: ${_}`, e), this._sendCallSignal(_, A.CLEAR_CALL_LOG, null);
|
|
772
|
+
}
|
|
773
|
+
async getCallSession(e, _) {
|
|
774
|
+
return this._logger.info(r.L_SIGNAL_TRANSPORTER_GET_CALL_INFO_BY_CALLID_T, `callId: ${e.callId}`, _), this._sendCallSignal(e.callId, A.GET_CALL_SESSION, e);
|
|
775
|
+
}
|
|
776
|
+
async sysStatusUp(e, _) {
|
|
777
|
+
return this._logger.info(r.L_SIGNAL_TRANSPORTER_USER_SYSTEM_STATE_UP_T, `opts: ${JSON.stringify(e)}`, _), this._sendCallSignal(e.callId, A.SYS_STATUS_UP, e);
|
|
778
|
+
}
|
|
779
|
+
async upCallLogReaded(e) {
|
|
780
|
+
const _ = this._context.getCurrentId();
|
|
781
|
+
return this._sendCallSignal(_, A.UP_CALL_LOG_READED, e);
|
|
782
|
+
}
|
|
783
|
+
/** ======私有方法============================================================================================= */
|
|
784
|
+
_onIMConnectionStateChange(e) {
|
|
785
|
+
const _ = this._logger.createTraceId();
|
|
786
|
+
this._logger.info(r.L_SIGNAL_TRANSPORTER_IM_STATE_CHANGE_O, `state: ${e}`, _), this._listener.onIMStateChange(e), e === W.CONNECTED ? this._timeCorrectioner.start(_) : this._timeCorrectioner.stop(_);
|
|
787
|
+
}
|
|
788
|
+
/**
|
|
789
|
+
* call 信令发送
|
|
790
|
+
* @param targetId 获取 call log (syncCallLog) 时传 userId, 其他 action 传 callId
|
|
791
|
+
* @param key call server 定义 action
|
|
792
|
+
* @param options action 携带参数,无参数传空字符串
|
|
793
|
+
*/
|
|
794
|
+
async _sendCallSignal(e, _, i) {
|
|
795
|
+
const n = i ? JSON.stringify({ ...i, sessionId: this._sessionId }) : "";
|
|
796
|
+
let o;
|
|
797
|
+
this._needRetryActions.includes(_) ? o = await X({
|
|
798
|
+
asyncFn: this._context.setCallInfo.bind(this._context),
|
|
799
|
+
fnArgs: [e, _, n]
|
|
800
|
+
}) : o = await this._context.setCallInfo(e, _, n);
|
|
801
|
+
const { code: a, data: L } = o;
|
|
802
|
+
if (a !== se.SUCCESS)
|
|
803
|
+
return { code: a };
|
|
804
|
+
const { key: c, value: T } = L, S = JSON.parse(T).data;
|
|
805
|
+
return {
|
|
806
|
+
code: E.SUCCESS,
|
|
807
|
+
data: S
|
|
808
|
+
};
|
|
809
|
+
}
|
|
810
|
+
/**
|
|
811
|
+
* call 信令接收
|
|
812
|
+
*/
|
|
813
|
+
_onRecvCallSignal(e) {
|
|
814
|
+
const _ = this._logger.createTraceId();
|
|
815
|
+
this._logger.info(r.L_SIGNAL_TRANSPORTER_RECEIVE_CALL_SIGNAL_DATA_O, `data: ${e}`, _), JSON.parse(e).list.forEach((n) => {
|
|
816
|
+
const { key: o } = n, a = JSON.parse(n.value);
|
|
817
|
+
switch (o) {
|
|
818
|
+
case A.PUB_INVITE_CALL:
|
|
819
|
+
this._onPubInviteCall(a, !0, _);
|
|
820
|
+
break;
|
|
821
|
+
case A.STATUS_DOWN_CALL:
|
|
822
|
+
this._onStatusDownCall(a, _);
|
|
823
|
+
break;
|
|
824
|
+
case A.EVENT_DOWN_CALL:
|
|
825
|
+
this._onEventDownCall(a, _);
|
|
826
|
+
break;
|
|
827
|
+
case A.DIALOG_DOWN_CALL:
|
|
828
|
+
this._onDialogDownCall(a, _);
|
|
829
|
+
break;
|
|
830
|
+
case A.PUB_CALL_LOG:
|
|
831
|
+
this._onPubCallLog(a, _);
|
|
832
|
+
break;
|
|
833
|
+
case A.PUB_CALL_LOG_READED:
|
|
834
|
+
break;
|
|
835
|
+
case A.PUB_NACK_SEQ_ID:
|
|
836
|
+
break;
|
|
837
|
+
default:
|
|
838
|
+
this._onConpensationData(a, _);
|
|
839
|
+
break;
|
|
840
|
+
}
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
/**
|
|
844
|
+
* 根据 deviceId 判断数据是否应该下发
|
|
845
|
+
* deviceId 为空字符串或 null 直接下发
|
|
846
|
+
* deviceId 有具体的值,根据 deviceId 判断是否是己端的 deviceId
|
|
847
|
+
*/
|
|
848
|
+
_isValidData(e) {
|
|
849
|
+
return !!(Pe(e) || Oe(e) && ((e == null ? void 0 : e.length) === 0 || e === this._sessionId));
|
|
850
|
+
}
|
|
851
|
+
/**
|
|
852
|
+
* 收到邀请
|
|
853
|
+
* @param isDirectly 是否为直发信令
|
|
854
|
+
*/
|
|
855
|
+
_onPubInviteCall(e, _ = !0, i) {
|
|
856
|
+
try {
|
|
857
|
+
const n = this._context.getCurrentId(), o = e.callSessionUsers.find((L) => L.userId === n), a = this._context.getConnectionStatus();
|
|
858
|
+
this._logger.info(r.L_SIGNAL_TRANSPORTER_RECEIVE_INVITE_O, `currentUser: ${JSON.stringify(o)}, currentUserId: ${n}, state: ${a}`, i);
|
|
859
|
+
} catch (n) {
|
|
860
|
+
this._logger.error(r.L_SIGNAL_TRANSPORTER_RECEIVE_INVITE_O, `error: ${n.message}`, i);
|
|
861
|
+
}
|
|
862
|
+
if (!this._isValidData(e.toDeviceId || "")) {
|
|
863
|
+
this._logger.warn(r.L_SIGNAL_TRANSPORTER_RECEIVE_INVITE_O, `not current deviceId -> deviceInfo: ${JSON.stringify({
|
|
864
|
+
toDeviceId: e.toDeviceId,
|
|
865
|
+
clientDeviceId: this._sessionId
|
|
866
|
+
})}`, i);
|
|
867
|
+
const n = {
|
|
868
|
+
extra: JSON.stringify(e),
|
|
869
|
+
reason: re.NOT_CURRENT_DEVICEID,
|
|
870
|
+
refer: _ ? J.PUB_INVITE : J.PULL_KV_INVITE
|
|
871
|
+
};
|
|
872
|
+
_ ? this.emit(x.onPubInviteCallMiss, Object.assign(e, n)) : this.emit(x.onPubInviteCallMiss, Object.assign(e, n));
|
|
873
|
+
return;
|
|
874
|
+
}
|
|
875
|
+
this._listener.onInvite(e, _, i), _ ? this.emit(x.onPubInviteCall, Object.assign(e, { extra: JSON.stringify(e) })) : this.emit(x.onPubInviteCallPullKv, Object.assign(e, { extra: JSON.stringify(e) }));
|
|
876
|
+
}
|
|
877
|
+
/**
|
|
878
|
+
* 收到状态变更:响铃、忙碌、通话等待、对方未接听、己方未接听
|
|
879
|
+
*/
|
|
880
|
+
_onStatusDownCall(e, _) {
|
|
881
|
+
if (e.callSessionUsers = e.callSessionUsers.filter((i) => !!i.changed), this._logger.info(r.L_SIGNAL_TRANSPORTER_RECEIVE_CALL_STATUS_O, "", _), !this._isValidData(e.toDeviceId || "")) {
|
|
882
|
+
this._logger.warn(r.L_SIGNAL_TRANSPORTER_RECEIVE_CALL_STATUS_O, `not current deviceId -> deviceInfo: ${JSON.stringify({
|
|
883
|
+
toDeviceId: e.toDeviceId,
|
|
884
|
+
clientDeviceId: this._sessionId
|
|
885
|
+
})}`, _), this._listener.onOtherClientStatusDown(e, _);
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
888
|
+
this._listener.onStatusDown(e, _, this._sessionId);
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* 收到通话事件变更:打开|关闭 摄像头
|
|
892
|
+
*/
|
|
893
|
+
_onEventDownCall(e, _) {
|
|
894
|
+
this._listener.onEventDown(e, _);
|
|
895
|
+
}
|
|
896
|
+
/**
|
|
897
|
+
* 收到通话调整事件及结果
|
|
898
|
+
* 事件:媒体类型切换
|
|
899
|
+
* 动作:请求、接受、拒绝、取消
|
|
900
|
+
*/
|
|
901
|
+
_onDialogDownCall(e, _) {
|
|
902
|
+
const { dialogType: i, action: n, extraKeyVal: o } = e;
|
|
903
|
+
switch (i) {
|
|
904
|
+
case q.SWITCH_MEDIA_TYPE:
|
|
905
|
+
this._listener.onSwitchMediaType(e, _);
|
|
906
|
+
break;
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
/**
|
|
910
|
+
* 通话结束后,日志下发
|
|
911
|
+
*/
|
|
912
|
+
_onPubCallLog(e, _) {
|
|
913
|
+
this._logger.info(r.L_CALL_ENGINE_RECEIVE_CALL_RECORD_O, `call record: ${JSON.stringify(e)}`, _), this._listener.onRecvCallEndLog(e, _);
|
|
914
|
+
}
|
|
915
|
+
/**
|
|
916
|
+
* 补偿数据处理
|
|
917
|
+
*/
|
|
918
|
+
_onConpensationData(e, _) {
|
|
919
|
+
this._logger.info(r.L_CALL_ENGINE_RECEIVE_COMPLEMENTARY_DATA_O, "", _);
|
|
920
|
+
const {
|
|
921
|
+
callId: i,
|
|
922
|
+
callType: n,
|
|
923
|
+
mediaType: o,
|
|
924
|
+
secretChat: a,
|
|
925
|
+
duration: L,
|
|
926
|
+
callStatus: c,
|
|
927
|
+
callingUserId: T,
|
|
928
|
+
callSessionUsers: S,
|
|
929
|
+
toDeviceId: I,
|
|
930
|
+
callDialogEntitys: d
|
|
931
|
+
} = e;
|
|
932
|
+
S.some((O) => O.sessionStatus === C.INVITED && O.userId === this._context.getCurrentId()) ? this._onPubInviteCall({
|
|
933
|
+
callId: i,
|
|
934
|
+
toDeviceId: I,
|
|
935
|
+
callType: n,
|
|
936
|
+
mediaType: o,
|
|
937
|
+
inviteUserId: T,
|
|
938
|
+
callingUserId: T,
|
|
939
|
+
callSessionUsers: S,
|
|
940
|
+
secretChat: a
|
|
941
|
+
}, !0, _) : this._onStatusDownCall({
|
|
942
|
+
callId: i,
|
|
943
|
+
toDeviceId: I,
|
|
944
|
+
callStatus: c,
|
|
945
|
+
duration: L,
|
|
946
|
+
callSessionUsers: S
|
|
947
|
+
}, _), d.length > 0 && d.forEach((O) => this._onDialogDownCall(O, _), this);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
const Xe = (t) => {
|
|
951
|
+
const s = "0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ+/".split(""), e = s.length + 1;
|
|
952
|
+
let _ = +t;
|
|
953
|
+
const i = [];
|
|
954
|
+
do {
|
|
955
|
+
const n = _ % e;
|
|
956
|
+
_ = (_ - n) / e, i.unshift(s[n]);
|
|
957
|
+
} while (_);
|
|
958
|
+
return i.join("");
|
|
959
|
+
}, ze = () => "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (t) => {
|
|
960
|
+
const s = Math.random() * 16 | 0;
|
|
961
|
+
return (t === "x" ? s : s & 3 | 8).toString(16);
|
|
962
|
+
}), Ze = () => {
|
|
963
|
+
let t = ze();
|
|
964
|
+
return t = `${t.replace(/-/g, "")}0`, t = parseInt(t, 16), t = Xe(t), t.length > 22 && (t = t.slice(0, 22)), t;
|
|
965
|
+
}, e_ = "RC_CALLPLUS", __ = 1;
|
|
966
|
+
let v;
|
|
967
|
+
const y = class y {
|
|
968
|
+
constructor() {
|
|
969
|
+
}
|
|
970
|
+
static init(s, e) {
|
|
971
|
+
v = s, this.isSupport() || v.info("[RCCallIndexDB]", "IndexDB is not support in the current environment");
|
|
972
|
+
const _ = window.indexedDB.open(e_, __);
|
|
973
|
+
_.onerror = (i) => {
|
|
974
|
+
v.warn("[RCCallIndexDB]", `open indexDB req failed -> ${i.target.error}`);
|
|
975
|
+
}, _.onsuccess = (i) => {
|
|
976
|
+
this._db = i.target.result, this._db && (this._db.onclose = (n) => {
|
|
977
|
+
v.warn("[RCCallIndexDB]", `The db ${this._db.name} has unexpectedly closed. ${n}`), this.unInit();
|
|
978
|
+
}, this._db.onerror = (n) => {
|
|
979
|
+
v.warn("[RCCallIndexDB]", `The db ${this._db.name} has opening error. ${n}`), this.unInit();
|
|
980
|
+
}, this._db.onabort = (n) => {
|
|
981
|
+
v.warn("[RCCallIndexDB]", `The db ${this._db.name} has opening aborted. ${n}`), this.unInit();
|
|
982
|
+
}), y._instance = new y(), e.onSuccess();
|
|
983
|
+
}, _.onupgradeneeded = (i) => {
|
|
984
|
+
this._db = i.target.result, y.createObjStore("CallBW_AbnormalCall", { keyPath: "userId" });
|
|
985
|
+
};
|
|
986
|
+
}
|
|
987
|
+
static unInit() {
|
|
988
|
+
this._db = null, this._instance = null;
|
|
989
|
+
}
|
|
990
|
+
static getInstance() {
|
|
991
|
+
return this._instance;
|
|
992
|
+
}
|
|
993
|
+
static isSupport() {
|
|
994
|
+
return !(typeof window > "u" || !window || !window.indexedDB);
|
|
995
|
+
}
|
|
996
|
+
static createObjStore(s, e) {
|
|
997
|
+
var _;
|
|
998
|
+
(_ = y._db) != null && _.objectStoreNames.contains(s) ? v.debug("[RCCallIndexDB]", `createObjStore ${s} already exists`) : y._db.createObjectStore(s, e);
|
|
999
|
+
}
|
|
1000
|
+
/**
|
|
1001
|
+
* @param objName 表明
|
|
1002
|
+
* @param val 要添加的数据
|
|
1003
|
+
*/
|
|
1004
|
+
addValue(s, e) {
|
|
1005
|
+
return new Promise((_, i) => {
|
|
1006
|
+
if (!y._db) {
|
|
1007
|
+
_(!1);
|
|
1008
|
+
return;
|
|
1009
|
+
}
|
|
1010
|
+
const o = y._db.transaction([s], "readwrite").objectStore(s).add(e);
|
|
1011
|
+
o.onsuccess = () => {
|
|
1012
|
+
_(!0);
|
|
1013
|
+
}, o.onerror = () => {
|
|
1014
|
+
v.debug("[RCCallIndexDB]", "addValue failed"), _(!1);
|
|
1015
|
+
};
|
|
1016
|
+
});
|
|
1017
|
+
}
|
|
1018
|
+
/**
|
|
1019
|
+
* 根据主键读取数据
|
|
1020
|
+
* @param key 主键
|
|
1021
|
+
*/
|
|
1022
|
+
readByKey(s, e) {
|
|
1023
|
+
return new Promise((_, i) => {
|
|
1024
|
+
if (!y._db) {
|
|
1025
|
+
_(null);
|
|
1026
|
+
return;
|
|
1027
|
+
}
|
|
1028
|
+
const o = y._db.transaction([s]).objectStore(s).get(e);
|
|
1029
|
+
o.onsuccess = () => {
|
|
1030
|
+
_(o.result);
|
|
1031
|
+
}, o.onerror = (a) => {
|
|
1032
|
+
v.warn("[RCCallIndexDB]", `readByKey onerror -> ${a}`), _(null);
|
|
1033
|
+
};
|
|
1034
|
+
});
|
|
1035
|
+
}
|
|
1036
|
+
/**
|
|
1037
|
+
* 根据主键更新数据
|
|
1038
|
+
*/
|
|
1039
|
+
updateByKey(s, e, _) {
|
|
1040
|
+
return new Promise((i, n) => {
|
|
1041
|
+
if (!y._db) {
|
|
1042
|
+
i(!1);
|
|
1043
|
+
return;
|
|
1044
|
+
}
|
|
1045
|
+
const a = y._db.transaction([s], "readwrite").objectStore(s).put(_);
|
|
1046
|
+
a.onsuccess = () => {
|
|
1047
|
+
i(!0);
|
|
1048
|
+
}, a.onerror = (L) => {
|
|
1049
|
+
i(!1), v.warn("[RCCallIndexDB]", `updateByKey onerror -> ${L}`);
|
|
1050
|
+
};
|
|
1051
|
+
});
|
|
1052
|
+
}
|
|
1053
|
+
removeByKey(s, e) {
|
|
1054
|
+
return new Promise((_, i) => {
|
|
1055
|
+
if (!y._db) {
|
|
1056
|
+
_(!1);
|
|
1057
|
+
return;
|
|
1058
|
+
}
|
|
1059
|
+
const o = y._db.transaction([s], "readwrite").objectStore(s).delete(e);
|
|
1060
|
+
o.onsuccess = () => {
|
|
1061
|
+
_(!0);
|
|
1062
|
+
}, o.onerror = (a) => {
|
|
1063
|
+
_(!1), v.warn("[RCCallIndexDB]", `removeByKey onerror -> ${a}`);
|
|
1064
|
+
};
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
};
|
|
1068
|
+
/**
|
|
1069
|
+
* call indexDB 库
|
|
1070
|
+
*/
|
|
1071
|
+
l(y, "_db", null), /**
|
|
1072
|
+
* RCCallIndexDB 实例
|
|
1073
|
+
*/
|
|
1074
|
+
l(y, "_instance", null);
|
|
1075
|
+
let z = y;
|
|
1076
|
+
class t_ {
|
|
1077
|
+
constructor(s, e) {
|
|
1078
|
+
l(this, "_localStore");
|
|
1079
|
+
l(this, "_indexDBStore");
|
|
1080
|
+
l(this, "_storeKey", "CallBW_AbnormalCall");
|
|
1081
|
+
l(this, "_isSupportIndexDB");
|
|
1082
|
+
if (this._runtime = s, this._logger = e, this._isSupportIndexDB = z.isSupport(), this._isSupportIndexDB) {
|
|
1083
|
+
z.init(this._logger, {
|
|
1084
|
+
onSuccess: () => {
|
|
1085
|
+
this._indexDBStore = z.getInstance();
|
|
1086
|
+
}
|
|
1087
|
+
});
|
|
1088
|
+
return;
|
|
1089
|
+
}
|
|
1090
|
+
this._localStore = s.localStorage;
|
|
1091
|
+
}
|
|
1092
|
+
/**
|
|
1093
|
+
* 添加异常 callId
|
|
1094
|
+
*/
|
|
1095
|
+
addAbnormallCallId(s, e) {
|
|
1096
|
+
(this._isSupportIndexDB ? this._addByIndexDB : this._addByLocalStore).call(this, s, e);
|
|
1097
|
+
}
|
|
1098
|
+
/**
|
|
1099
|
+
* 删除异常 callId
|
|
1100
|
+
*/
|
|
1101
|
+
removeAbnormalCallIds(s, e) {
|
|
1102
|
+
(this._isSupportIndexDB ? this._removeByIndexDB : this._removeByLocalStore).call(this, s, e);
|
|
1103
|
+
}
|
|
1104
|
+
/**
|
|
1105
|
+
* 获取异常结束的 callId 列表
|
|
1106
|
+
*/
|
|
1107
|
+
getAbnormalCallIds(s) {
|
|
1108
|
+
return (this._isSupportIndexDB ? this._getByIndexDB : this._getByLocalStore).call(this, s);
|
|
1109
|
+
}
|
|
1110
|
+
_addByLocalStore(s, e) {
|
|
1111
|
+
try {
|
|
1112
|
+
const _ = JSON.parse(this._localStore.getItem(this._storeKey) || "{}");
|
|
1113
|
+
let i = _[s];
|
|
1114
|
+
i ? i.push(e) : i = [e], _[s] = i, this._localStore.setItem(this._storeKey, JSON.stringify(_));
|
|
1115
|
+
} catch (_) {
|
|
1116
|
+
this._logger.warn("[AbnormalCall]", `_addByLocalStore err: ${_.message}`);
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
_removeByLocalStore(s, e) {
|
|
1120
|
+
try {
|
|
1121
|
+
const _ = JSON.parse(this._localStore.getItem(this._storeKey) || "{}");
|
|
1122
|
+
let i = _[s];
|
|
1123
|
+
i && (i = i.filter((n) => !e.includes(n)), i.length > 0 ? _[s] = i : delete _[s], this._localStore.setItem(this._storeKey, JSON.stringify(_)));
|
|
1124
|
+
} catch (_) {
|
|
1125
|
+
this._logger.warn("[AbnormalCall]", `_removeByLocalStore err: ${_.message}`);
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
_getByLocalStore(s) {
|
|
1129
|
+
let e = null;
|
|
1130
|
+
try {
|
|
1131
|
+
const i = JSON.parse(this._localStore.getItem(this._storeKey) || "{}")[s];
|
|
1132
|
+
i && (e = i);
|
|
1133
|
+
} catch (_) {
|
|
1134
|
+
this._logger.warn("[AbnormalCall]", `_getByLocalStore err: ${_.message}`);
|
|
1135
|
+
}
|
|
1136
|
+
return Promise.resolve(e);
|
|
1137
|
+
}
|
|
1138
|
+
async _addByIndexDB(s, e) {
|
|
1139
|
+
try {
|
|
1140
|
+
const _ = await this._indexDBStore.readByKey(this._storeKey, s);
|
|
1141
|
+
_ ? (_.callIds.push(e), this._indexDBStore.updateByKey(this._storeKey, s, {
|
|
1142
|
+
userId: s,
|
|
1143
|
+
callIds: _.callIds
|
|
1144
|
+
})) : this._indexDBStore.addValue(this._storeKey, {
|
|
1145
|
+
userId: s,
|
|
1146
|
+
callIds: [e]
|
|
1147
|
+
});
|
|
1148
|
+
} catch (_) {
|
|
1149
|
+
this._logger.warn("[AbnormalCall]", `_addByIndexDB err: ${_.message}`);
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
async _removeByIndexDB(s, e) {
|
|
1153
|
+
try {
|
|
1154
|
+
const _ = await this._indexDBStore.readByKey(this._storeKey, s);
|
|
1155
|
+
_ && (_.callIds = _.callIds.filter((i) => !e.includes(i)), _.callIds.length > 0 ? this._indexDBStore.updateByKey(this._storeKey, s, {
|
|
1156
|
+
userId: s,
|
|
1157
|
+
callIds: _.callIds
|
|
1158
|
+
}) : this._indexDBStore.removeByKey(this._storeKey, s));
|
|
1159
|
+
} catch (_) {
|
|
1160
|
+
this._logger.warn("[AbnormalCall]", `_removeByIndexDB err: ${_.message}`);
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
async _getByIndexDB(s) {
|
|
1164
|
+
let e = null;
|
|
1165
|
+
try {
|
|
1166
|
+
e = await this._indexDBStore.readByKey(this._storeKey, s);
|
|
1167
|
+
} catch (_) {
|
|
1168
|
+
this._logger.warn("[AbnormalCall]", `_getByIndexDB err: ${_.message}`);
|
|
1169
|
+
}
|
|
1170
|
+
return e ? e.callIds : null;
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
var le = /* @__PURE__ */ ((t) => (t[t.PROMPT = 0] = "PROMPT", t[t.CALL_DURATION = 10] = "CALL_DURATION", t[t.FIRST_FRAME = 20] = "FIRST_FRAME", t))(le || {}), P = /* @__PURE__ */ ((t) => (t[t.SUCCESS = 0] = "SUCCESS", t[t.INVALID_RESPONSE_TIME = 80170] = "INVALID_RESPONSE_TIME", t[t.NONOPTIMAL_RES_TIME = 80171] = "NONOPTIMAL_RES_TIME", t))(P || {});
|
|
1174
|
+
class i_ {
|
|
1175
|
+
constructor(s, e, _) {
|
|
1176
|
+
/**
|
|
1177
|
+
* 接口响应时间
|
|
1178
|
+
*/
|
|
1179
|
+
l(this, "_RTT", 0);
|
|
1180
|
+
/**
|
|
1181
|
+
* 可用的接口响应时间下限(单位: ms)
|
|
1182
|
+
*/
|
|
1183
|
+
l(this, "_validMinRTT", 200);
|
|
1184
|
+
/**
|
|
1185
|
+
* 可用的接口响应时间上限(单位: ms)
|
|
1186
|
+
*/
|
|
1187
|
+
l(this, "_validMaxRTT", 1e3);
|
|
1188
|
+
/**
|
|
1189
|
+
* 与 callServer 的时间偏差时间(单位: ms)
|
|
1190
|
+
*/
|
|
1191
|
+
l(this, "_deltaTime", 0);
|
|
1192
|
+
/**
|
|
1193
|
+
* timerId
|
|
1194
|
+
*/
|
|
1195
|
+
l(this, "_timerId", null);
|
|
1196
|
+
/**
|
|
1197
|
+
* 轮训时间间隔(单位: ms)
|
|
1198
|
+
*/
|
|
1199
|
+
l(this, "_interval", 2 * 1e3);
|
|
1200
|
+
/**
|
|
1201
|
+
* 最大重试次数
|
|
1202
|
+
*/
|
|
1203
|
+
l(this, "_maxRetryTimes", 8);
|
|
1204
|
+
l(this, "_startTimes", 0);
|
|
1205
|
+
l(this, "_retryTimesInCall", 0);
|
|
1206
|
+
l(this, "_maxRetryTimesInCall", 3);
|
|
1207
|
+
this._callEngine = s, this._logger = e, this._singleCallDurationEv = _;
|
|
1208
|
+
}
|
|
1209
|
+
/**
|
|
1210
|
+
* 从服务端获取通话时长、通话开始时间
|
|
1211
|
+
*/
|
|
1212
|
+
async getCallClientTimeByServer(s, e) {
|
|
1213
|
+
this._logger.info(r.L_TIME_CORRECT_GET_CALL_CLIENT_TIME_BY_SERVER_T, `callId: ${s}`, e), (!this._RTT || this._RTT > this._validMinRTT) && await this._getDeltaTime(e), this._RTT > this._validMaxRTT && this._logger.error(r.L_TIME_CORRECT_GET_CALL_CLIENT_TIME_BY_SERVER_R, `code: ${P.INVALID_RESPONSE_TIME}`, e);
|
|
1214
|
+
const { code: _, data: i } = await this._callEngine.getCallTimeInfo(s, e);
|
|
1215
|
+
if (_ !== E.SUCCESS)
|
|
1216
|
+
return this._logger.error(r.L_TIME_CORRECT_GET_CALL_CLIENT_TIME_BY_SERVER_R, `code: ${_}`, e), { code: _ };
|
|
1217
|
+
const { startTime: n } = i, o = Math.floor(n - this._deltaTime);
|
|
1218
|
+
let L = (Date.now() + this._deltaTime - n) / 1e3;
|
|
1219
|
+
return L < 0 && (this._logger.warn(r.L_TIME_CORRECT_GET_CALL_CLIENT_TIME_BY_SERVER_P, `invalid duration: ${L}`, e), L = 0), L = Math.floor(L), this._RTT > this._validMinRTT && this._RTT <= this._validMaxRTT && this._logger.error(r.L_TIME_CORRECT_GET_CALL_CLIENT_TIME_BY_SERVER_R, `code: ${P.NONOPTIMAL_RES_TIME}`, e), this._logger.info(r.L_TIME_CORRECT_GET_CALL_CLIENT_TIME_BY_SERVER_R, JSON.stringify({
|
|
1220
|
+
rtt: this._RTT,
|
|
1221
|
+
deltaT: this._deltaTime,
|
|
1222
|
+
serverStartTime: n,
|
|
1223
|
+
clientStartTime: o,
|
|
1224
|
+
duration: L
|
|
1225
|
+
}), e), { code: _, duration: L, clientStartTime: o };
|
|
1226
|
+
}
|
|
1227
|
+
/**
|
|
1228
|
+
* 直接计算客户端开始时间
|
|
1229
|
+
*/
|
|
1230
|
+
calcClientStartTime(s, e, _) {
|
|
1231
|
+
if (this._logger.info(r.L_TIME_CORRECT_CALC_CLIENT_START_TIME_T, `callId: ${s}, startTime: ${e}`, _), this._RTT > this._validMaxRTT)
|
|
1232
|
+
return this._logger.error(r.L_TIME_CORRECT_CALC_CLIENT_START_TIME_R, `code: ${P.INVALID_RESPONSE_TIME}`, _), this._loopCorrectClientTime(s, _), { code: P.INVALID_RESPONSE_TIME };
|
|
1233
|
+
const i = Math.floor(e - this._deltaTime);
|
|
1234
|
+
return this._logger.info(r.L_TIME_CORRECT_CALC_CLIENT_START_TIME_R, JSON.stringify({
|
|
1235
|
+
rtt: this._RTT,
|
|
1236
|
+
deltaT: this._deltaTime,
|
|
1237
|
+
startT: e,
|
|
1238
|
+
clientStartTime: i
|
|
1239
|
+
}), _), this._RTT > this._validMinRTT && (this._retryTimesInCall = 0, this._loopCorrectClientTime(s, _)), { code: P.SUCCESS, clientStartTime: i };
|
|
1240
|
+
}
|
|
1241
|
+
/**
|
|
1242
|
+
* 开始定时递归获取与 CallServer 的时间偏差值
|
|
1243
|
+
*/
|
|
1244
|
+
start(s) {
|
|
1245
|
+
this._timerId || this._startTimes >= this._maxRetryTimes || (this._logger.info(r.L_TIME_CORRECT_START_O, `timerId: ${this._timerId}`), this._startTimes++, this._getDeltaTime(s), this._timerId = Se(() => {
|
|
1246
|
+
this._timerId = null, this.start(s);
|
|
1247
|
+
}, this._interval));
|
|
1248
|
+
}
|
|
1249
|
+
/**
|
|
1250
|
+
* 停止定时轮训
|
|
1251
|
+
*/
|
|
1252
|
+
stop(s) {
|
|
1253
|
+
this._logger.info(r.L_TIME_CORRECT_STOP_O, `timerId: ${this._timerId}`, s), this._timerId && clearTimeout(this._timerId), this._timerId = null, this._startTimes = 0;
|
|
1254
|
+
}
|
|
1255
|
+
/**
|
|
1256
|
+
* 重新定时轮训
|
|
1257
|
+
*/
|
|
1258
|
+
restart(s) {
|
|
1259
|
+
this._logger.info(r.L_TIME_CORRECT_RESTART_O, `legal rtt time, RTT: ${this._RTT}, validMinRTT: ${this._validMinRTT}`, s), !(this._RTT < this._validMinRTT) && (this.stop(s), this.start(s));
|
|
1260
|
+
}
|
|
1261
|
+
getLocalDelayTime() {
|
|
1262
|
+
return this._deltaTime;
|
|
1263
|
+
}
|
|
1264
|
+
getRTT() {
|
|
1265
|
+
return this._RTT;
|
|
1266
|
+
}
|
|
1267
|
+
/**
|
|
1268
|
+
* 获取与 CallServer 的时间偏差值,非通话中的计算
|
|
1269
|
+
*/
|
|
1270
|
+
async _getDeltaTime(s) {
|
|
1271
|
+
const e = Date.now(), { code: _, data: i } = await this._callEngine.getCallServerTimestamp(s), n = Date.now();
|
|
1272
|
+
if (_ !== E.SUCCESS)
|
|
1273
|
+
return { code: _ };
|
|
1274
|
+
const o = n - e;
|
|
1275
|
+
return (o < this._RTT || this._RTT === 0) && o <= this._validMaxRTT && (this._RTT = o), o < this._validMinRTT && this.stop(s), this._deltaTime = i - e - this._RTT / 2, this._logger.info(r.L_TIME_CORRECT_SET_DELTA_TIME_O, JSON.stringify({
|
|
1276
|
+
rtt: this._RTT,
|
|
1277
|
+
deltaT: this._deltaTime
|
|
1278
|
+
}), s), { code: _, delayTime: this._deltaTime };
|
|
1279
|
+
}
|
|
1280
|
+
/**
|
|
1281
|
+
* 通话中获取开始时间
|
|
1282
|
+
*/
|
|
1283
|
+
async _getDeltaTimeInCall(s, e) {
|
|
1284
|
+
const _ = Date.now(), { code: i, data: n } = await this._callEngine.getCallTimeInfo(s, e), o = Date.now();
|
|
1285
|
+
if (i !== E.SUCCESS)
|
|
1286
|
+
return { code: i };
|
|
1287
|
+
const a = o - _;
|
|
1288
|
+
a < this._RTT && (this._RTT = a), this._deltaTime = n.syncTime - _ - this._RTT / 2, this._logger.info(r.L_TIME_CORRECT_SET_DELTA_TIME_O, JSON.stringify({
|
|
1289
|
+
callId: s,
|
|
1290
|
+
rtt: this._RTT,
|
|
1291
|
+
deltaT: this._deltaTime
|
|
1292
|
+
}), e);
|
|
1293
|
+
const L = Math.floor(n.startTime - this._deltaTime), c = Math.floor(n.firstFrametime - this._deltaTime);
|
|
1294
|
+
return a < this._validMinRTT ? { code: P.SUCCESS, clientStartTime: L, clientFirstFrameTime: c } : { code: P.INVALID_RESPONSE_TIME, clientStartTime: L, clientFirstFrameTime: c };
|
|
1295
|
+
}
|
|
1296
|
+
/**
|
|
1297
|
+
* 多次校正抛给业务层的通话开始时间、首帧时间
|
|
1298
|
+
*/
|
|
1299
|
+
async _loopCorrectClientTime(s, e) {
|
|
1300
|
+
this.stop(e), this._logger.info(r.L_TIME_CORRECT_LOOP_CORRECT_CLINET_TIME_T, `callId: ${s}`, e);
|
|
1301
|
+
const { code: _, clientStartTime: i, clientFirstFrameTime: n } = await this._getDeltaTimeInCall(s, e);
|
|
1302
|
+
if (_ === P.SUCCESS) {
|
|
1303
|
+
this._logger.info(r.L_TIME_CORRECT_LOOP_CORRECT_CLINET_TIME_R, `code: ${E.SUCCESS}`, e), this._singleCallDurationEv(s, i, n, e);
|
|
1304
|
+
return;
|
|
1305
|
+
}
|
|
1306
|
+
if (this._retryTimesInCall > this._maxRetryTimesInCall && _ === P.INVALID_RESPONSE_TIME) {
|
|
1307
|
+
this._logger.info(r.L_TIME_CORRECT_LOOP_CORRECT_CLINET_TIME_R, `code: ${P.INVALID_RESPONSE_TIME}`, e), this._singleCallDurationEv(s, i, n, e);
|
|
1308
|
+
return;
|
|
1309
|
+
}
|
|
1310
|
+
this._retryTimesInCall > this._maxRetryTimesInCall || (this._retryTimesInCall++, setTimeout(() => {
|
|
1311
|
+
this._loopCorrectClientTime(s, e);
|
|
1312
|
+
}, this._interval));
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
var Z = /* @__PURE__ */ ((t) => (t[t.SOON_AFETER = 0] = "SOON_AFETER", t[t.CURRENT = 1] = "CURRENT", t))(Z || {}), Ie = /* @__PURE__ */ ((t) => (t[t.PUB_INVITE_CALL = 0] = "PUB_INVITE_CALL", t[t.PULL_KV_INVITE_CALL = 1] = "PULL_KV_INVITE_CALL", t[t.SYSTEM_PUSH = 2] = "SYSTEM_PUSH", t))(Ie || {}), Ce = /* @__PURE__ */ ((t) => (t[t.OUT = -1] = "OUT", t[t.GROUP = 0] = "GROUP", t[t.IN = 1] = "IN", t))(Ce || {});
|
|
1316
|
+
const Re = 60 * 1e3, w = class w extends oe {
|
|
1317
|
+
/**
|
|
1318
|
+
* 构造器
|
|
1319
|
+
*/
|
|
1320
|
+
constructor(e, _, i, n, o) {
|
|
1321
|
+
super();
|
|
1322
|
+
/**
|
|
1323
|
+
* 主 session
|
|
1324
|
+
*/
|
|
1325
|
+
l(this, "_mainSession", null);
|
|
1326
|
+
/**
|
|
1327
|
+
* 在通话中收到的 邀请 session
|
|
1328
|
+
*/
|
|
1329
|
+
l(this, "_holdSessions", []);
|
|
1330
|
+
/**
|
|
1331
|
+
* 信令模块
|
|
1332
|
+
*/
|
|
1333
|
+
l(this, "_signalModule");
|
|
1334
|
+
/**
|
|
1335
|
+
* 异常结束 call 处理器
|
|
1336
|
+
*/
|
|
1337
|
+
l(this, "_abnormalModule");
|
|
1338
|
+
/**
|
|
1339
|
+
* 记录单呼中,是否上报过第一帧
|
|
1340
|
+
* 置 true 时机:收到远端第一帧,成功上报 Server
|
|
1341
|
+
* 置 false 时机:通话结束
|
|
1342
|
+
*/
|
|
1343
|
+
l(this, "_isUpFirstFrameTime", !1);
|
|
1344
|
+
/**
|
|
1345
|
+
* 通话为 ONCALL 时,SDK 需给业务层上报通话开始计时事件
|
|
1346
|
+
* 会收到多次 ONCALL,所以需要标识是否已抛过事件
|
|
1347
|
+
*/
|
|
1348
|
+
l(this, "_callStartMap", {});
|
|
1349
|
+
/**
|
|
1350
|
+
* 校时器
|
|
1351
|
+
*/
|
|
1352
|
+
l(this, "_timeCorrectioner");
|
|
1353
|
+
this._context = e, this._runtime = _, this._initOpts = i, this._logger = n, this._reportAppEventModule = o, this._timeCorrectioner = new i_(this, n, this._onRecvSinCallDuration.bind(this)), this._signalModule = new qe(e, _, i, this._timeCorrectioner, this._logger), this._signalModule.registerListener({
|
|
1354
|
+
onInvite: this._onInvite.bind(this),
|
|
1355
|
+
onStatusDown: this._onStatusDown.bind(this),
|
|
1356
|
+
onOtherClientStatusDown: this._onOtherClientStatusDown.bind(this),
|
|
1357
|
+
onEventDown: this._onEventDown.bind(this),
|
|
1358
|
+
onSwitchMediaType: this._onSwitchMediaType.bind(this),
|
|
1359
|
+
onRecvCallEndLog: this._onRecvCallEndLog.bind(this),
|
|
1360
|
+
onIMStateChange: this._onIMStateChange.bind(this)
|
|
1361
|
+
}), this._abnormalModule = new t_(_, n);
|
|
1362
|
+
}
|
|
1363
|
+
/**
|
|
1364
|
+
* 发起呼叫
|
|
1365
|
+
*/
|
|
1366
|
+
async startCall(e, _) {
|
|
1367
|
+
const i = this._context.getCurrentId(), {
|
|
1368
|
+
callType: n,
|
|
1369
|
+
mediaType: o,
|
|
1370
|
+
toUsers: a,
|
|
1371
|
+
targetId: L,
|
|
1372
|
+
targetType: c,
|
|
1373
|
+
oldRoomId: T
|
|
1374
|
+
} = e, { code: S, data: I } = await this._signalModule.startCall({
|
|
1375
|
+
clientCallId: e.callId,
|
|
1376
|
+
callType: n,
|
|
1377
|
+
mediaType: o,
|
|
1378
|
+
toUsers: a,
|
|
1379
|
+
secretChat: ce.NORMAL,
|
|
1380
|
+
targetType: c,
|
|
1381
|
+
targetId: L,
|
|
1382
|
+
oldRoomId: T
|
|
1383
|
+
}, _);
|
|
1384
|
+
if (S !== E.SUCCESS)
|
|
1385
|
+
return { code: S };
|
|
1386
|
+
const { callId: d, busylineUsers: g } = I;
|
|
1387
|
+
if (this._abnormalModule.addAbnormallCallId(i, d), this._mainSession = new Le(
|
|
1388
|
+
d,
|
|
1389
|
+
p.INVITED,
|
|
1390
|
+
n,
|
|
1391
|
+
o,
|
|
1392
|
+
i,
|
|
1393
|
+
i,
|
|
1394
|
+
[],
|
|
1395
|
+
this._logger
|
|
1396
|
+
), n === M.SINGLE) {
|
|
1397
|
+
const N = this._startTimer(I.callId, C.NO_ANSWER, _);
|
|
1398
|
+
this._mainSession.updateTimerId(Te.INVITER, N);
|
|
1399
|
+
}
|
|
1400
|
+
const O = {
|
|
1401
|
+
userId: i,
|
|
1402
|
+
userState: C.CALLING,
|
|
1403
|
+
systemState: h.CALLING,
|
|
1404
|
+
targetType: c,
|
|
1405
|
+
targetId: L,
|
|
1406
|
+
cameraEnable: !1,
|
|
1407
|
+
microphoneEnable: !1
|
|
1408
|
+
};
|
|
1409
|
+
let u = a.map(({ userId: N, targetType: U, targetId: f }) => ({
|
|
1410
|
+
userId: N,
|
|
1411
|
+
userState: C.INVITED,
|
|
1412
|
+
systemState: h.INVITED,
|
|
1413
|
+
targetType: U,
|
|
1414
|
+
targetId: f,
|
|
1415
|
+
cameraEnable: !1,
|
|
1416
|
+
microphoneEnable: !1
|
|
1417
|
+
})), m = [];
|
|
1418
|
+
return g && (m = g.map((N) => {
|
|
1419
|
+
const { targetType: U, targetId: f } = u.find((B) => B.userId === N.userId);
|
|
1420
|
+
return {
|
|
1421
|
+
userId: N.userId,
|
|
1422
|
+
userState: N.sessionStatus,
|
|
1423
|
+
systemState: h.BUSYLINE_RINGING,
|
|
1424
|
+
targetType: U,
|
|
1425
|
+
targetId: f,
|
|
1426
|
+
cameraEnable: !1,
|
|
1427
|
+
microphoneEnable: !1
|
|
1428
|
+
};
|
|
1429
|
+
}), u = u.filter(({ userId: N }) => m.every(({ userId: U }) => U !== N))), setTimeout(() => {
|
|
1430
|
+
this.updateUsersState(d, [O, ...u, ...m], _);
|
|
1431
|
+
}), { code: S, data: I };
|
|
1432
|
+
}
|
|
1433
|
+
/**
|
|
1434
|
+
* 通话中邀请
|
|
1435
|
+
*/
|
|
1436
|
+
async invite(e, _) {
|
|
1437
|
+
var L;
|
|
1438
|
+
if (!this._mainSession)
|
|
1439
|
+
return { code: E.NOT_IN_CALL };
|
|
1440
|
+
const { toUsers: i } = e, n = this._mainSession.getCallId(), { code: o, data: a } = await this._signalModule.inviteCall({
|
|
1441
|
+
callId: n,
|
|
1442
|
+
toUsers: i
|
|
1443
|
+
}, _);
|
|
1444
|
+
if (o === E.SUCCESS) {
|
|
1445
|
+
this._mainSession.getCallType() === M.SINGLE && (this._mainSession.updateCallType(M.MULTI), this._onCallTypeChange(this._mainSession.getCallId(), M.MULTI, _));
|
|
1446
|
+
let c = i.map(({ userId: S, targetType: I, targetId: d }) => ({
|
|
1447
|
+
userId: S,
|
|
1448
|
+
userState: C.INVITED,
|
|
1449
|
+
systemState: h.INVITED,
|
|
1450
|
+
targetType: I,
|
|
1451
|
+
targetId: d,
|
|
1452
|
+
cameraEnable: !1,
|
|
1453
|
+
microphoneEnable: !1
|
|
1454
|
+
})), T = [];
|
|
1455
|
+
a.busylineUsers && (T = (L = a.busylineUsers) == null ? void 0 : L.map((S) => {
|
|
1456
|
+
const { targetType: I, targetId: d } = c.find((g) => g.userId === S.userId);
|
|
1457
|
+
return {
|
|
1458
|
+
userId: S.userId,
|
|
1459
|
+
userState: S.sessionStatus,
|
|
1460
|
+
systemState: h.BUSYLINE_RINGING,
|
|
1461
|
+
targetType: I,
|
|
1462
|
+
targetId: d,
|
|
1463
|
+
cameraEnable: !1,
|
|
1464
|
+
microphoneEnable: !1
|
|
1465
|
+
};
|
|
1466
|
+
}), c = c.filter(({ userId: S }) => T.every(({ userId: I }) => I !== S))), this.updateUsersState(n, [...c, ...T], _);
|
|
1467
|
+
}
|
|
1468
|
+
return { code: o, data: a };
|
|
1469
|
+
}
|
|
1470
|
+
/**
|
|
1471
|
+
* beforeHangup
|
|
1472
|
+
*/
|
|
1473
|
+
clearAllTimer(e, _) {
|
|
1474
|
+
[this._mainSession, ...this._holdSessions].forEach((i) => {
|
|
1475
|
+
i && i.getCallId() === e && i.getAllTimerIds().forEach((n) => this._stopTimer.bind(this)(n, _));
|
|
1476
|
+
});
|
|
1477
|
+
}
|
|
1478
|
+
/**
|
|
1479
|
+
* 挂断
|
|
1480
|
+
* 通话请求取消、通话拒绝
|
|
1481
|
+
*/
|
|
1482
|
+
async hangup(e, _) {
|
|
1483
|
+
return this._signalModule.hangupCall({
|
|
1484
|
+
callId: e.callId,
|
|
1485
|
+
sysStatus: e.systemState
|
|
1486
|
+
}, _);
|
|
1487
|
+
}
|
|
1488
|
+
/**
|
|
1489
|
+
* 接收邀请
|
|
1490
|
+
* 通话中又收到新来电后,接听新来电时,必须先挂断之前的通话(mainSession)
|
|
1491
|
+
*/
|
|
1492
|
+
async accept(e, _) {
|
|
1493
|
+
if (!this._mainSession)
|
|
1494
|
+
return { code: E.NOT_IN_CALL };
|
|
1495
|
+
const { code: i } = await this._signalModule.acceptCall({ callId: e.callId }, _);
|
|
1496
|
+
return this._stopTimer(this._mainSession.getInviteeTimerId(), _), i !== E.SUCCESS ? { code: i } : (this._clearMobileOnPhone(e.callId, _), this._mainSession.updateSessionState(p.CONNECTING), { code: i });
|
|
1497
|
+
}
|
|
1498
|
+
/**
|
|
1499
|
+
* 直接加入
|
|
1500
|
+
*/
|
|
1501
|
+
async joinCall(e, _) {
|
|
1502
|
+
const i = this._context.getCurrentId();
|
|
1503
|
+
this._mainSession && this._stopTimer(this._mainSession.getInviteeTimerId(), _);
|
|
1504
|
+
const { code: n } = await this._signalModule.joinCall({ callId: e.callId }, _);
|
|
1505
|
+
return n !== E.SUCCESS ? { code: n } : (this._abnormalModule.addAbnormallCallId(i, e.callId), this._mainSession ? this._clearMobileOnPhone(e.callId, _) : await this._createSessionByServer(e.callId, !0, _), { code: n });
|
|
1506
|
+
}
|
|
1507
|
+
/**
|
|
1508
|
+
* 通话媒体变更请求
|
|
1509
|
+
*/
|
|
1510
|
+
async requestChangeMediaType(e, _) {
|
|
1511
|
+
if (!this._mainSession)
|
|
1512
|
+
return { code: E.NOT_IN_CALL };
|
|
1513
|
+
const i = {
|
|
1514
|
+
mediaType: e.mediaType
|
|
1515
|
+
};
|
|
1516
|
+
this._mainSession.updateReqMediaType(e.mediaType);
|
|
1517
|
+
const n = Ze(), { code: o } = await this._signalModule.dialogUpCall({
|
|
1518
|
+
transactionId: n,
|
|
1519
|
+
callId: this._mainSession.getCallId(),
|
|
1520
|
+
toUserIds: e.toUserIds,
|
|
1521
|
+
dialogType: q.SWITCH_MEDIA_TYPE,
|
|
1522
|
+
action: b.REQUEST,
|
|
1523
|
+
extraKeyVal: i
|
|
1524
|
+
}, _);
|
|
1525
|
+
return o !== E.SUCCESS ? { code: o } : { code: E.SUCCESS, data: { transactionId: n } };
|
|
1526
|
+
}
|
|
1527
|
+
/**
|
|
1528
|
+
* 通话媒体类型变更请求响应
|
|
1529
|
+
*/
|
|
1530
|
+
async responseChangeMediaType(e, _) {
|
|
1531
|
+
if (!this._mainSession)
|
|
1532
|
+
return { code: E.NOT_IN_CALL };
|
|
1533
|
+
const i = this._mainSession.getReqMediaType();
|
|
1534
|
+
return e.agree && (this._mainSession.updateMediaType(i), this._mainSession.updateReqMediaType(null)), this._signalModule.dialogUpCall({
|
|
1535
|
+
transactionId: e.transactionId,
|
|
1536
|
+
callId: this._mainSession.getCallId(),
|
|
1537
|
+
dialogType: q.SWITCH_MEDIA_TYPE,
|
|
1538
|
+
action: e.agree ? b.ACCEPT : b.REFUSE
|
|
1539
|
+
}, _);
|
|
1540
|
+
}
|
|
1541
|
+
/**
|
|
1542
|
+
* 取消通话媒体类型切换请求
|
|
1543
|
+
*/
|
|
1544
|
+
async cancelChangeMediaType(e, _) {
|
|
1545
|
+
return this._mainSession ? this._signalModule.dialogUpCall({
|
|
1546
|
+
transactionId: e.transactionId,
|
|
1547
|
+
callId: this._mainSession.getCallId(),
|
|
1548
|
+
dialogType: q.SWITCH_MEDIA_TYPE,
|
|
1549
|
+
action: b.CANCEL
|
|
1550
|
+
}, _) : { code: E.NOT_IN_CALL };
|
|
1551
|
+
}
|
|
1552
|
+
/**
|
|
1553
|
+
* 获取 call log 列表
|
|
1554
|
+
*/
|
|
1555
|
+
async getCallLogList(e, _) {
|
|
1556
|
+
const i = this._context.getCurrentId(), { code: n, data: o } = await this._signalModule.syncCallLog({
|
|
1557
|
+
userId: i,
|
|
1558
|
+
syncTime: e.timestamp,
|
|
1559
|
+
count: e.count
|
|
1560
|
+
}, _);
|
|
1561
|
+
if (n !== E.SUCCESS)
|
|
1562
|
+
return { code: n };
|
|
1563
|
+
const a = o.callLogList.map((L) => Ne(L));
|
|
1564
|
+
return {
|
|
1565
|
+
code: E.SUCCESS,
|
|
1566
|
+
data: {
|
|
1567
|
+
hasMore: !!(o != null && o.hasMore),
|
|
1568
|
+
maxTime: o.maxTime,
|
|
1569
|
+
list: a
|
|
1570
|
+
}
|
|
1571
|
+
};
|
|
1572
|
+
}
|
|
1573
|
+
/**
|
|
1574
|
+
* 批量删除通话日志
|
|
1575
|
+
*/
|
|
1576
|
+
async deleteCallLog(e, _) {
|
|
1577
|
+
const i = this._context.getCurrentId();
|
|
1578
|
+
return this._signalModule.deleteCallRecord(i, e, _);
|
|
1579
|
+
}
|
|
1580
|
+
/**
|
|
1581
|
+
* 获取 call server 当前时间戳
|
|
1582
|
+
*/
|
|
1583
|
+
async getCallServerTimestamp(e) {
|
|
1584
|
+
const { code: _, data: i } = await this._signalModule.getCallServerTimestamp(e);
|
|
1585
|
+
return _ !== E.SUCCESS ? { code: _ } : { code: _, data: i.syncTime };
|
|
1586
|
+
}
|
|
1587
|
+
/**
|
|
1588
|
+
* 获取 call 时间信息
|
|
1589
|
+
*/
|
|
1590
|
+
async getCallTimeInfo(e, _) {
|
|
1591
|
+
return this._signalModule.getCallTimeInfo(e, _);
|
|
1592
|
+
}
|
|
1593
|
+
/**
|
|
1594
|
+
* 获取未结束的通话列表
|
|
1595
|
+
*/
|
|
1596
|
+
async getOpenCallList(e) {
|
|
1597
|
+
const _ = this._context.getCurrentId(), { code: i, data: n } = await this._signalModule.getUserCallStateList(e);
|
|
1598
|
+
if (i !== E.SUCCESS)
|
|
1599
|
+
return { code: i };
|
|
1600
|
+
const o = n.callStateList.map((a) => {
|
|
1601
|
+
const {
|
|
1602
|
+
callId: L,
|
|
1603
|
+
callType: c,
|
|
1604
|
+
mediaType: T,
|
|
1605
|
+
callingUserId: S,
|
|
1606
|
+
callUserIds: I,
|
|
1607
|
+
callStatus: d,
|
|
1608
|
+
crtTime: g,
|
|
1609
|
+
userSessionStatus: O,
|
|
1610
|
+
targetType: u,
|
|
1611
|
+
targetId: m,
|
|
1612
|
+
startTime: N,
|
|
1613
|
+
syncTime: U
|
|
1614
|
+
} = a, f = S === _ ? Ce.OUT : Ce.IN, { clientStartTime: B = N } = this._timeCorrectioner.calcClientStartTime(L, N, e);
|
|
1615
|
+
return {
|
|
1616
|
+
callId: L,
|
|
1617
|
+
callType: c,
|
|
1618
|
+
callDirection: f,
|
|
1619
|
+
mediaType: T,
|
|
1620
|
+
callerUserId: S,
|
|
1621
|
+
callUserIds: I,
|
|
1622
|
+
sessionState: d,
|
|
1623
|
+
userState: O,
|
|
1624
|
+
startTimestamp: N,
|
|
1625
|
+
endTimestamp: 0,
|
|
1626
|
+
duration: Math.floor((+/* @__PURE__ */ new Date() - B) / 1e3),
|
|
1627
|
+
syncTimestamp: U,
|
|
1628
|
+
systemState: 0,
|
|
1629
|
+
createTimestamp: g
|
|
1630
|
+
};
|
|
1631
|
+
});
|
|
1632
|
+
return {
|
|
1633
|
+
code: i,
|
|
1634
|
+
data: o
|
|
1635
|
+
};
|
|
1636
|
+
}
|
|
1637
|
+
/**
|
|
1638
|
+
* 清除当前用户的 call log
|
|
1639
|
+
*/
|
|
1640
|
+
async removeAllCallLog(e) {
|
|
1641
|
+
const { code: _ } = await this._signalModule.clearCallRecord(e);
|
|
1642
|
+
return _ !== E.SUCCESS ? { code: _ } : { code: _ };
|
|
1643
|
+
}
|
|
1644
|
+
/**
|
|
1645
|
+
* 通过 callId 获取 session 详细信息
|
|
1646
|
+
*/
|
|
1647
|
+
async getCallSession(e, _) {
|
|
1648
|
+
const { code: i, data: n } = await this._signalModule.getCallSession(e, _);
|
|
1649
|
+
if (i !== E.SUCCESS)
|
|
1650
|
+
return { code: i };
|
|
1651
|
+
const {
|
|
1652
|
+
callId: o,
|
|
1653
|
+
callingUserId: a,
|
|
1654
|
+
callType: L,
|
|
1655
|
+
mediaType: c,
|
|
1656
|
+
callStatus: T,
|
|
1657
|
+
callSessionUsers: S,
|
|
1658
|
+
startTime: I,
|
|
1659
|
+
duration: d,
|
|
1660
|
+
syncTime: g
|
|
1661
|
+
} = n, O = S.map((u) => {
|
|
1662
|
+
const {
|
|
1663
|
+
userId: m,
|
|
1664
|
+
sessionStatus: N,
|
|
1665
|
+
sysStatus: U,
|
|
1666
|
+
targetType: f,
|
|
1667
|
+
targetId: B
|
|
1668
|
+
} = u;
|
|
1669
|
+
return {
|
|
1670
|
+
userId: m,
|
|
1671
|
+
userState: N,
|
|
1672
|
+
systemState: U,
|
|
1673
|
+
targetType: f,
|
|
1674
|
+
targetId: B,
|
|
1675
|
+
cameraEnable: !1,
|
|
1676
|
+
microphoneEnable: !1
|
|
1677
|
+
};
|
|
1678
|
+
});
|
|
1679
|
+
return {
|
|
1680
|
+
code: i,
|
|
1681
|
+
data: {
|
|
1682
|
+
callId: o,
|
|
1683
|
+
startCallerId: a,
|
|
1684
|
+
callType: L,
|
|
1685
|
+
mediaType: c,
|
|
1686
|
+
sessionState: T,
|
|
1687
|
+
callSessionUsers: O,
|
|
1688
|
+
startTime: I,
|
|
1689
|
+
duration: d,
|
|
1690
|
+
syncTime: g
|
|
1691
|
+
}
|
|
1692
|
+
};
|
|
1693
|
+
}
|
|
1694
|
+
getHoldSession(e) {
|
|
1695
|
+
const _ = this._holdSessions.find((i) => i && i.getCallId() === e);
|
|
1696
|
+
return _ ? new ie(_, this, this._logger) : null;
|
|
1697
|
+
}
|
|
1698
|
+
/**
|
|
1699
|
+
* 获取当前主 session
|
|
1700
|
+
*/
|
|
1701
|
+
getLocalMainSession() {
|
|
1702
|
+
return this._mainSession ? new ie(this._mainSession, this, this._logger) : null;
|
|
1703
|
+
}
|
|
1704
|
+
/**
|
|
1705
|
+
* 设置主 session 状态
|
|
1706
|
+
*/
|
|
1707
|
+
updateMainSessionState(e) {
|
|
1708
|
+
var _;
|
|
1709
|
+
(_ = this._mainSession) == null || _.updateSessionState(e);
|
|
1710
|
+
}
|
|
1711
|
+
/**
|
|
1712
|
+
* 记录是否是本端挂断
|
|
1713
|
+
*/
|
|
1714
|
+
setIsLocalClientHangup(e) {
|
|
1715
|
+
var _;
|
|
1716
|
+
(_ = this._mainSession) == null || _.setIsLocalClientHangup(e);
|
|
1717
|
+
}
|
|
1718
|
+
/**
|
|
1719
|
+
* 通知人员状态
|
|
1720
|
+
* CallClient 也需要更新人员状态,定义为公共函数
|
|
1721
|
+
*/
|
|
1722
|
+
updateUsersState(e, _, i) {
|
|
1723
|
+
this._logger.info(r.L_CALL_ENGINE_UPDATE_USERS_STATE_O, `updateUsersState -> users: ${JSON.stringify(_)}`, i);
|
|
1724
|
+
const n = [this._mainSession, ...this._holdSessions].find((a) => (a == null ? void 0 : a.getCallId()) === e), o = [];
|
|
1725
|
+
if (n) {
|
|
1726
|
+
const a = _.map((L) => {
|
|
1727
|
+
const c = n.getUserList().filter(({ userId: d }) => d === L.userId)[0] || {}, T = L.userState === C.IDLE, { cameraEnable: S = !1, microphoneEnable: I = !1 } = T ? { cameraEnable: !1, microphoneEnable: !1 } : c;
|
|
1728
|
+
return {
|
|
1729
|
+
...L,
|
|
1730
|
+
cameraEnable: S,
|
|
1731
|
+
microphoneEnable: I
|
|
1732
|
+
};
|
|
1733
|
+
});
|
|
1734
|
+
o.push(...n.updateUserList(a, i));
|
|
1735
|
+
} else
|
|
1736
|
+
o.push(..._);
|
|
1737
|
+
o.length > 0 && this._onUserStateChange(e, o, i);
|
|
1738
|
+
}
|
|
1739
|
+
setUserDeviceEnable(e, _, i, n) {
|
|
1740
|
+
var o;
|
|
1741
|
+
(o = this._mainSession) == null || o.setUserDeviceEnable(e, _, i, n);
|
|
1742
|
+
}
|
|
1743
|
+
/**
|
|
1744
|
+
* 获取通话开始时间
|
|
1745
|
+
*/
|
|
1746
|
+
async getCallStaringTime(e, _) {
|
|
1747
|
+
return this._timeCorrectioner.getCallClientTimeByServer(e.callId, _);
|
|
1748
|
+
}
|
|
1749
|
+
/**
|
|
1750
|
+
* 人员系统状态上报
|
|
1751
|
+
*/
|
|
1752
|
+
async systemStatusUp(e, _) {
|
|
1753
|
+
return this._signalModule.sysStatusUp(e, _);
|
|
1754
|
+
}
|
|
1755
|
+
/**
|
|
1756
|
+
* 单呼中收到远端流后,给 CallServer 上报,用于处理计时逻辑
|
|
1757
|
+
*/
|
|
1758
|
+
async upFirstFrameTime(e) {
|
|
1759
|
+
if (!this._mainSession || this._mainSession && this._mainSession.getCallType() !== M.SINGLE || this._isUpFirstFrameTime)
|
|
1760
|
+
return { code: E.SUCCESS };
|
|
1761
|
+
const i = Date.now(), n = this._timeCorrectioner.getLocalDelayTime(), o = Math.floor(i + n);
|
|
1762
|
+
this._logger.info(r.L_CALL_ENGINE_UP_FIRST_FRAME_TIME_T, `now: ${i}; delay: ${n}; streamReadyTime: ${o}`, e), this._isUpFirstFrameTime = !0;
|
|
1763
|
+
const a = this._mainSession.getCallId(), { code: L } = await this._signalModule.eventUpCall({
|
|
1764
|
+
callId: a,
|
|
1765
|
+
eventType: le.FIRST_FRAME,
|
|
1766
|
+
eventArgs: { streamReadyTime: o },
|
|
1767
|
+
eventTime: Date.now()
|
|
1768
|
+
}, e);
|
|
1769
|
+
return this._logger.info(r.L_CALL_ENGINE_UP_FIRST_FRAME_TIME_R, `code: ${L}`, e), { code: L };
|
|
1770
|
+
}
|
|
1771
|
+
/**
|
|
1772
|
+
* 上层模拟 statusDownCall, 结束 session
|
|
1773
|
+
* 通话建立后,只能结束 mainSession
|
|
1774
|
+
*/
|
|
1775
|
+
endCurrentSession(e, _, i) {
|
|
1776
|
+
const n = this._context.getCurrentId();
|
|
1777
|
+
if (this._mainSession && this._mainSession.getCallId() === _) {
|
|
1778
|
+
const o = this._mainSession.getUserList().map((L) => {
|
|
1779
|
+
let {
|
|
1780
|
+
userId: c,
|
|
1781
|
+
userState: T,
|
|
1782
|
+
systemState: S,
|
|
1783
|
+
targetType: I,
|
|
1784
|
+
targetId: d
|
|
1785
|
+
} = L;
|
|
1786
|
+
return c === n && (S = e), {
|
|
1787
|
+
userId: c,
|
|
1788
|
+
sessionStatus: C.ENDED,
|
|
1789
|
+
statusTime: Date.now(),
|
|
1790
|
+
duration: 0,
|
|
1791
|
+
changed: 1,
|
|
1792
|
+
inviteUserId: this._mainSession.getStartCallerId(),
|
|
1793
|
+
sysStatus: S,
|
|
1794
|
+
targetType: I,
|
|
1795
|
+
targetId: d
|
|
1796
|
+
};
|
|
1797
|
+
}), a = {
|
|
1798
|
+
callId: this._mainSession.getCallId(),
|
|
1799
|
+
toDeviceId: this._signalModule.getSessionId(),
|
|
1800
|
+
callStatus: p.ENDED,
|
|
1801
|
+
duration: 0,
|
|
1802
|
+
callSessionUsers: o
|
|
1803
|
+
};
|
|
1804
|
+
this._onStatusDown(a, i);
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
/**
|
|
1808
|
+
* 上层 RTC 加入房间后重新开始校时
|
|
1809
|
+
*/
|
|
1810
|
+
startTimeCorrection(e) {
|
|
1811
|
+
this._timeCorrectioner.restart(e);
|
|
1812
|
+
}
|
|
1813
|
+
getDelayTimeInfo() {
|
|
1814
|
+
return {
|
|
1815
|
+
delayTime: this._timeCorrectioner.getLocalDelayTime(),
|
|
1816
|
+
rtt: this._timeCorrectioner.getRTT()
|
|
1817
|
+
};
|
|
1818
|
+
}
|
|
1819
|
+
/**
|
|
1820
|
+
* holdSession 升级为 mainSession
|
|
1821
|
+
*/
|
|
1822
|
+
upgradeMainSession(e) {
|
|
1823
|
+
var i;
|
|
1824
|
+
const _ = this._holdSessions.findIndex((n) => n.getCallId() === e);
|
|
1825
|
+
this._mainSession = (i = this._holdSessions.splice(_, 1)) == null ? void 0 : i[0];
|
|
1826
|
+
}
|
|
1827
|
+
/** ======私有方法============================================================================================= */
|
|
1828
|
+
/**
|
|
1829
|
+
* IM 状态变更处理
|
|
1830
|
+
*/
|
|
1831
|
+
_onIMStateChange(e) {
|
|
1832
|
+
const _ = this._logger.createTraceId();
|
|
1833
|
+
let i = 0;
|
|
1834
|
+
e === W.DISCONNECTED && this._mainSession && this._mainSession.getSessionState() !== p.ONCALL && (i = Se(() => {
|
|
1835
|
+
var n;
|
|
1836
|
+
this._logger.info(r.L_CALL_ENGINE_IM_STATE_CHANGE_O, "endCurrentSession, IM disconnected for more than 60s", _), this.endCurrentSession(h.CONNECTION_ERR, (n = this._mainSession) == null ? void 0 : n.getCallId(), _);
|
|
1837
|
+
}, Re)), e === W.CONNECTED && i && clearTimeout(i);
|
|
1838
|
+
}
|
|
1839
|
+
/**
|
|
1840
|
+
* 处理发起邀请、收到邀请后计时超时
|
|
1841
|
+
* 提前模拟 _onStatusDown, 不再依赖 CallServer 下发的 _onStatusDown
|
|
1842
|
+
* 处理网络异常情况下上报 CallServer 失败,CallServer 不会下发 _onStatusDown 情况
|
|
1843
|
+
*/
|
|
1844
|
+
_handleCallTimeout(e, _, i) {
|
|
1845
|
+
this._logger.warn(r.L_CALL_ENGINE_CALL_TIMEOUT_O, `call timeout callId: ${e}, userState: ${_}`, i);
|
|
1846
|
+
const n = [this._mainSession, ...this._holdSessions].find((a) => a && a.getCallId() === e);
|
|
1847
|
+
if (!n) {
|
|
1848
|
+
this._logger.warn(r.L_CALL_ENGINE_CALL_TIMEOUT_O, `handleCallTimeout without session, callId: ${e}`, i);
|
|
1849
|
+
return;
|
|
1850
|
+
}
|
|
1851
|
+
const o = this._context.getCurrentId();
|
|
1852
|
+
this._onStatusDown({
|
|
1853
|
+
callId: e,
|
|
1854
|
+
toDeviceId: this._signalModule.getSessionId(),
|
|
1855
|
+
callStatus: p.ENDED,
|
|
1856
|
+
duration: 0,
|
|
1857
|
+
callSessionUsers: n.getUserList().map((a) => {
|
|
1858
|
+
const {
|
|
1859
|
+
userId: L,
|
|
1860
|
+
targetType: c,
|
|
1861
|
+
targetId: T,
|
|
1862
|
+
stateTime: S
|
|
1863
|
+
} = a;
|
|
1864
|
+
let I, d;
|
|
1865
|
+
return L === o ? (I = _ === C.MISSED ? h.MISSED : h.NO_ANSWER, d = _ === C.MISSED ? C.MISSED : C.NO_ANSWER) : (I = _ === C.MISSED ? h.NO_ANSWER : h.MISSED, d = _ === C.MISSED ? C.NO_ANSWER : C.MISSED), {
|
|
1866
|
+
userId: L,
|
|
1867
|
+
sessionStatus: d,
|
|
1868
|
+
statusTime: S ? S + 1 : Date.now(),
|
|
1869
|
+
duration: 0,
|
|
1870
|
+
changed: 1,
|
|
1871
|
+
inviteUserId: n.getCallerId(),
|
|
1872
|
+
sysStatus: I,
|
|
1873
|
+
targetType: c,
|
|
1874
|
+
targetId: T
|
|
1875
|
+
};
|
|
1876
|
+
})
|
|
1877
|
+
}, i);
|
|
1878
|
+
}
|
|
1879
|
+
/**
|
|
1880
|
+
* 开启超时计时器
|
|
1881
|
+
*/
|
|
1882
|
+
_startTimer(e, _, i) {
|
|
1883
|
+
const n = Se(() => {
|
|
1884
|
+
this._handleCallTimeout(e, _, i), this._signalModule.statusUpCall({ callId: e, sessionStatus: _ }, i);
|
|
1885
|
+
}, Re);
|
|
1886
|
+
return this._logger.info(r.L_CALL_ENGINE_START_CALL_TIMER_O, `callId: ${e}, timerId: ${n}`, i), n;
|
|
1887
|
+
}
|
|
1888
|
+
/**
|
|
1889
|
+
* 停止超时计时器
|
|
1890
|
+
*/
|
|
1891
|
+
_stopTimer(e, _) {
|
|
1892
|
+
clearTimeout(e), this._logger.info(r.L_CALL_ENGINE_STOP_CALL_TIMER_O, `timerId: ${e}`, _);
|
|
1893
|
+
}
|
|
1894
|
+
/**
|
|
1895
|
+
* 收到 通话邀请
|
|
1896
|
+
*/
|
|
1897
|
+
_onInvite(e, _, i) {
|
|
1898
|
+
var O, u, m;
|
|
1899
|
+
const n = this._context.getCurrentId(), {
|
|
1900
|
+
callId: o,
|
|
1901
|
+
inviteUserId: a,
|
|
1902
|
+
callType: L,
|
|
1903
|
+
mediaType: c,
|
|
1904
|
+
callSessionUsers: T,
|
|
1905
|
+
secretChat: S,
|
|
1906
|
+
callingUserId: I
|
|
1907
|
+
} = e;
|
|
1908
|
+
if (S === ce.SECRET) {
|
|
1909
|
+
this.emit(x.onPubInviteCallMiss, Object.assign(e, {
|
|
1910
|
+
extra: JSON.stringify(e),
|
|
1911
|
+
reason: re.SECRET_CALL,
|
|
1912
|
+
refer: _ ? J.PUB_INVITE : J.PULL_KV_INVITE
|
|
1913
|
+
}));
|
|
1914
|
+
return;
|
|
1915
|
+
}
|
|
1916
|
+
if (T.some((N) => N.userId === n)) {
|
|
1917
|
+
this._abnormalModule.addAbnormallCallId(n, o);
|
|
1918
|
+
const N = new Le(
|
|
1919
|
+
o,
|
|
1920
|
+
p.RINGING,
|
|
1921
|
+
L,
|
|
1922
|
+
c,
|
|
1923
|
+
a,
|
|
1924
|
+
a,
|
|
1925
|
+
[],
|
|
1926
|
+
this._logger
|
|
1927
|
+
);
|
|
1928
|
+
this._signalModule.ringingCall({ callId: o }, i);
|
|
1929
|
+
const U = this._startTimer(o, C.MISSED, i);
|
|
1930
|
+
N.updateTimerId(Te.INVITEE, U), this._mainSession ? (this._holdSessions.push(N), this._mainSession.updateSessionState(p.BUSYLINE_WAIT)) : this._mainSession = N;
|
|
1931
|
+
const f = new ie(N, this, this._logger);
|
|
1932
|
+
this._reportAppEventModule.onReceivedCall(f, i);
|
|
1933
|
+
const B = _ ? Ie.PUB_INVITE_CALL : Ie.PULL_KV_INVITE_CALL;
|
|
1934
|
+
this.emit(w.__INNER_INVITE__, f, B);
|
|
1935
|
+
const te = T.map(({
|
|
1936
|
+
userId: Ee,
|
|
1937
|
+
sessionStatus: Ue,
|
|
1938
|
+
sysStatus: me,
|
|
1939
|
+
targetType: pe,
|
|
1940
|
+
targetId: fe,
|
|
1941
|
+
statusTime: Me
|
|
1942
|
+
}) => ({
|
|
1943
|
+
userId: Ee,
|
|
1944
|
+
userState: Ue,
|
|
1945
|
+
systemState: me,
|
|
1946
|
+
targetType: pe,
|
|
1947
|
+
targetId: fe,
|
|
1948
|
+
stateTime: Me,
|
|
1949
|
+
cameraEnable: !1,
|
|
1950
|
+
microphoneEnable: !1
|
|
1951
|
+
}));
|
|
1952
|
+
this.updateUsersState(o, te, i);
|
|
1953
|
+
} else
|
|
1954
|
+
this.emit(x.onPubInviteCallMiss, Object.assign(e, {
|
|
1955
|
+
extra: JSON.stringify(e),
|
|
1956
|
+
reason: re.NOT_INVITEE,
|
|
1957
|
+
refer: _ ? J.PUB_INVITE : J.PULL_KV_INVITE
|
|
1958
|
+
}));
|
|
1959
|
+
const g = T.filter((N) => N.userId !== n && N.userId !== a && N.sessionStatus === C.INVITED);
|
|
1960
|
+
if (g.length > 0) {
|
|
1961
|
+
((O = this._mainSession) == null ? void 0 : O.getCallType()) === M.SINGLE && ((u = this._mainSession) == null ? void 0 : u.getCallId()) === o && (this._onCallTypeChange(this._mainSession.getCallId(), M.MULTI, i), (m = this._mainSession) == null || m.updateCallType(M.MULTI));
|
|
1962
|
+
const N = [], U = [];
|
|
1963
|
+
g.forEach((f) => {
|
|
1964
|
+
const { userId: B, sessionStatus: te, sysStatus: Ee } = f;
|
|
1965
|
+
N.push({ callId: o, userId: B, userState: te }), U.push({
|
|
1966
|
+
userId: B,
|
|
1967
|
+
userState: te,
|
|
1968
|
+
systemState: Ee,
|
|
1969
|
+
cameraEnable: !1,
|
|
1970
|
+
microphoneEnable: !1
|
|
1971
|
+
});
|
|
1972
|
+
}), this._onOtherMemberInvite(N), this.updateUsersState(o, U, i);
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
/**
|
|
1976
|
+
* 收到 挂断(对方通话取消、通话拒绝)
|
|
1977
|
+
*/
|
|
1978
|
+
_onHangup(e, _, i) {
|
|
1979
|
+
this._mainSession && e.forEach((n) => {
|
|
1980
|
+
n.callId === this._mainSession.getCallId() && (n.userState === C.CANCELLED ? this._stopTimer(this._mainSession.getInviteeTimerId(), i) : this._stopTimer(this._mainSession.getInviterTimerId(), i));
|
|
1981
|
+
});
|
|
1982
|
+
}
|
|
1983
|
+
/**
|
|
1984
|
+
* 收到 接听
|
|
1985
|
+
*/
|
|
1986
|
+
_onAccept(e, _) {
|
|
1987
|
+
var L, c, T, S;
|
|
1988
|
+
const i = (L = this._mainSession) == null ? void 0 : L.getSessionState(), n = [
|
|
1989
|
+
p.CONNECTING,
|
|
1990
|
+
p.ONCALL,
|
|
1991
|
+
p.BUSYLINE_WAIT
|
|
1992
|
+
];
|
|
1993
|
+
if (((c = this._mainSession) == null ? void 0 : c.getCallType()) === M.SINGLE && i && n.includes(i))
|
|
1994
|
+
return;
|
|
1995
|
+
const o = this._mainSession.getStartCallerId(), a = this._context.getCurrentId();
|
|
1996
|
+
((T = this._mainSession) == null ? void 0 : T.getCallType()) === M.SINGLE && o === a && e.filter((d) => d.fromUserId !== a) && this.emit(w.__INNER_SESSION_CONNECT__, this.getLocalMainSession().getCallId(), _), (S = this._mainSession) == null || S.updateSessionState(p.CONNECTING), this._stopTimer(this._mainSession.getInviterTimerId(), _);
|
|
1997
|
+
}
|
|
1998
|
+
/**
|
|
1999
|
+
* 收到状态下发
|
|
2000
|
+
*/
|
|
2001
|
+
async _onStatusDown(e, _) {
|
|
2002
|
+
var g, O;
|
|
2003
|
+
const {
|
|
2004
|
+
callStatus: i,
|
|
2005
|
+
startTime: n,
|
|
2006
|
+
syncTime: o,
|
|
2007
|
+
callId: a
|
|
2008
|
+
} = e;
|
|
2009
|
+
if (a !== ((g = this._mainSession) == null ? void 0 : g.getCallId()))
|
|
2010
|
+
return;
|
|
2011
|
+
if (this._callStartMap[a] = this._callStartMap[a] || {}, !this._callStartMap[a].isReceiveCallStartTime && i === p.ONCALL) {
|
|
2012
|
+
this._callStartMap[a].isReceiveCallStartTime = !0;
|
|
2013
|
+
const { code: u, clientStartTime: m } = await this._timeCorrectioner.calcClientStartTime(a, n, _);
|
|
2014
|
+
u === P.SUCCESS && this._reportAppEventModule.onReceivedCallStartTime({
|
|
2015
|
+
callId: a,
|
|
2016
|
+
callStartTime: m
|
|
2017
|
+
}, _);
|
|
2018
|
+
}
|
|
2019
|
+
let L = !1;
|
|
2020
|
+
const c = this._context.getCurrentId(), T = e.callSessionUsers.map((u) => ([
|
|
2021
|
+
C.IDLE,
|
|
2022
|
+
C.DECLINED,
|
|
2023
|
+
C.MISSED,
|
|
2024
|
+
C.NO_ANSWER,
|
|
2025
|
+
C.CANCELLED
|
|
2026
|
+
].includes(u.sessionStatus) && u.userId === c && (L = !0), {
|
|
2027
|
+
userId: u.userId,
|
|
2028
|
+
userState: u.sessionStatus,
|
|
2029
|
+
systemState: u.sysStatus,
|
|
2030
|
+
stateTime: u.statusTime,
|
|
2031
|
+
cameraEnable: !1,
|
|
2032
|
+
microphoneEnable: !1
|
|
2033
|
+
}));
|
|
2034
|
+
if (T.length > 0 && this.updateUsersState(a, T, _), !this._mainSession && !this._holdSessions.length)
|
|
2035
|
+
return;
|
|
2036
|
+
const {
|
|
2037
|
+
hangupData: S,
|
|
2038
|
+
acceptData: I,
|
|
2039
|
+
otherInvitedData: d
|
|
2040
|
+
} = xe(e);
|
|
2041
|
+
S.length > 0 && this._onHangup(S, e.callStatus, _), I.length > 0 && this._onAccept(I, _), d.length > 0 && ((O = this._mainSession) == null ? void 0 : O.getCallType()) === M.MULTI && this._onOtherMemberInvite(d), (e.callStatus === p.ENDED || L) && this.sessionClose(e, _, !0);
|
|
2042
|
+
}
|
|
2043
|
+
/**
|
|
2044
|
+
* 收到其他端的状态下发
|
|
2045
|
+
*/
|
|
2046
|
+
_onOtherClientStatusDown(e, _) {
|
|
2047
|
+
var c, T, S;
|
|
2048
|
+
const i = this._context.getCurrentId(), { callId: n, callSessionUsers: o, callStatus: a } = e, L = o.find(({ userId: I }) => I === i);
|
|
2049
|
+
if (L && (this._mainSession || this._holdSessions.length)) {
|
|
2050
|
+
const { userId: I, sessionStatus: d, statusTime: g } = L;
|
|
2051
|
+
if (d === C.CONNECTING) {
|
|
2052
|
+
const O = [C.ONCALL, C.CONNECTING], u = ((c = this._mainSession) == null ? void 0 : c.getCallId()) === n, m = (S = (T = this._mainSession) == null ? void 0 : T.getUserList().find((U) => U.userId === i)) == null ? void 0 : S.userState;
|
|
2053
|
+
u && m && O.includes(m) || (this.updateUsersState(n, [{
|
|
2054
|
+
userId: I,
|
|
2055
|
+
userState: d,
|
|
2056
|
+
systemState: h.OTHER_CLIENT_ACCEPT,
|
|
2057
|
+
stateTime: g,
|
|
2058
|
+
cameraEnable: !1,
|
|
2059
|
+
microphoneEnable: !1
|
|
2060
|
+
}], _), this.sessionClose(e, _, !1));
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
/**
|
|
2065
|
+
* 收到事件下发
|
|
2066
|
+
*/
|
|
2067
|
+
async _onEventDown(e, _) {
|
|
2068
|
+
var c;
|
|
2069
|
+
const {
|
|
2070
|
+
callId: i,
|
|
2071
|
+
eventTime: n,
|
|
2072
|
+
eventArgs: o,
|
|
2073
|
+
eventType: a,
|
|
2074
|
+
fromUserId: L
|
|
2075
|
+
} = e;
|
|
2076
|
+
if (a === le.CALL_DURATION && i === ((c = this._mainSession) == null ? void 0 : c.getCallId())) {
|
|
2077
|
+
const { firstFrameTime: T } = o, { code: S, clientStartTime: I } = await this._timeCorrectioner.calcClientStartTime(i, T, _);
|
|
2078
|
+
this._logger.info(r.L_CALL_ENGINE_RECEIVE_FIRST_FRAME_TIME_O, `clientFirstFrameTime: ${I}`, _), S === P.SUCCESS && this._reportAppEventModule.onReceivedCallFirstFrameTime(i, I, _);
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
/**
|
|
2082
|
+
* 通知单呼 duration 变更
|
|
2083
|
+
*/
|
|
2084
|
+
_onRecvSinCallDuration(e, _, i, n) {
|
|
2085
|
+
var o;
|
|
2086
|
+
((o = this._mainSession) == null ? void 0 : o.getCallId()) === e && (this._reportAppEventModule.onReceivedCallStartTime({ callId: e, callStartTime: _ }, n), this._reportAppEventModule.onReceivedCallFirstFrameTime(e, i, n));
|
|
2087
|
+
}
|
|
2088
|
+
/**
|
|
2089
|
+
* 收到媒体变更相关事件
|
|
2090
|
+
*/
|
|
2091
|
+
_onSwitchMediaType(e, _) {
|
|
2092
|
+
var O, u, m, N, U;
|
|
2093
|
+
const {
|
|
2094
|
+
callId: i,
|
|
2095
|
+
action: n,
|
|
2096
|
+
extraKeyVal: o,
|
|
2097
|
+
transactionId: a,
|
|
2098
|
+
promoterId: L
|
|
2099
|
+
} = e, { mediaType: c, reason: T } = o, S = (O = this._mainSession) == null ? void 0 : O.getCallId();
|
|
2100
|
+
if (i !== S) {
|
|
2101
|
+
this._logger.info(r.L_CALL_ENGINE_RECEIVE_MEDIATYPE_CHANGE_O, `not current session callId: ${S}, recvCallId: ${i}`, _);
|
|
2102
|
+
return;
|
|
2103
|
+
}
|
|
2104
|
+
const { transactionId: I, action: d, mediaType: g } = ((u = this._mainSession) == null ? void 0 : u.getOldDialogData()) || {};
|
|
2105
|
+
if (I === a && d === n && g === c) {
|
|
2106
|
+
this._logger.info(r.L_CALL_ENGINE_RECEIVE_MEDIATYPE_CHANGE_O, "duplicate dialog data", _);
|
|
2107
|
+
return;
|
|
2108
|
+
}
|
|
2109
|
+
if (this._logger.info(r.L_CALL_ENGINE_RECEIVE_MEDIATYPE_CHANGE_O, `action: ${n}, reason: ${T}`, _), (m = this._mainSession) == null || m.setOldDialogData({ transactionId: a, action: n, mediaType: c }), n === b.REQUEST)
|
|
2110
|
+
this._onRequestChangeMediaType({
|
|
2111
|
+
transactionId: a,
|
|
2112
|
+
userId: L,
|
|
2113
|
+
mediaType: c
|
|
2114
|
+
}, _);
|
|
2115
|
+
else {
|
|
2116
|
+
let f = null;
|
|
2117
|
+
switch (T) {
|
|
2118
|
+
case b.CANCEL:
|
|
2119
|
+
f = F.CANCEL_CHANGE_MEDIA_TYPE;
|
|
2120
|
+
break;
|
|
2121
|
+
case b.ACCEPT:
|
|
2122
|
+
f = F.SERVER_ALLOW_MEDIA_TYPE, (N = this._mainSession) == null || N.updateMediaType(this._mainSession.getReqMediaType()), (U = this._mainSession) == null || U.updateReqMediaType(null);
|
|
2123
|
+
break;
|
|
2124
|
+
case b.REFUSE:
|
|
2125
|
+
f = F.REFUSE_CHANGE_MEDIA_TYPE;
|
|
2126
|
+
break;
|
|
2127
|
+
case b.TIMEOUT:
|
|
2128
|
+
f = F.CHANGE_MEDIA_TYPE_TIMEOUT;
|
|
2129
|
+
break;
|
|
2130
|
+
}
|
|
2131
|
+
F[f] && this._receiveMediaTypeChangeResult({
|
|
2132
|
+
transactionId: a,
|
|
2133
|
+
userId: L,
|
|
2134
|
+
mediaType: c
|
|
2135
|
+
}, f, _);
|
|
2136
|
+
}
|
|
2137
|
+
n === b.NOTICE && c === R.AUDIO && !T && this._receiveMediaTypeChangeResult({
|
|
2138
|
+
transactionId: a,
|
|
2139
|
+
userId: L,
|
|
2140
|
+
mediaType: c
|
|
2141
|
+
}, F.SERVER_ALLOW_MEDIA_TYPE, _);
|
|
2142
|
+
}
|
|
2143
|
+
/**
|
|
2144
|
+
* 收到 call log 日志
|
|
2145
|
+
*/
|
|
2146
|
+
_onRecvCallEndLog(e, _) {
|
|
2147
|
+
const i = Ne(e);
|
|
2148
|
+
this._reportAppEventModule.onReceivedCallRecord(i, _);
|
|
2149
|
+
}
|
|
2150
|
+
/**
|
|
2151
|
+
* 通话结束
|
|
2152
|
+
*/
|
|
2153
|
+
sessionClose(e, _, i) {
|
|
2154
|
+
const { callId: n } = e, o = this._context.getCurrentId();
|
|
2155
|
+
this._abnormalModule.removeAbnormalCallIds(o, [n]);
|
|
2156
|
+
let a = [this._mainSession, ...this._holdSessions].find((T) => T && T.getCallId() === n);
|
|
2157
|
+
if (!a) {
|
|
2158
|
+
this._logger.warn(r.L_CALL_ENGINE_RECEIVE_CLOSE_SESSION_O, `unexpect session callId -> ${n}`, _);
|
|
2159
|
+
return;
|
|
2160
|
+
}
|
|
2161
|
+
this._logger.warn(r.L_CALL_ENGINE_RECEIVE_CLOSE_SESSION_O, `callId: ${n}`, _), this._mainSession && this._mainSession.getCallId() === n && (this._mainSession.getAllTimerIds().forEach((T) => this._stopTimer.bind(this)(T, _)), a.getCallType() === M.SINGLE && (this._isUpFirstFrameTime = !1), delete this._callStartMap[n]), this.emit(w.__INNER_SESSION_CLOSE__, n, _);
|
|
2162
|
+
const L = a.getUserList().find((T) => T.userId === o);
|
|
2163
|
+
let c;
|
|
2164
|
+
i && e.toDeviceId !== this._signalModule.getSessionId() && (c = a.getIsLocalClientHangup() ? L.systemState : h.OTHER_CLIENT_HANGUP), this._reportAppEventModule.onCallEnded(new ie(a, this, this._logger), c || L.systemState, _), this._removeSession(n);
|
|
2165
|
+
}
|
|
2166
|
+
/**
|
|
2167
|
+
* 根据 callId 移除 session
|
|
2168
|
+
*/
|
|
2169
|
+
_removeSession(e) {
|
|
2170
|
+
var _;
|
|
2171
|
+
if (e === ((_ = this._mainSession) == null ? void 0 : _.getCallId()))
|
|
2172
|
+
this._mainSession = null;
|
|
2173
|
+
else {
|
|
2174
|
+
const i = this._holdSessions.findIndex((n) => (n == null ? void 0 : n.getCallId()) === e);
|
|
2175
|
+
this._holdSessions.splice(i, 1);
|
|
2176
|
+
}
|
|
2177
|
+
}
|
|
2178
|
+
/**
|
|
2179
|
+
* 不存在 mainSession 时,从服务端获取数据生成 mainSession, 并通知人员状态变更
|
|
2180
|
+
*/
|
|
2181
|
+
async _createSessionByServer(e, _ = !1, i) {
|
|
2182
|
+
this._logger.info(r.L_CALL_ENGINE_CREATE_SESSION_BY_SERVER_T, `callId: ${e}`, i);
|
|
2183
|
+
const { code: n, data: o } = await this.getCallSession({ callId: e }, i);
|
|
2184
|
+
if (n !== E.SUCCESS) {
|
|
2185
|
+
this._logger.error(r.L_CALL_ENGINE_CREATE_SESSION_BY_SERVER_R, `errcode: ${n}`, i);
|
|
2186
|
+
return;
|
|
2187
|
+
}
|
|
2188
|
+
this._logger.info(r.L_CALL_ENGINE_CREATE_SESSION_BY_SERVER_R, `code: ${n}, data: ${JSON.stringify(o)}`, i);
|
|
2189
|
+
const {
|
|
2190
|
+
callType: a,
|
|
2191
|
+
mediaType: L,
|
|
2192
|
+
callSessionUsers: c,
|
|
2193
|
+
startCallerId: T
|
|
2194
|
+
} = o;
|
|
2195
|
+
this._mainSession = new Le(
|
|
2196
|
+
e,
|
|
2197
|
+
p.CONNECTING,
|
|
2198
|
+
a,
|
|
2199
|
+
L,
|
|
2200
|
+
T,
|
|
2201
|
+
T,
|
|
2202
|
+
[],
|
|
2203
|
+
this._logger
|
|
2204
|
+
), _ && this._clearMobileOnPhone(e, i), this.updateUsersState(e, c, i);
|
|
2205
|
+
}
|
|
2206
|
+
/**
|
|
2207
|
+
* 兼容移动端 onPhone 无法消除问题
|
|
2208
|
+
* A1 移动端和 B 正在 call 中,且 onPhone 状态, A1 杀进程后,B 端展示的 onPhone 状态无法消失
|
|
2209
|
+
* A2 多端在接听和直接加入 call 时,上报 onPhoneEnd 状态,消除 B 端展示的 onPhone 状态
|
|
2210
|
+
*/
|
|
2211
|
+
async _clearMobileOnPhone(e, _) {
|
|
2212
|
+
const i = [this._mainSession, ...this._holdSessions].find((n) => (n == null ? void 0 : n.getCallId()) === e);
|
|
2213
|
+
if (i && i.getCallType() === M.MULTI) {
|
|
2214
|
+
this._logger.info(r.L_CALL_ENGINE_UP_ON_PHONE_END_T, `callId: ${e}`, _);
|
|
2215
|
+
const { code: n } = await this.systemStatusUp({
|
|
2216
|
+
callId: e,
|
|
2217
|
+
sysStatus: h.ON_PHONE_END,
|
|
2218
|
+
forward: Z.CURRENT
|
|
2219
|
+
}, _);
|
|
2220
|
+
n === E.SUCCESS ? this._logger.info(r.L_CALL_ENGINE_UP_ON_PHONE_END_R, `callId: ${e}`, _) : this._logger.warn(r.L_CALL_ENGINE_UP_ON_PHONE_END_R, `callId: ${e}, errCode: ${n}`, _);
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2223
|
+
// 原 client 中定义的事件
|
|
2224
|
+
_onUserStateChange(e, _, i) {
|
|
2225
|
+
const n = this._context.getCurrentId();
|
|
2226
|
+
_.forEach((o) => {
|
|
2227
|
+
const { userId: a, userState: L, systemState: c } = o;
|
|
2228
|
+
a !== n && this._reportAppEventModule.onRemoteUserStateChanged({
|
|
2229
|
+
callId: e,
|
|
2230
|
+
userId: a,
|
|
2231
|
+
userState: L,
|
|
2232
|
+
reason: c
|
|
2233
|
+
}, i);
|
|
2234
|
+
}), _.forEach(({ userId: o, systemState: a }) => {
|
|
2235
|
+
o === n && a === h.ABNORMAL_END && this.emit(w.__INNER_SESSION_CLOSE__, e, i);
|
|
2236
|
+
});
|
|
2237
|
+
}
|
|
2238
|
+
_onOtherMemberInvite(e) {
|
|
2239
|
+
e.forEach((_) => {
|
|
2240
|
+
var a;
|
|
2241
|
+
const { userId: i, callId: n } = _, o = (a = this.getLocalMainSession()) == null ? void 0 : a.getInviterUserId();
|
|
2242
|
+
this._reportAppEventModule.onRemoteUserInvited([i], o, n);
|
|
2243
|
+
});
|
|
2244
|
+
}
|
|
2245
|
+
_onRequestChangeMediaType(e, _) {
|
|
2246
|
+
const { userId: i, transactionId: n, mediaType: o } = e;
|
|
2247
|
+
this._reportAppEventModule.onReceivedChangeMediaTypeRequest(i, n, o, _);
|
|
2248
|
+
}
|
|
2249
|
+
_receiveMediaTypeChangeResult(e, _, i) {
|
|
2250
|
+
_ === F.SERVER_ALLOW_MEDIA_TYPE && this.emit(w.__INNER_CHANGE_MEDIA_TYPE__, e.mediaType, i), this._reportAppEventModule.onReceivedChangeMediaTypeResult({
|
|
2251
|
+
...e,
|
|
2252
|
+
code: _
|
|
2253
|
+
}, i);
|
|
2254
|
+
}
|
|
2255
|
+
_onCallTypeChange(e, _, i) {
|
|
2256
|
+
this._reportAppEventModule.onCallTypeChanged(_, e, i);
|
|
2257
|
+
}
|
|
2258
|
+
};
|
|
2259
|
+
l(w, "__INNER_SESSION_CLOSE__", "inner-session-close"), l(w, "__INNER_SESSION_CONNECT__", "inner-session-connect"), l(w, "__INNER_CHANGE_MEDIA_TYPE__", "inner-change-media-type"), l(w, "__INNER_INVITE__", "inner-invite");
|
|
2260
|
+
let Y = w;
|
|
2261
|
+
var ne = /* @__PURE__ */ ((t) => (t.NORMAL = "RongCloudRTC", t.SCREEN = "ScreenShare", t))(ne || {});
|
|
2262
|
+
const V = class V extends oe {
|
|
2263
|
+
constructor(e, _, i, n, o, a) {
|
|
2264
|
+
super();
|
|
2265
|
+
/**
|
|
2266
|
+
* RCRTC 实例
|
|
2267
|
+
*/
|
|
2268
|
+
l(this, "_rtcClient");
|
|
2269
|
+
/**
|
|
2270
|
+
* 己方的音视频 tracks
|
|
2271
|
+
*/
|
|
2272
|
+
l(this, "_localTracks", []);
|
|
2273
|
+
/**
|
|
2274
|
+
* RCRTCRoom 实例
|
|
2275
|
+
*/
|
|
2276
|
+
l(this, "_room", null);
|
|
2277
|
+
l(this, "_callId", "");
|
|
2278
|
+
l(this, "_callMediaType");
|
|
2279
|
+
l(this, "_videoConfig", {
|
|
2280
|
+
resolution: ee.W640_H480,
|
|
2281
|
+
frameRate: _e.FPS_15
|
|
2282
|
+
});
|
|
2283
|
+
l(this, "_audioConfig", {});
|
|
2284
|
+
l(this, "_isPubTiny", !1);
|
|
2285
|
+
/**
|
|
2286
|
+
* 视频配置是否变更
|
|
2287
|
+
*/
|
|
2288
|
+
l(this, "_videoConfigIsChange", !1);
|
|
2289
|
+
/**
|
|
2290
|
+
* 音频配置是否变更
|
|
2291
|
+
*/
|
|
2292
|
+
l(this, "_audioConfigIsChange", !1);
|
|
2293
|
+
/**
|
|
2294
|
+
* 存储设置的人员和视图
|
|
2295
|
+
*/
|
|
2296
|
+
l(this, "_userViewMap", {});
|
|
2297
|
+
l(this, "_callPlusStatusReportListener", null);
|
|
2298
|
+
l(this, "_remoteAudioEnable", !0);
|
|
2299
|
+
this._context = e, this._runtime = _, this._initOpts = i, this._logger = n, this._callEngine = o, this._reportAppEventModule = a, this._rtcClient = i == null ? void 0 : i.rtcClient, this._isPubTiny = i.isPubTiny || !1;
|
|
2300
|
+
}
|
|
2301
|
+
setCallPlusStatusReportListener(e) {
|
|
2302
|
+
this._callPlusStatusReportListener = e;
|
|
2303
|
+
}
|
|
2304
|
+
/**
|
|
2305
|
+
* 取摄像头资源
|
|
2306
|
+
* 内存中有时,返回内存中的视轨
|
|
2307
|
+
*/
|
|
2308
|
+
async getCameraVideoTrack(e) {
|
|
2309
|
+
const _ = this.getLocalVideoTrack(), { code: i, track: n } = _ && !this._videoConfigIsChange ? { track: _, code: E.SUCCESS } : await this._createVideoTrack(e);
|
|
2310
|
+
return this._videoConfigIsChange = !1, i !== E.SUCCESS ? { code: i } : {
|
|
2311
|
+
code: E.SUCCESS,
|
|
2312
|
+
track: n
|
|
2313
|
+
};
|
|
2314
|
+
}
|
|
2315
|
+
/**
|
|
2316
|
+
* 取麦克风资源
|
|
2317
|
+
* 内存中有时,返回内存中的音轨
|
|
2318
|
+
*/
|
|
2319
|
+
async getMicrophoneAudioTrack(e) {
|
|
2320
|
+
const _ = this.getLocalAudioTrack(), { code: i, track: n } = _ && !this._audioConfigIsChange ? { track: _, code: E.SUCCESS } : await this._createAudioTrack(e);
|
|
2321
|
+
return this._audioConfigIsChange = !1, i !== E.SUCCESS ? { code: i } : {
|
|
2322
|
+
code: E.SUCCESS,
|
|
2323
|
+
track: n
|
|
2324
|
+
};
|
|
2325
|
+
}
|
|
2326
|
+
/**
|
|
2327
|
+
* 根据通话类型创建音、视频资源
|
|
2328
|
+
* @param mediaType 音频或音视频
|
|
2329
|
+
*/
|
|
2330
|
+
async createCallMediaTracks(e, _) {
|
|
2331
|
+
this._callMediaType = e;
|
|
2332
|
+
const { code: i } = await this.getMicrophoneAudioTrack(_);
|
|
2333
|
+
if (i !== E.SUCCESS)
|
|
2334
|
+
return { code: i };
|
|
2335
|
+
if (e === R.AUDIO_VIDEO) {
|
|
2336
|
+
const { code: n } = await this.getCameraVideoTrack(_);
|
|
2337
|
+
if (n !== E.SUCCESS)
|
|
2338
|
+
return { code: n };
|
|
2339
|
+
}
|
|
2340
|
+
return { code: E.SUCCESS };
|
|
2341
|
+
}
|
|
2342
|
+
setVideoConfig(e) {
|
|
2343
|
+
this._videoConfigIsChange = !0, this._videoConfig = e;
|
|
2344
|
+
}
|
|
2345
|
+
setAudioConfig(e) {
|
|
2346
|
+
this._audioConfigIsChange = !0, this._audioConfig = e;
|
|
2347
|
+
}
|
|
2348
|
+
destroyAllTracks(e) {
|
|
2349
|
+
this._logger.info(r.L_RTC_MODULE_DESTROY_ALL_TRACKS_O, "", e), this._localTracks.forEach((_) => {
|
|
2350
|
+
_.destroy();
|
|
2351
|
+
}), this._localTracks.length = 0;
|
|
2352
|
+
}
|
|
2353
|
+
setAllRemoteAudioEnable(e, _) {
|
|
2354
|
+
return this._logger.info(r.L_RTC_MODULE_SET_ALL_REMOTE_AUDIO_ENABLE_T, `enable: ${e}`, _), ue(e) ? (this._remoteAudioEnable = e, this._room ? (this._room.getRemoteTracks().filter((n) => n.isAudioTrack()).forEach((n) => {
|
|
2355
|
+
e ? n.unmute() : n.mute();
|
|
2356
|
+
}), this._logger.info(r.L_RTC_MODULE_SET_ALL_REMOTE_AUDIO_ENABLE_R, "success", _), { code: E.SUCCESS }) : { code: E.SUCCESS }) : (this._logger.error(r.L_RTC_MODULE_SET_ALL_REMOTE_AUDIO_ENABLE_R, `param error, enable: type is boolean, value: ${e}`), { code: E.PARAM_ERROR });
|
|
2357
|
+
}
|
|
2358
|
+
async destroyTrack(e) {
|
|
2359
|
+
e.destroy();
|
|
2360
|
+
const _ = this._localTracks.findIndex((i) => i.getTrackId() === e.getTrackId());
|
|
2361
|
+
this._localTracks.splice(_, 1);
|
|
2362
|
+
}
|
|
2363
|
+
/**
|
|
2364
|
+
* session 连接
|
|
2365
|
+
*/
|
|
2366
|
+
async sessionConnected(e, _) {
|
|
2367
|
+
var i;
|
|
2368
|
+
this._logger.info(r.L_RTC_MODULE_SESSION_CONNECT_T, `callId: ${e}`, _);
|
|
2369
|
+
try {
|
|
2370
|
+
if (!this._room) {
|
|
2371
|
+
const { code: n, room: o } = await this.joinRTCRoom(e, _);
|
|
2372
|
+
if (n !== E.SUCCESS) {
|
|
2373
|
+
this._logger.error(r.L_RTC_MODULE_SESSION_CONNECT_R, `errCode -> ${n}`, _);
|
|
2374
|
+
return;
|
|
2375
|
+
}
|
|
2376
|
+
this._callId = e, this._regRTCListeners(), this._room = o;
|
|
2377
|
+
const a = ((i = this._room) == null ? void 0 : i.getRemoteUserIds()) || [];
|
|
2378
|
+
a.length > 0 && this._onOtherMemJoined(a.map((L) => ({ callId: e, userId: L })), _);
|
|
2379
|
+
}
|
|
2380
|
+
} catch (n) {
|
|
2381
|
+
this._logger.error(r.L_RTC_MODULE_SESSION_CONNECT_R, `callId -> ${e}, err msg -> ${n.message}`, _);
|
|
2382
|
+
return;
|
|
2383
|
+
}
|
|
2384
|
+
try {
|
|
2385
|
+
if (this._localTracks.length > 0) {
|
|
2386
|
+
this.emit(x.onBeforePublish);
|
|
2387
|
+
const n = this._isPubTiny ? this._localTracks.map((a) => a.isVideoTrack() ? { track: a, isPubTiny: !0 } : a) : this._localTracks, { code: o } = await this.publish(n, _);
|
|
2388
|
+
this.emit(x.onPublishRes, o);
|
|
2389
|
+
} else
|
|
2390
|
+
this._logger.warn(r.L_RTC_MODULE_SESSION_CONNECT_P, "sessionConnected local tracks is empty", _);
|
|
2391
|
+
} catch (n) {
|
|
2392
|
+
this._logger.error(r.L_RTC_MODULE_SESSION_CONNECT_R, `publish Exception callId -> ${e}, err msg -> ${n.message}`, _);
|
|
2393
|
+
return;
|
|
2394
|
+
}
|
|
2395
|
+
this._logger.info(r.L_RTC_MODULE_SESSION_CONNECT_R, `code: ${E.SUCCESS}`, _);
|
|
2396
|
+
}
|
|
2397
|
+
async sessionClose(e, _) {
|
|
2398
|
+
var n;
|
|
2399
|
+
this._logger.info(r.L_RTC_MODULE_SESSION_CLOSE_T, `callId: ${e}`, _), this.destroyAllTracks(_);
|
|
2400
|
+
const i = (n = this._room) == null ? void 0 : n.getRoomId();
|
|
2401
|
+
if (this._room && e === i) {
|
|
2402
|
+
const { code: o } = await this._rtcClient.leaveRoom(this._room);
|
|
2403
|
+
if (this._releaseStoredData(), o !== D.SUCCESS) {
|
|
2404
|
+
this._logger.error(r.L_RTC_MODULE_SESSION_CLOSE_R, `leaveRoom failed, code: ${o}`, _);
|
|
2405
|
+
return;
|
|
2406
|
+
}
|
|
2407
|
+
this._logger.info(r.L_RTC_MODULE_SESSION_CLOSE_R, "leaveRoom success", _);
|
|
2408
|
+
} else
|
|
2409
|
+
this._logger.warn(r.L_RTC_MODULE_SESSION_CLOSE_R, "leaveRoom throw exception: not in room", _);
|
|
2410
|
+
}
|
|
2411
|
+
/**
|
|
2412
|
+
* 禁用视频 track
|
|
2413
|
+
*/
|
|
2414
|
+
async disableVideoTrack() {
|
|
2415
|
+
const e = this.getLocalVideoTrack();
|
|
2416
|
+
return e ? { code: await e.mute(), track: e } : { code: E.CAMERA_CLOSED };
|
|
2417
|
+
}
|
|
2418
|
+
/**
|
|
2419
|
+
* 启用视频track
|
|
2420
|
+
* 1. 启用前应用层需先创建视频 track
|
|
2421
|
+
*/
|
|
2422
|
+
async enableVideoTrack(e) {
|
|
2423
|
+
const _ = this.getLocalVideoTrack();
|
|
2424
|
+
return _ ? _.isOwnerMuted() ? { code: await _.unmute() } : { code: E.SUCCESS } : { code: E.CAMERA_CLOSED };
|
|
2425
|
+
}
|
|
2426
|
+
/**
|
|
2427
|
+
* 通话中切换视频设备
|
|
2428
|
+
*/
|
|
2429
|
+
async changeVideoDevice(e) {
|
|
2430
|
+
const _ = [], i = [], { code: n, track: o } = await this._rtcClient.createCameraVideoTrack(ne.NORMAL, this._videoConfig);
|
|
2431
|
+
if (n !== D.SUCCESS)
|
|
2432
|
+
return { code: n };
|
|
2433
|
+
const { minBitrate: a, maxBitrate: L } = this._videoConfig;
|
|
2434
|
+
(a || L) && o.setBitrate(L, a);
|
|
2435
|
+
let c;
|
|
2436
|
+
if (this._localTracks && this._localTracks.forEach((T) => {
|
|
2437
|
+
T.isVideoTrack() ? (T.destroy(), c = T) : i.push(T);
|
|
2438
|
+
}), this._localTracks = this._localTracks.filter((T) => c && T.getTrackId() !== c.getTrackId()), _.push(o), i.push(o), this._localTracks = i, this._onLocalTrackReady(_, e), this._room) {
|
|
2439
|
+
const { code: T } = await this._room.publish(_);
|
|
2440
|
+
if (T !== D.SUCCESS)
|
|
2441
|
+
return { code: T };
|
|
2442
|
+
}
|
|
2443
|
+
return { code: E.SUCCESS, track: o };
|
|
2444
|
+
}
|
|
2445
|
+
/**
|
|
2446
|
+
* 禁用音频 track
|
|
2447
|
+
*/
|
|
2448
|
+
async disableAudioTrack() {
|
|
2449
|
+
const e = this.getLocalAudioTrack();
|
|
2450
|
+
return e ? { code: await e.mute(), track: e } : { code: E.MICROPHONE_CLOSED };
|
|
2451
|
+
}
|
|
2452
|
+
/**
|
|
2453
|
+
* 媒体类型升、降
|
|
2454
|
+
*/
|
|
2455
|
+
async changeMediaType(e, _) {
|
|
2456
|
+
if (this._logger.info(r.L_RTC_MODULE_CHANGE_MEDIA_TYPE_T, `mediaType: ${e}`, _), e === R.AUDIO_VIDEO) {
|
|
2457
|
+
let i = this.getLocalVideoTrack();
|
|
2458
|
+
if (!i) {
|
|
2459
|
+
const { code: a, track: L } = await this._createVideoTrack(_);
|
|
2460
|
+
if (a !== E.SUCCESS) {
|
|
2461
|
+
this._logger.error(r.L_RTC_MODULE_CHANGE_MEDIA_TYPE_R, `create video track errCode: ${a}`, _);
|
|
2462
|
+
return;
|
|
2463
|
+
}
|
|
2464
|
+
i = L;
|
|
2465
|
+
const { minBitrate: c, maxBitrate: T } = this._videoConfig;
|
|
2466
|
+
(c || T) && i.setBitrate(T, c);
|
|
2467
|
+
}
|
|
2468
|
+
const n = this._isPubTiny ? { track: i, isPubTiny: !0 } : i, { code: o } = await this.publish([n], _);
|
|
2469
|
+
if (o !== E.SUCCESS) {
|
|
2470
|
+
this._logger.error(r.L_RTC_MODULE_CHANGE_MEDIA_TYPE_R, `publish errCode: ${o}`, _);
|
|
2471
|
+
return;
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
if (e === R.AUDIO) {
|
|
2475
|
+
const i = this.getLocalVideoTrack();
|
|
2476
|
+
if (i) {
|
|
2477
|
+
const { code: n } = await this._room.unpublish([i]);
|
|
2478
|
+
n !== D.SUCCESS && this._logger.error(r.L_RTC_MODULE_CHANGE_MEDIA_TYPE_R, `unpublish errCode: ${n}`, _), this.destroyTrack(i);
|
|
2479
|
+
}
|
|
2480
|
+
}
|
|
2481
|
+
this._logger.info(r.L_RTC_MODULE_CHANGE_MEDIA_TYPE_R, "success", _);
|
|
2482
|
+
}
|
|
2483
|
+
/**
|
|
2484
|
+
* 加入 RTC 房间
|
|
2485
|
+
*/
|
|
2486
|
+
async joinRTCRoom(e, _) {
|
|
2487
|
+
this._logger.info(r.L_RTC_MODULE_JOIN_RTC_ROOM_T, `call: ${e}`, _);
|
|
2488
|
+
const { code: i, room: n, tracks: o } = await X({
|
|
2489
|
+
asyncFn: this._rtcClient.joinRTCRoom.bind(this._rtcClient),
|
|
2490
|
+
fnArgs: [e, void 0, void 0, !1, Ge.CALL]
|
|
2491
|
+
});
|
|
2492
|
+
return i !== D.SUCCESS ? (this._logger.error(r.L_RTC_MODULE_JOIN_RTC_ROOM_R, `callId: ${e}, errCode: ${i}`, _), this._onRTCMethodFail(h.JOIN_ROOM_ERR, _), { code: i }) : (this._logger.info(r.L_RTC_MODULE_JOIN_RTC_ROOM_R, "success", _), this._room = n, this._onSelfJoined({ callId: e, userId: this._context.getCurrentId() }, _), o != null && o.length && this._onRemoteTrackPublish(o), this._callId = e, { code: E.SUCCESS, room: n, tracks: o });
|
|
2493
|
+
}
|
|
2494
|
+
/**
|
|
2495
|
+
* RTC 订阅
|
|
2496
|
+
*/
|
|
2497
|
+
async subscribeTracks(e, _) {
|
|
2498
|
+
if (this._logger.info(r.L_RTC_MODULE_SUBSCRIBE_T, JSON.stringify({
|
|
2499
|
+
params: e.map((n) => {
|
|
2500
|
+
const { track: o, subTiny: a } = n;
|
|
2501
|
+
return {
|
|
2502
|
+
trackId: o.getTrackId(),
|
|
2503
|
+
subTiny: a
|
|
2504
|
+
};
|
|
2505
|
+
})
|
|
2506
|
+
}), _), !this._room)
|
|
2507
|
+
return { code: E.SUCCESS };
|
|
2508
|
+
const { code: i } = await X({
|
|
2509
|
+
asyncFn: this._room.subscribe.bind(this._room),
|
|
2510
|
+
fnArgs: [e],
|
|
2511
|
+
onError: (n) => {
|
|
2512
|
+
}
|
|
2513
|
+
});
|
|
2514
|
+
return i !== D.SUCCESS ? (this._reportAppEventModule.onFetchRemoteMediaError(e, i), this._onRTCMethodFail(h.SUBSCRIBE_ERR, _), this._logger.error(r.L_RTC_MODULE_SUBSCRIBE_R, `errorCode: ${i}`, _), { code: i }) : (this._logger.info(r.L_RTC_MODULE_SUBSCRIBE_R, "success", _), { code: E.SUCCESS });
|
|
2515
|
+
}
|
|
2516
|
+
/**
|
|
2517
|
+
* RTC 取消订阅
|
|
2518
|
+
*/
|
|
2519
|
+
async unsubscribeTracks(e, _) {
|
|
2520
|
+
if (this._logger.info(r.L_RTC_MODULE_UNSUBSCRIBE_T, JSON.stringify({
|
|
2521
|
+
trackIds: e.map((n) => n.getTrackId())
|
|
2522
|
+
}), _), !this._room)
|
|
2523
|
+
return { code: E.SUCCESS };
|
|
2524
|
+
const { code: i } = await this._room.unsubscribe(e);
|
|
2525
|
+
return i !== D.SUCCESS ? (this._logger.error(r.L_RTC_MODULE_UNSUBSCRIBE_R, `errorCode: ${i}`, _), { code: i }) : (this._logger.info(r.L_RTC_MODULE_UNSUBSCRIBE_R, "success", _), { code: E.SUCCESS });
|
|
2526
|
+
}
|
|
2527
|
+
_releaseStoredData() {
|
|
2528
|
+
this._room = null, this._remoteAudioEnable = !0, this._userViewMap = {};
|
|
2529
|
+
}
|
|
2530
|
+
getRemoteTracks() {
|
|
2531
|
+
const e = {};
|
|
2532
|
+
return this._room && this._room.getRemoteUserIds().forEach((i) => {
|
|
2533
|
+
e[i] = this._room.getRemoteTracksByUserId(i);
|
|
2534
|
+
}), e;
|
|
2535
|
+
}
|
|
2536
|
+
getRemoteTrack(e, _) {
|
|
2537
|
+
var i;
|
|
2538
|
+
return (i = this._room) == null ? void 0 : i.getRemoteTracksByUserId(e).find((n) => _ === R.AUDIO ? n.isAudioTrack() : n.isVideoTrack());
|
|
2539
|
+
}
|
|
2540
|
+
/** ======私有方法============================================================================================= */
|
|
2541
|
+
/**
|
|
2542
|
+
* RTC 事件监听注册
|
|
2543
|
+
*/
|
|
2544
|
+
_regRTCListeners() {
|
|
2545
|
+
this._room.registerRoomEventListener({
|
|
2546
|
+
/**
|
|
2547
|
+
* 本端被踢出房间时触发
|
|
2548
|
+
* @description 被踢出房间可能是由于服务端超出一定时间未能收到 rtcPing 消息,所以认为己方离线。
|
|
2549
|
+
* 另一种可能是己方 rtcPing 失败次数超出上限,故而主动断线
|
|
2550
|
+
* @param byServer
|
|
2551
|
+
* 当值为 false 时,说明本端 rtcPing 超时
|
|
2552
|
+
* 当值为 true 时,说明本端收到被踢出房间通知
|
|
2553
|
+
*/
|
|
2554
|
+
onKickOff: (e, _) => {
|
|
2555
|
+
this._onKickOff(e, this._room.getRoomId(), _), this._releaseStoredData();
|
|
2556
|
+
},
|
|
2557
|
+
// 远端用户加入
|
|
2558
|
+
onUserJoin: (e) => {
|
|
2559
|
+
const _ = e.map((n) => ({ callId: this._callId, userId: n })), i = this._logger.createTraceId();
|
|
2560
|
+
this._onOtherMemJoined(_, i);
|
|
2561
|
+
},
|
|
2562
|
+
// 远端用户离开
|
|
2563
|
+
onUserLeave: (e) => {
|
|
2564
|
+
e.forEach((_) => {
|
|
2565
|
+
delete this._userViewMap[_];
|
|
2566
|
+
});
|
|
2567
|
+
},
|
|
2568
|
+
// 远端资源发布
|
|
2569
|
+
onTrackPublish: this._onRemoteTrackPublish.bind(this),
|
|
2570
|
+
// 远端资源取消发布
|
|
2571
|
+
onTrackUnpublish: this._onTrackUnpublish.bind(this),
|
|
2572
|
+
// 远端资源准备就绪
|
|
2573
|
+
onTrackReady: (e) => {
|
|
2574
|
+
this._onRemoteTrackReady([e]);
|
|
2575
|
+
},
|
|
2576
|
+
// 发布者禁用、启用视频
|
|
2577
|
+
onVideoMuteChange: (e) => {
|
|
2578
|
+
this._onVideoMuteChagne({
|
|
2579
|
+
fromUserId: e.getUserId(),
|
|
2580
|
+
muted: e.isOwnerMuted(),
|
|
2581
|
+
trackId: e.getTrackId()
|
|
2582
|
+
});
|
|
2583
|
+
},
|
|
2584
|
+
// 发布者禁用、启用音频
|
|
2585
|
+
onAudioMuteChange: (e) => {
|
|
2586
|
+
this._onAudioMuteChange({
|
|
2587
|
+
fromUserId: e.getUserId(),
|
|
2588
|
+
muted: e.isOwnerMuted(),
|
|
2589
|
+
trackId: e.getTrackId()
|
|
2590
|
+
});
|
|
2591
|
+
},
|
|
2592
|
+
onRTCPeerConnectionCloseByException: this._onRTCPeerConnectionCloseByException.bind(this)
|
|
2593
|
+
}), this._room.registerReportListener({
|
|
2594
|
+
onStateReport: this._onRTCStateReport.bind(this)
|
|
2595
|
+
}), this._room.onAudioLevelChange((e) => {
|
|
2596
|
+
this._reportAppEventModule.onUserAudioLevelChanged(e);
|
|
2597
|
+
});
|
|
2598
|
+
}
|
|
2599
|
+
_onLocalTrackReady(e, _) {
|
|
2600
|
+
this._reportAppEventModule.onUserMediaAvailable(e, _);
|
|
2601
|
+
}
|
|
2602
|
+
_onRemoteTrackReady(e) {
|
|
2603
|
+
this._reportAppEventModule.onUserMediaAvailable(e), this.emit(V.__INNER_RECEIVE_FIRST_FRAME__);
|
|
2604
|
+
}
|
|
2605
|
+
_onKickOff(e, _, i, n) {
|
|
2606
|
+
this._logger.info(r.L_RTC_MODULE_RECEIVE_KICK_OFF_O, `roonId: ${_}, byServer: ${e}, state: ${i}, kickExtra: ${JSON.stringify(n)}`);
|
|
2607
|
+
let o = h.CONNECTION_ERR;
|
|
2608
|
+
if (e)
|
|
2609
|
+
if (n)
|
|
2610
|
+
o = n.kickReasonCode;
|
|
2611
|
+
else
|
|
2612
|
+
switch (i) {
|
|
2613
|
+
case Q.SERVER_KICK:
|
|
2614
|
+
o = h.KICKED_BY_SERVER;
|
|
2615
|
+
break;
|
|
2616
|
+
case Q.OTHER_KICK:
|
|
2617
|
+
o = h.OTHER_CLIENT_JOINED;
|
|
2618
|
+
break;
|
|
2619
|
+
case Q.IM_DISCONNECTED:
|
|
2620
|
+
o = h.CONNECTION_ERR;
|
|
2621
|
+
break;
|
|
2622
|
+
case Q.IM_LOGOUT:
|
|
2623
|
+
o = h.LOGOUT;
|
|
2624
|
+
break;
|
|
2625
|
+
case Q.OTHER_CLIENT_IM_CONNECTED:
|
|
2626
|
+
o = h.OTHER_CLIENT_LOGIN;
|
|
2627
|
+
break;
|
|
2628
|
+
}
|
|
2629
|
+
this.emit(V.__INNER_ON_KICKOFF__, o, _);
|
|
2630
|
+
}
|
|
2631
|
+
/**
|
|
2632
|
+
* RTC Peer 异常关闭
|
|
2633
|
+
* 移动端未处理此回调,定义 sysStatus 为 CONNECTION_ERR
|
|
2634
|
+
*/
|
|
2635
|
+
_onRTCPeerConnectionCloseByException() {
|
|
2636
|
+
const e = this._logger.createTraceId();
|
|
2637
|
+
this._logger.info(r.L_RTC_MODULE_RECEIVE_PEERCONNECTION_EXCEPT_CLOSE_O, "", e), this.emit(V.__INNER_RTC_PEERCONNECTION_ABNORMAL_CLOSE__, e);
|
|
2638
|
+
}
|
|
2639
|
+
async _onSelfJoined(e, _) {
|
|
2640
|
+
this.emit(V.__INNER_ON_SELF_JOINED__, e.callId, _);
|
|
2641
|
+
}
|
|
2642
|
+
_onRemoteTrackPublish(e) {
|
|
2643
|
+
const _ = this._logger.createTraceId();
|
|
2644
|
+
this._onDeviceEnableChange(e, _), this._logger.info(r.L_RTC_MODULE_RECEIVE_TRACK_PUBLISH_O, JSON.stringify({
|
|
2645
|
+
callId: this._callId,
|
|
2646
|
+
trackIds: e.map((n) => n.getTrackId())
|
|
2647
|
+
}), _);
|
|
2648
|
+
const i = [];
|
|
2649
|
+
e.forEach((n) => {
|
|
2650
|
+
var a;
|
|
2651
|
+
const o = n.getUserId();
|
|
2652
|
+
if (n.isAudioTrack())
|
|
2653
|
+
i.push({ track: n, subTiny: !1 }), this._reportAppEventModule.onRemoteMicrophoneStateChanged(this._callId, n);
|
|
2654
|
+
else if ((a = this._userViewMap[o]) != null && a.videoView) {
|
|
2655
|
+
this._reportAppEventModule.onRemoteCameraStateChanged(this._callId, n);
|
|
2656
|
+
const { isTiny: L } = this._userViewMap[o];
|
|
2657
|
+
i.push({ track: n, subTiny: L });
|
|
2658
|
+
}
|
|
2659
|
+
}), i.length && this.subscribeTracks(i, _);
|
|
2660
|
+
}
|
|
2661
|
+
async _onTrackUnpublish(e) {
|
|
2662
|
+
const _ = this._logger.createTraceId();
|
|
2663
|
+
this._onDeviceEnableChange(e, _), this._logger.info(r.L_RTC_MODULE_RECEIVE_TRACK_UNPUBLISH_O, JSON.stringify({
|
|
2664
|
+
callId: this._callId,
|
|
2665
|
+
trackIds: e.map((i) => i.getTrackId())
|
|
2666
|
+
}), _), await this.unsubscribeTracks(e, _);
|
|
2667
|
+
}
|
|
2668
|
+
_onAudioMuteChange(e) {
|
|
2669
|
+
const _ = this._logger.createTraceId();
|
|
2670
|
+
this._logger.info(r.L_RTC_MODULE_RECEIVE_TRACK_ENABLE_CHANGE_O, JSON.stringify({ info: e }), _);
|
|
2671
|
+
const i = this._room.getRemoteTrack(e.trackId);
|
|
2672
|
+
this._onDeviceEnableChange([i], _), this._reportAppEventModule.onRemoteMicrophoneStateChanged(this._callId, i);
|
|
2673
|
+
}
|
|
2674
|
+
_onVideoMuteChagne(e) {
|
|
2675
|
+
const _ = this._logger.createTraceId();
|
|
2676
|
+
this._logger.info(r.L_RTC_MODULE_RECEIVE_TRACK_ENABLE_CHANGE_O, JSON.stringify({ info: e }), _);
|
|
2677
|
+
const i = this._room.getRemoteTrack(e.trackId);
|
|
2678
|
+
this._onDeviceEnableChange([i], _), this._reportAppEventModule.onRemoteCameraStateChanged(this._callId, i);
|
|
2679
|
+
}
|
|
2680
|
+
_onRTCStateReport(e) {
|
|
2681
|
+
const { senders: _, receivers: i } = e;
|
|
2682
|
+
_.forEach((n) => {
|
|
2683
|
+
var c;
|
|
2684
|
+
const { kind: o, packetsLostRate: a, rtt: L } = n;
|
|
2685
|
+
this._callMediaType === R.AUDIO_VIDEO && o === "audio" || (c = this._callPlusStatusReportListener) == null || c.onSendPacketLoss(a || 0, L || 0);
|
|
2686
|
+
}), i.forEach((n) => {
|
|
2687
|
+
var I;
|
|
2688
|
+
const {
|
|
2689
|
+
trackId: o,
|
|
2690
|
+
kind: a,
|
|
2691
|
+
packetsLostRate: L,
|
|
2692
|
+
bitrate: c
|
|
2693
|
+
} = n;
|
|
2694
|
+
if (this._callMediaType === R.AUDIO_VIDEO && a === "audio")
|
|
2695
|
+
return;
|
|
2696
|
+
const { userId: T } = Be.parseTrackId(o), S = {};
|
|
2697
|
+
S[T] = {
|
|
2698
|
+
packetLostRate: L,
|
|
2699
|
+
bitRate: c
|
|
2700
|
+
}, (I = this._callPlusStatusReportListener) == null || I.onReceivePacketLoss(S);
|
|
2701
|
+
});
|
|
2702
|
+
}
|
|
2703
|
+
/**
|
|
2704
|
+
* RTC 接收最终失败后需要调用 hangup 挂断的情况
|
|
2705
|
+
*/
|
|
2706
|
+
_onRTCMethodFail(e, _) {
|
|
2707
|
+
this.emit(V.__INNER_RTC_PROCESS_FAILED__, e, _);
|
|
2708
|
+
}
|
|
2709
|
+
_onOtherMemJoined(e, _) {
|
|
2710
|
+
this.emit(V.__INNER_ON_OTHER_JOINED__, e, _);
|
|
2711
|
+
}
|
|
2712
|
+
_onDeviceEnableChange(e, _) {
|
|
2713
|
+
this.emit(V.__INNER_ON_DEVICE_ENABLE_CHANGE__, e, _);
|
|
2714
|
+
}
|
|
2715
|
+
/**
|
|
2716
|
+
* 创建本地音频 track, 创建成功后保存本地并回调通知
|
|
2717
|
+
*/
|
|
2718
|
+
async _createAudioTrack(e) {
|
|
2719
|
+
var a;
|
|
2720
|
+
if (this._logger.info(r.L_RTC_MODULE_CREATE_AUDIO_TRACK_T, "", e), (a = this._localTracks) != null && a.some((L) => L.isAudioTrack()))
|
|
2721
|
+
return this._logger.info(r.L_RTC_MODULE_CREATE_AUDIO_TRACK_R, "success", e), { code: E.SUCCESS };
|
|
2722
|
+
const { code: _, track: i } = await this._rtcClient.createMicrophoneAudioTrack(ne.NORMAL, this._audioConfig);
|
|
2723
|
+
if (_ !== D.SUCCESS)
|
|
2724
|
+
return this._logger.error(r.L_RTC_MODULE_CREATE_AUDIO_TRACK_R, `errCode: ${_}`, e), { code: _ };
|
|
2725
|
+
this._logger.info(r.L_RTC_MODULE_CREATE_AUDIO_TRACK_R, "success", e);
|
|
2726
|
+
const { minBitrate: n, maxBitrate: o } = this._audioConfig;
|
|
2727
|
+
return (n || o) && i.setBitrate(o, n), this._localTracks.push(i), this._onLocalTrackReady([i], e), { code: E.SUCCESS, track: i };
|
|
2728
|
+
}
|
|
2729
|
+
/**
|
|
2730
|
+
* 创建本地视频 track, 创建成功后保存本地并回调通知
|
|
2731
|
+
*/
|
|
2732
|
+
async _createVideoTrack(e) {
|
|
2733
|
+
var a;
|
|
2734
|
+
if (this._logger.info(r.L_RTC_MODULE_CREATE_VIDEO_TRACK_T, "", e), (a = this._localTracks) != null && a.some((L) => L.isVideoTrack() && !L.isDestroyed()))
|
|
2735
|
+
return this._logger.info(r.L_RTC_MODULE_CREATE_VIDEO_TRACK_R, "success", e), { code: E.SUCCESS };
|
|
2736
|
+
const { code: _, track: i } = await this._rtcClient.createCameraVideoTrack(ne.NORMAL, this._videoConfig);
|
|
2737
|
+
if (_ !== D.SUCCESS)
|
|
2738
|
+
return this._logger.error(r.L_RTC_MODULE_CREATE_VIDEO_TRACK_R, `errCode: ${_}`, e), { code: _ };
|
|
2739
|
+
this._logger.info(r.L_RTC_MODULE_CREATE_VIDEO_TRACK_R, "success", e);
|
|
2740
|
+
const { minBitrate: n, maxBitrate: o } = this._videoConfig;
|
|
2741
|
+
return (n || o) && i.setBitrate(o, n), this._localTracks.push(i), this._onLocalTrackReady([i], e), { code: E.SUCCESS, track: i };
|
|
2742
|
+
}
|
|
2743
|
+
/**
|
|
2744
|
+
* 获得本地缓存视频 track
|
|
2745
|
+
*/
|
|
2746
|
+
getLocalVideoTrack() {
|
|
2747
|
+
let e;
|
|
2748
|
+
return this._localTracks && ([e] = this._localTracks.filter((_) => _.isVideoTrack())), e;
|
|
2749
|
+
}
|
|
2750
|
+
/**
|
|
2751
|
+
* 获得本地缓存音频 track
|
|
2752
|
+
*/
|
|
2753
|
+
getLocalAudioTrack() {
|
|
2754
|
+
let e;
|
|
2755
|
+
return this._localTracks && ([e] = this._localTracks.filter((_) => _.isAudioTrack())), e;
|
|
2756
|
+
}
|
|
2757
|
+
/**
|
|
2758
|
+
* 发布本地资源的逻辑
|
|
2759
|
+
*/
|
|
2760
|
+
async publish(e, _) {
|
|
2761
|
+
this._logger.info(r.L_RTC_MODULE_PUBLISH_T, `tracksIds: ${e.map((n) => n instanceof $e ? n.getTrackId() : n.track.getTrackId())}`, _);
|
|
2762
|
+
const { code: i } = await X({
|
|
2763
|
+
asyncFn: this._room.publish.bind(this._room),
|
|
2764
|
+
fnArgs: [e],
|
|
2765
|
+
onError: (n) => {
|
|
2766
|
+
}
|
|
2767
|
+
});
|
|
2768
|
+
return i !== D.SUCCESS ? (this._onRTCMethodFail(h.PUBLISH_ERR, _), this._logger.error(r.L_RTC_MODULE_PUBLISH_R, `errCode: ${i}`, _), { code: i }) : (this._logger.info(r.L_RTC_MODULE_PUBLISH_R, `code: ${E.SUCCESS}`, _), { code: E.SUCCESS });
|
|
2769
|
+
}
|
|
2770
|
+
publishVideoTrack() {
|
|
2771
|
+
const e = this.getLocalVideoTrack(), _ = this._isPubTiny ? { track: e, isPubTiny: !0 } : e;
|
|
2772
|
+
return this._room.publish([_]);
|
|
2773
|
+
}
|
|
2774
|
+
setVideoView(e, _) {
|
|
2775
|
+
const i = [];
|
|
2776
|
+
e.forEach((n) => {
|
|
2777
|
+
const { userId: o, videoElement: a, isTiny: L = !1 } = n;
|
|
2778
|
+
if (this._userViewMap[o] = {
|
|
2779
|
+
videoView: a,
|
|
2780
|
+
isTiny: L
|
|
2781
|
+
}, o === this._context.getCurrentId() || !this._room)
|
|
2782
|
+
return;
|
|
2783
|
+
const T = (this.getRemoteTracks()[o] || []).map((S) => ({
|
|
2784
|
+
track: S,
|
|
2785
|
+
subTiny: L
|
|
2786
|
+
})).filter(({ track: S }) => !S.isSubscribed());
|
|
2787
|
+
i.push(...T);
|
|
2788
|
+
}), this._logger.info(r.L_RTC_MODULE_SET_VIDEO_VIEW_O, JSON.stringify(
|
|
2789
|
+
{
|
|
2790
|
+
userViewMap: this._userViewMap,
|
|
2791
|
+
needSubTrackIds: i.map(({ track: n }) => n.getTrackId())
|
|
2792
|
+
}
|
|
2793
|
+
), _), i.length && this.subscribeTracks(i, _);
|
|
2794
|
+
}
|
|
2795
|
+
/**
|
|
2796
|
+
* 删除视图时,取消订阅资源
|
|
2797
|
+
*/
|
|
2798
|
+
removeVideoView(e, _) {
|
|
2799
|
+
const i = [];
|
|
2800
|
+
e.forEach((n) => {
|
|
2801
|
+
const o = this.getRemoteTracks()[n];
|
|
2802
|
+
if (o && o.length) {
|
|
2803
|
+
const a = o.filter((L) => L.isVideoTrack());
|
|
2804
|
+
a.length && i.push(a[0]);
|
|
2805
|
+
}
|
|
2806
|
+
delete this._userViewMap[n];
|
|
2807
|
+
}), this._logger.info(r.L_RTC_MODULE_REMOVE_VIDEO_VIEW_O, JSON.stringify(
|
|
2808
|
+
{
|
|
2809
|
+
userViewMap: this._userViewMap,
|
|
2810
|
+
unsubTracks: i.map((n) => n.getTrackId())
|
|
2811
|
+
}
|
|
2812
|
+
), _), i.length && this.unsubscribeTracks(i, _);
|
|
2813
|
+
}
|
|
2814
|
+
/**
|
|
2815
|
+
* 获取存储的人员和 video 元素数据
|
|
2816
|
+
*/
|
|
2817
|
+
getUserViewMap() {
|
|
2818
|
+
return this._userViewMap;
|
|
2819
|
+
}
|
|
2820
|
+
/**
|
|
2821
|
+
* 播放媒体资源
|
|
2822
|
+
*/
|
|
2823
|
+
async playMedia(e, _, i, n) {
|
|
2824
|
+
this._logger.info(r.L_RTC_MODULE_PLAY_MEDIA_T, `userId: ${e}, mediaType: ${_}, videoView: ${i == null ? void 0 : i.nodeName}`, n);
|
|
2825
|
+
let o = null;
|
|
2826
|
+
if (e === this._context.getCurrentId() ? o = _ === R.AUDIO ? this.getLocalAudioTrack() : this.getLocalVideoTrack() : o = this.getRemoteTracks()[e].filter((a) => _ === R.AUDIO ? a.isAudioTrack() : a.isVideoTrack())[0], !o)
|
|
2827
|
+
return this._logger.error(r.L_RTC_MODULE_PLAY_MEDIA_R, `error code: ${E.MEDIA_RESOURCE_INVALIED}`, n), { code: E.MEDIA_RESOURCE_INVALIED };
|
|
2828
|
+
try {
|
|
2829
|
+
const { code: a } = o.isAudioTrack() ? await o.play() : await o.play(i);
|
|
2830
|
+
return o.isAudioTrack() && !this._remoteAudioEnable && o.mute(), a !== D.SUCCESS ? (this._logger.error(r.L_RTC_MODULE_PLAY_MEDIA_R, `errCode: ${a}`, n), { code: a }) : (this._logger.info(r.L_RTC_MODULE_PLAY_MEDIA_R, "success", n), { code: E.SUCCESS });
|
|
2831
|
+
} catch (a) {
|
|
2832
|
+
return this._logger.error(r.L_RTC_MODULE_PLAY_MEDIA_R, `errCode: ${E.PLAY_MEDIA_FAILED}, message: ${a.message},`, n), { code: E.PLAY_MEDIA_FAILED };
|
|
2833
|
+
}
|
|
2834
|
+
}
|
|
2835
|
+
};
|
|
2836
|
+
l(V, "__INNER_RTC_PROCESS_FAILED__", "inner-rtc-process-failed"), l(V, "__INNER_RTC_PEERCONNECTION_ABNORMAL_CLOSE__", "inner-rtc-peerconnection-abnormal-close"), l(V, "__INNER_ON_SELF_JOINED__", "inner-on-self-joined"), l(V, "__INNER_ON_OTHER_JOINED__", "inner-on-other-joined"), l(V, "__INNER_RECEIVE_FIRST_FRAME__", "inner-receive-first-frame"), l(V, "__INNER_ON_KICKOFF__", "inner-kickoff-frame"), l(V, "__INNER_ON_DEVICE_ENABLE_CHANGE__", "inner-on-device-enable-change");
|
|
2837
|
+
let $ = V;
|
|
2838
|
+
class s_ {
|
|
2839
|
+
constructor(s) {
|
|
2840
|
+
l(this, "_listener");
|
|
2841
|
+
this._logger = s;
|
|
2842
|
+
}
|
|
2843
|
+
/**
|
|
2844
|
+
* 状态机事件注册
|
|
2845
|
+
*/
|
|
2846
|
+
registerEventListener(s) {
|
|
2847
|
+
this._listener = s;
|
|
2848
|
+
}
|
|
2849
|
+
/**
|
|
2850
|
+
* 回调应用层事件
|
|
2851
|
+
* @param eventName
|
|
2852
|
+
* @param attrs
|
|
2853
|
+
* @returns
|
|
2854
|
+
*/
|
|
2855
|
+
_callAppListener(s, ...e) {
|
|
2856
|
+
var i;
|
|
2857
|
+
const _ = (i = this._listener) == null ? void 0 : i[s];
|
|
2858
|
+
if (_)
|
|
2859
|
+
try {
|
|
2860
|
+
_(...e);
|
|
2861
|
+
} catch (n) {
|
|
2862
|
+
this._logger.error(r.L_CALLPLUS_CLIENT_CALL_EVENT_LISTENER_O, JSON.stringify({
|
|
2863
|
+
name: n.name,
|
|
2864
|
+
message: n.message
|
|
2865
|
+
}));
|
|
2866
|
+
}
|
|
2867
|
+
}
|
|
2868
|
+
onReceivedCall(s, e) {
|
|
2869
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_CALL_EVENT_LISTENER_O, JSON.stringify({
|
|
2870
|
+
eventType: "onReceivedCall",
|
|
2871
|
+
callId: s.getCallId()
|
|
2872
|
+
}), e), this._callAppListener("onReceivedCall", s);
|
|
2873
|
+
}
|
|
2874
|
+
onRemoteUserInvited(s, e, _) {
|
|
2875
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_CALL_EVENT_LISTENER_O, JSON.stringify({
|
|
2876
|
+
eventType: "onRemoteUserInvited",
|
|
2877
|
+
inviteeUserList: s,
|
|
2878
|
+
inviterUserId: e,
|
|
2879
|
+
callId: _
|
|
2880
|
+
})), this._callAppListener("onRemoteUserInvited", s, e, _);
|
|
2881
|
+
}
|
|
2882
|
+
onCallConnected(s) {
|
|
2883
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_CALL_EVENT_LISTENER_O, JSON.stringify({
|
|
2884
|
+
eventType: "onCallConnected",
|
|
2885
|
+
callId: s.getCallId()
|
|
2886
|
+
})), this._callAppListener("onCallConnected", s);
|
|
2887
|
+
}
|
|
2888
|
+
onCallTypeChanged(s, e, _) {
|
|
2889
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_CALL_EVENT_LISTENER_O, JSON.stringify({
|
|
2890
|
+
eventType: "onCallTypeChanged",
|
|
2891
|
+
callId: e,
|
|
2892
|
+
callType: s
|
|
2893
|
+
}), _), this._callAppListener("onCallTypeChanged", s, e);
|
|
2894
|
+
}
|
|
2895
|
+
/**
|
|
2896
|
+
* 增量上报远端人员状态变化
|
|
2897
|
+
*/
|
|
2898
|
+
onRemoteUserStateChanged(s, e) {
|
|
2899
|
+
const {
|
|
2900
|
+
callId: _,
|
|
2901
|
+
userId: i,
|
|
2902
|
+
userState: n,
|
|
2903
|
+
reason: o
|
|
2904
|
+
} = s;
|
|
2905
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_CALL_EVENT_LISTENER_O, JSON.stringify({
|
|
2906
|
+
eventType: "onRemoteUserStateChanged",
|
|
2907
|
+
callId: _,
|
|
2908
|
+
userId: i,
|
|
2909
|
+
userState: n,
|
|
2910
|
+
reason: o
|
|
2911
|
+
}), e), this._callAppListener("onRemoteUserStateChanged", _, i, n, o);
|
|
2912
|
+
}
|
|
2913
|
+
onCallEnded(s, e, _) {
|
|
2914
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_CALL_EVENT_LISTENER_O, JSON.stringify({
|
|
2915
|
+
eventType: "onCallEnded",
|
|
2916
|
+
callId: s.getCallId(),
|
|
2917
|
+
closeReason: e
|
|
2918
|
+
}), _), this._callAppListener("onCallEnded", s, e);
|
|
2919
|
+
}
|
|
2920
|
+
onRemoteCameraStateChanged(s, e) {
|
|
2921
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_CALL_EVENT_LISTENER_O, JSON.stringify({
|
|
2922
|
+
eventType: "onRemoteCameraStateChanged",
|
|
2923
|
+
callId: s,
|
|
2924
|
+
trackId: e == null ? void 0 : e.getTrackId(),
|
|
2925
|
+
enable: e == null ? void 0 : e.isOwnerMuted()
|
|
2926
|
+
}));
|
|
2927
|
+
const _ = e == null ? void 0 : e.getUserId();
|
|
2928
|
+
this._callAppListener("onRemoteCameraStateChanged", s, _, e == null ? void 0 : e.isOwnerMuted());
|
|
2929
|
+
}
|
|
2930
|
+
onRemoteMicrophoneStateChanged(s, e) {
|
|
2931
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_CALL_EVENT_LISTENER_O, JSON.stringify({
|
|
2932
|
+
eventType: "onRemoteMicrophoneStateChanged",
|
|
2933
|
+
callId: s,
|
|
2934
|
+
trackId: e == null ? void 0 : e.getTrackId(),
|
|
2935
|
+
enable: e == null ? void 0 : e.isOwnerMuted()
|
|
2936
|
+
}));
|
|
2937
|
+
const _ = e == null ? void 0 : e.getUserId();
|
|
2938
|
+
this._callAppListener("onRemoteMicrophoneStateChanged", s, _, e == null ? void 0 : e.isOwnerMuted());
|
|
2939
|
+
}
|
|
2940
|
+
onReceivedCallRecord(s, e) {
|
|
2941
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_CALL_EVENT_LISTENER_O, JSON.stringify({
|
|
2942
|
+
eventType: "onReceivedCallRecord",
|
|
2943
|
+
record: s
|
|
2944
|
+
}), e), this._callAppListener("onReceivedCallRecord", s);
|
|
2945
|
+
}
|
|
2946
|
+
onReceivedChangeMediaTypeRequest(s, e, _, i) {
|
|
2947
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_CALL_EVENT_LISTENER_O, JSON.stringify({
|
|
2948
|
+
eventType: "onReceivedChangeMediaTypeRequest",
|
|
2949
|
+
userId: s,
|
|
2950
|
+
transactionId: e
|
|
2951
|
+
}), i), this._callAppListener("onReceivedChangeMediaTypeRequest", s, e, _);
|
|
2952
|
+
}
|
|
2953
|
+
onReceivedChangeMediaTypeResult(s, e) {
|
|
2954
|
+
const {
|
|
2955
|
+
userId: _,
|
|
2956
|
+
transactionId: i,
|
|
2957
|
+
mediaType: n,
|
|
2958
|
+
code: o
|
|
2959
|
+
} = s;
|
|
2960
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_CALL_EVENT_LISTENER_O, JSON.stringify({
|
|
2961
|
+
eventType: "onReceivedChangeMediaTypeResult",
|
|
2962
|
+
userId: _,
|
|
2963
|
+
mediaType: n
|
|
2964
|
+
}), e), this._callAppListener("onReceivedChangeMediaTypeResult", {
|
|
2965
|
+
userId: _,
|
|
2966
|
+
transactionId: i,
|
|
2967
|
+
mediaType: n,
|
|
2968
|
+
code: o
|
|
2969
|
+
});
|
|
2970
|
+
}
|
|
2971
|
+
onReceivedCallStartTime(s, e) {
|
|
2972
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_CALL_EVENT_LISTENER_O, JSON.stringify({
|
|
2973
|
+
eventType: "onReceivedCallStartTime",
|
|
2974
|
+
info: s
|
|
2975
|
+
}), e), this._callAppListener("onReceivedCallStartTime", s);
|
|
2976
|
+
}
|
|
2977
|
+
onReceivedCallFirstFrameTime(s, e, _) {
|
|
2978
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_CALL_EVENT_LISTENER_O, JSON.stringify({
|
|
2979
|
+
eventType: "onReceivedCallFirstFrameTime",
|
|
2980
|
+
callId: s,
|
|
2981
|
+
callFirstFrameTime: e
|
|
2982
|
+
}), _), this._callAppListener("onReceivedCallFirstFrameTime", s, e);
|
|
2983
|
+
}
|
|
2984
|
+
onUserMediaAvailable(s, e) {
|
|
2985
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_CALL_EVENT_LISTENER_O, JSON.stringify({
|
|
2986
|
+
eventType: "onUserMediaAvailable",
|
|
2987
|
+
trackIds: s.map((_) => _.getTrackId())
|
|
2988
|
+
}), e), s.forEach((_) => {
|
|
2989
|
+
const i = _.getUserId(), n = _.isAudioTrack() ? R.AUDIO : R.VIDEO;
|
|
2990
|
+
this._callAppListener("onUserMediaAvailable", i, n);
|
|
2991
|
+
});
|
|
2992
|
+
}
|
|
2993
|
+
onFetchRemoteMediaError(s, e) {
|
|
2994
|
+
s.forEach(({ track: _ }) => {
|
|
2995
|
+
const i = _.getUserId();
|
|
2996
|
+
this._callAppListener("onFetchRemoteMediaError", i, e);
|
|
2997
|
+
});
|
|
2998
|
+
}
|
|
2999
|
+
onUserAudioLevelChanged(s) {
|
|
3000
|
+
s.forEach(({ track: e, audioLevel: _ }) => {
|
|
3001
|
+
const i = e.getUserId();
|
|
3002
|
+
this._callAppListener("onUserAudioLevelChanged", i, _);
|
|
3003
|
+
});
|
|
3004
|
+
}
|
|
3005
|
+
}
|
|
3006
|
+
var ge = /* @__PURE__ */ ((t) => (t[t.UNKNOW_ERR = 41e3] = "UNKNOW_ERR", t[t.DB_ERR = 41001] = "DB_ERR", t[t.JSON_ERR = 41002] = "JSON_ERR", t[t.INVALID_JSON_ERR = 41003] = "INVALID_JSON_ERR", t[t.MISSING_PARAMS = 41004] = "MISSING_PARAMS", t[t.PARAMS_REQUIRED = 41005] = "PARAMS_REQUIRED", t[t.DATA_FORMAT_ERR = 41006] = "DATA_FORMAT_ERR", t[t.METHOD_NOT_IMPLEMENTED = 41007] = "METHOD_NOT_IMPLEMENTED", t[t.CALL_NOT_EXIST = 41010] = "CALL_NOT_EXIST", t[t.SINGAL_EXCEED_TWO_INVITEE = 41011] = "SINGAL_EXCEED_TWO_INVITEE", t[t.GROUP_EXCEEDS_QUORUM = 41012] = "GROUP_EXCEEDS_QUORUM", t[t.OPERATION_EXPIRED = 41013] = "OPERATION_EXPIRED", t[t.DEVICE_IS_CALLING = 41014] = "DEVICE_IS_CALLING", t[t.REPORT_STREAM_READY_TIME_IS_INVALID = 41018] = "REPORT_STREAM_READY_TIME_IS_INVALID", t[t.NOT_CALL_YOURSELF = 41019] = "NOT_CALL_YOURSELF", t[t.SESSION_STATUS_NOT_EXIST = 41020] = "SESSION_STATUS_NOT_EXIST", t[t.HANGUP_NOT_ALLOW = 41021] = "HANGUP_NOT_ALLOW", t[t.ACCEPT_NOT_ALLOW = 41022] = "ACCEPT_NOT_ALLOW", t[t.OPERATION_NOT_ALLOW = 41025] = "OPERATION_NOT_ALLOW", t[t.TRANSACTION_ID_ERR = 41100] = "TRANSACTION_ID_ERR", t[t.UP_VIDEO_CANCELED = 41050] = "UP_VIDEO_CANCELED", t[t.CURRENT_CALL_IS_AUDIO = 41051] = "CURRENT_CALL_IS_AUDIO", t[t.CURRENT_CALL_IS_VIDEO = 41052] = "CURRENT_CALL_IS_VIDEO", t))(ge || {});
|
|
3007
|
+
class n_ {
|
|
3008
|
+
constructor(s, e, _, i) {
|
|
3009
|
+
/**
|
|
3010
|
+
* 摄像头采集配置
|
|
3011
|
+
*/
|
|
3012
|
+
l(this, "_videoConfig", {
|
|
3013
|
+
resolution: ee.W640_H480,
|
|
3014
|
+
frameRate: _e.FPS_15
|
|
3015
|
+
});
|
|
3016
|
+
/**
|
|
3017
|
+
* 麦克风采集配置
|
|
3018
|
+
*/
|
|
3019
|
+
l(this, "_audioConfig", {});
|
|
3020
|
+
/**
|
|
3021
|
+
* 统计埋点类
|
|
3022
|
+
*/
|
|
3023
|
+
l(this, "_callPlusStatistics");
|
|
3024
|
+
/**
|
|
3025
|
+
* client callId
|
|
3026
|
+
*/
|
|
3027
|
+
l(this, "_clientCallId", "");
|
|
3028
|
+
/**
|
|
3029
|
+
* 是否为主动挂断
|
|
3030
|
+
*/
|
|
3031
|
+
l(this, "_isLaunchHangup", !1);
|
|
3032
|
+
/**
|
|
3033
|
+
* 呼叫过程中挂断
|
|
3034
|
+
*/
|
|
3035
|
+
l(this, "_needHangupCallId", null);
|
|
3036
|
+
l(this, "_callEngine");
|
|
3037
|
+
l(this, "_rtcModule");
|
|
3038
|
+
/**
|
|
3039
|
+
* 上报应用层事件模块
|
|
3040
|
+
*/
|
|
3041
|
+
l(this, "_reportAppEventModule");
|
|
3042
|
+
this._context = s, this._logger = e, this._runtime = _, this._initOpts = i, this._reportAppEventModule = new s_(e), this._callPlusStatistics = new We(this._logger, this._context), this._callEngine = new Y(this._context, this._runtime, this._initOpts, this._logger, this._reportAppEventModule), this._rtcModule = new $(this._context, this._runtime, this._initOpts, this._logger, this._callEngine, this._reportAppEventModule), this._rtcModule.on($.__INNER_RTC_PROCESS_FAILED__, this._rtcProcessFailHandle.bind(this)), this._rtcModule.on($.__INNER_RTC_PEERCONNECTION_ABNORMAL_CLOSE__, this._peerConnectionAbnormalClose.bind(this)), this._rtcModule.on($.__INNER_ON_SELF_JOINED__, this._selfJoinedHandle.bind(this)), this._rtcModule.on($.__INNER_ON_OTHER_JOINED__, this._otherJoinedHandle.bind(this)), this._rtcModule.on($.__INNER_RECEIVE_FIRST_FRAME__, this._receiveFirstFrameHandle.bind(this)), this._rtcModule.on($.__INNER_ON_KICKOFF__, this._kickoffHandle.bind(this)), this._rtcModule.on($.__INNER_ON_DEVICE_ENABLE_CHANGE__, this._receiveDeviceEnableChangeHandle.bind(this)), this._callEngine.on(Y.__INNER_SESSION_CONNECT__, this._rtcModule.sessionConnected.bind(this._rtcModule)), this._callEngine.on(Y.__INNER_SESSION_CLOSE__, this._sessionCloseHandle.bind(this)), this._callEngine.on(Y.__INNER_CHANGE_MEDIA_TYPE__, this._rtcModule.changeMediaType.bind(this._rtcModule)), this._callEngine.on(Y.__INNER_INVITE__, (n, o) => {
|
|
3043
|
+
this._callPlusStatistics.reportStatisticsData(k.L_QS_RECEIVE_CALL_S, E.SUCCESS, +/* @__PURE__ */ new Date(), n, "", o);
|
|
3044
|
+
});
|
|
3045
|
+
}
|
|
3046
|
+
/**
|
|
3047
|
+
* 加房间、发布、订阅失败时需结束通话,并上报原因
|
|
3048
|
+
*/
|
|
3049
|
+
_rtcProcessFailHandle(s, e) {
|
|
3050
|
+
const _ = this._callEngine.getLocalMainSession();
|
|
3051
|
+
if (_) {
|
|
3052
|
+
const i = _.getCallId();
|
|
3053
|
+
this._callEngine.systemStatusUp({
|
|
3054
|
+
callId: i,
|
|
3055
|
+
sysStatus: s,
|
|
3056
|
+
forward: Z.CURRENT
|
|
3057
|
+
}, e), this._callPlusStatistics.reportStatisticsData(k.L_QS_ABNORMAL_HANGUP_S, E.SUCCESS, +/* @__PURE__ */ new Date(), _), this.__innerHangup({ callId: i, systemState: s }, e);
|
|
3058
|
+
}
|
|
3059
|
+
}
|
|
3060
|
+
/**
|
|
3061
|
+
* rtc peerConnection 异常断开时需结束通话,并上报原因
|
|
3062
|
+
*/
|
|
3063
|
+
_peerConnectionAbnormalClose(s) {
|
|
3064
|
+
const e = this._callEngine.getLocalMainSession();
|
|
3065
|
+
e && (this._callEngine.systemStatusUp({
|
|
3066
|
+
callId: e.getCallId(),
|
|
3067
|
+
sysStatus: h.CONNECTION_ERR,
|
|
3068
|
+
forward: Z.CURRENT
|
|
3069
|
+
}, s), this._callEngine.endCurrentSession(h.CONNECTION_ERR, e.getCallId(), s));
|
|
3070
|
+
}
|
|
3071
|
+
/**
|
|
3072
|
+
* 本端加入 RTC 房间,需更新本人 ONCALL 状态,重新校时
|
|
3073
|
+
*/
|
|
3074
|
+
async _selfJoinedHandle(s, e) {
|
|
3075
|
+
const _ = this._context.getCurrentId(), i = this._callEngine.getLocalMainSession();
|
|
3076
|
+
this._reportAppEventModule.onCallConnected(i);
|
|
3077
|
+
const n = this._rtcModule.getLocalVideoTrack(), o = this._rtcModule.getLocalAudioTrack(), a = n ? !n.isOwnerMuted() : !1, L = o ? !o.isOwnerMuted() : !1;
|
|
3078
|
+
this._callEngine.setUserDeviceEnable(_, R.VIDEO, a, e), this._callEngine.setUserDeviceEnable(_, R.AUDIO, L, e);
|
|
3079
|
+
const c = [
|
|
3080
|
+
{
|
|
3081
|
+
userId: _,
|
|
3082
|
+
userState: C.ONCALL,
|
|
3083
|
+
systemState: h.ONCALL,
|
|
3084
|
+
cameraEnable: a,
|
|
3085
|
+
microphoneEnable: L
|
|
3086
|
+
}
|
|
3087
|
+
];
|
|
3088
|
+
this._callEngine.updateUsersState(s, c, e), this._callEngine.startTimeCorrection(e);
|
|
3089
|
+
}
|
|
3090
|
+
/**
|
|
3091
|
+
* 远端人员加入房间,更新远端人员状态和通话状态为 ONCALL
|
|
3092
|
+
*/
|
|
3093
|
+
_otherJoinedHandle(s, e) {
|
|
3094
|
+
var n;
|
|
3095
|
+
let _ = "";
|
|
3096
|
+
const i = s.map((o) => (_ = o.callId, {
|
|
3097
|
+
userId: o.userId,
|
|
3098
|
+
userState: C.ONCALL,
|
|
3099
|
+
systemState: h.ONCALL,
|
|
3100
|
+
cameraEnable: !1,
|
|
3101
|
+
microphoneEnable: !1
|
|
3102
|
+
}));
|
|
3103
|
+
this._callEngine.updateUsersState(_, i, e), ((n = this._callEngine.getLocalMainSession()) == null ? void 0 : n.getState()) !== p.ONCALL && this._callEngine.updateMainSessionState(p.ONCALL);
|
|
3104
|
+
}
|
|
3105
|
+
/**
|
|
3106
|
+
* 收到首帧上报给业务层
|
|
3107
|
+
*/
|
|
3108
|
+
_receiveFirstFrameHandle(s) {
|
|
3109
|
+
var e;
|
|
3110
|
+
((e = this._callEngine.getLocalMainSession()) == null ? void 0 : e.getState()) !== p.ONCALL && this._callEngine.updateMainSessionState(p.ONCALL), this._callEngine.upFirstFrameTime(s);
|
|
3111
|
+
}
|
|
3112
|
+
/**
|
|
3113
|
+
* 被踢出房间时,需结束通话
|
|
3114
|
+
*/
|
|
3115
|
+
_kickoffHandle(s, e, _) {
|
|
3116
|
+
if (s === h.CONNECTION_ERR) {
|
|
3117
|
+
this._callEngine.endCurrentSession(s, e, _);
|
|
3118
|
+
return;
|
|
3119
|
+
}
|
|
3120
|
+
const i = this._callEngine.getLocalMainSession();
|
|
3121
|
+
if (i) {
|
|
3122
|
+
const n = i.getCallId();
|
|
3123
|
+
this._callPlusStatistics.reportStatisticsData(k.L_QS_ABNORMAL_HANGUP_S, E.SUCCESS, +/* @__PURE__ */ new Date(), i, this._clientCallId), this._callEngine.systemStatusUp({
|
|
3124
|
+
callId: n,
|
|
3125
|
+
sysStatus: s,
|
|
3126
|
+
forward: Z.CURRENT
|
|
3127
|
+
}, _), this._callEngine.endCurrentSession(s, e, _);
|
|
3128
|
+
}
|
|
3129
|
+
}
|
|
3130
|
+
/**
|
|
3131
|
+
* 远端资源音视频状态变化,需更新 session 中人员的设备状态
|
|
3132
|
+
*/
|
|
3133
|
+
_receiveDeviceEnableChangeHandle(s, e) {
|
|
3134
|
+
s.forEach((_) => {
|
|
3135
|
+
const i = _.getUserId(), n = _.isAudioTrack() ? R.AUDIO : R.VIDEO;
|
|
3136
|
+
this._callEngine.setUserDeviceEnable(i, n, !_.isOwnerMuted(), e);
|
|
3137
|
+
});
|
|
3138
|
+
}
|
|
3139
|
+
/**
|
|
3140
|
+
* 通话挂断时,需清空内存,离开房间
|
|
3141
|
+
*/
|
|
3142
|
+
_sessionCloseHandle(s, e) {
|
|
3143
|
+
this._isLaunchHangup || (this._clientCallId = ""), this._isLaunchHangup = !1, this._rtcModule.sessionClose(s, e);
|
|
3144
|
+
}
|
|
3145
|
+
/**
|
|
3146
|
+
* 注册应用层事件
|
|
3147
|
+
* 包含“收到呼叫、通话结束、通话人员状态变更、通话类型变更”等事件
|
|
3148
|
+
* ICallPlusEventListener 对象请参考 apiDoc
|
|
3149
|
+
*/
|
|
3150
|
+
setCallPlusEventListener(s) {
|
|
3151
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_SET_EVENT_LISTENER_O, s ? Object.keys(s).join(",") : null), this._reportAppEventModule.registerEventListener(s);
|
|
3152
|
+
}
|
|
3153
|
+
/**
|
|
3154
|
+
* 注册音视频上下行丢包数据监听
|
|
3155
|
+
* 每秒上报一次
|
|
3156
|
+
* @param listener 类型为 IStatusReportListener,详细定义可参考 apiDoc
|
|
3157
|
+
* @param listener.onSendPacketLoss 发送丢包率信息回调
|
|
3158
|
+
* @param listener.onReceivePacketLoss 接收丢包率信息回调
|
|
3159
|
+
*/
|
|
3160
|
+
setStatusReportListener(s) {
|
|
3161
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_SET_STATUS_REPORT_LISTENER_O, s ? Object.keys(s).join(",") : null), this._rtcModule.setCallPlusStatusReportListener(s);
|
|
3162
|
+
}
|
|
3163
|
+
/**
|
|
3164
|
+
* 设置要观看人员(包括自己和对方)的媒体播放器
|
|
3165
|
+
* @param list 为一个列表,可传入多人的媒体播放器
|
|
3166
|
+
* @param item.userId 用户 id
|
|
3167
|
+
* @param item.videoElement 一个 video 元素,用于播放视频,需要挂载在业务层页面上
|
|
3168
|
+
* @param item.isTiny 是否观看别人的小流,小窗口时可以配置为 true,可节省带宽,userId 为远端用户时有效
|
|
3169
|
+
* @returns code 返回是否设置成功
|
|
3170
|
+
*/
|
|
3171
|
+
setVideoView(s) {
|
|
3172
|
+
const e = this._logger.createTraceId();
|
|
3173
|
+
if (this._logger.info(r.L_CALLPLUS_CLIENT_SET_VIDEO_VIEW_T, JSON.stringify({
|
|
3174
|
+
list: s.map((_) => {
|
|
3175
|
+
const { userId: i, videoElement: n, isTiny: o } = _;
|
|
3176
|
+
return {
|
|
3177
|
+
userId: i,
|
|
3178
|
+
elementName: n == null ? void 0 : n.nodeName,
|
|
3179
|
+
isTiny: o
|
|
3180
|
+
};
|
|
3181
|
+
})
|
|
3182
|
+
}), e), !j(s))
|
|
3183
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_SET_VIDEO_VIEW_R, `params err, list: not empty array, value: ${JSON.stringify(s)}`, e), { code: E.PARAM_ERROR };
|
|
3184
|
+
for (let _ = 0; _ < s.length; _++) {
|
|
3185
|
+
const i = s[_], { userId: n, videoElement: o } = i;
|
|
3186
|
+
if (!G(n))
|
|
3187
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_SET_VIDEO_VIEW_R, `params err, userId: not empty string, value: ${n}`, e), { code: E.PARAM_ERROR };
|
|
3188
|
+
if (!Fe(o))
|
|
3189
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_SET_VIDEO_VIEW_R, `params err, videoElement: need a video element, value: ${o instanceof HTMLElement ? o.nodeName : o}`, e), { code: E.PARAM_ERROR };
|
|
3190
|
+
}
|
|
3191
|
+
return this._logger.info(r.L_CALLPLUS_CLIENT_SET_VIDEO_VIEW_R, "succes", e), this._rtcModule.setVideoView(s, e), { code: E.SUCCESS };
|
|
3192
|
+
}
|
|
3193
|
+
/**
|
|
3194
|
+
* 删除某个人的媒体播放器
|
|
3195
|
+
* 不观看某个人的视频时,业务层可以直接移除对应的 video 标签,
|
|
3196
|
+
* 调 removeVideoView 方法,SDK 内部会停止接收对方的媒体传输
|
|
3197
|
+
* @param userIds 用户 id 列表
|
|
3198
|
+
* @returns code 返回是否删除成功
|
|
3199
|
+
*/
|
|
3200
|
+
removeVideoView(s) {
|
|
3201
|
+
const e = this._logger.createTraceId();
|
|
3202
|
+
return this._logger.info(r.L_CALLPLUS_CLIENT_REMOVE_VIDEO_VIEW_T, JSON.stringify({
|
|
3203
|
+
userIds: s
|
|
3204
|
+
}), e), j(s) && s.every((_) => G(_)) ? (this._logger.info(r.L_CALLPLUS_CLIENT_REMOVE_VIDEO_VIEW_R, "succes", e), this._rtcModule.removeVideoView(s, e), { code: E.SUCCESS }) : (this._logger.error(r.L_CALLPLUS_CLIENT_REMOVE_VIDEO_VIEW_R, `params err, userIds: not empty array, userId: not empty string, value: ${JSON.stringify(s)}`, e), { code: E.PARAM_ERROR });
|
|
3205
|
+
}
|
|
3206
|
+
/**
|
|
3207
|
+
* 播放指定人员的音视频媒体
|
|
3208
|
+
* 播放某个人的视频前,请确保已经调用 `setVideoView` 方法为其设置视频视图
|
|
3209
|
+
* @param userId 指定要查看某个人的媒体资源
|
|
3210
|
+
* @param mediaType 指定播放音频还是视频
|
|
3211
|
+
* @returns 返回是否播放成功
|
|
3212
|
+
*/
|
|
3213
|
+
async playMedia(s, e) {
|
|
3214
|
+
const _ = this._logger.createTraceId();
|
|
3215
|
+
if (this._logger.info(r.L_CALLPLUS_CLIENT_PLAY_MEDIA_T, JSON.stringify({
|
|
3216
|
+
userId: s,
|
|
3217
|
+
mediaType: e
|
|
3218
|
+
}), _), !G(s))
|
|
3219
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_PLAY_MEDIA_R, `params err, userId: not empty string, value: ${s}`, _), { code: E.PARAM_ERROR };
|
|
3220
|
+
if (K(R[e]))
|
|
3221
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_PLAY_MEDIA_R, `params err, mediaType is illegal, value: ${e}`, _), { code: E.PARAM_ERROR };
|
|
3222
|
+
const { videoView: i } = this._rtcModule.getUserViewMap()[s] || {};
|
|
3223
|
+
return e !== R.AUDIO && !i ? (this._logger.error(r.L_CALLPLUS_CLIENT_PLAY_MEDIA_R, `errCode: ${E.VIDEO_VIEW_NOT_SET}, video view not set`, _), { code: E.VIDEO_VIEW_NOT_SET }) : this._rtcModule.playMedia(s, e, i, _);
|
|
3224
|
+
}
|
|
3225
|
+
/**
|
|
3226
|
+
* 创建视频配置构建器
|
|
3227
|
+
* @returns RCVideoConfigBuilder 用于构造视频采集时的配置项,可以设置摄像头设备 id、帧率、分辨率等,
|
|
3228
|
+
* 设置完需调 build 方法,最终在 setVideoConfig 后生效
|
|
3229
|
+
*/
|
|
3230
|
+
createVideoConfigBuilder() {
|
|
3231
|
+
return new ke(this._logger);
|
|
3232
|
+
}
|
|
3233
|
+
/**
|
|
3234
|
+
* 设置视频配置
|
|
3235
|
+
* 下次采集时生效,如切换摄像头、重新建立通话
|
|
3236
|
+
*/
|
|
3237
|
+
setVideoConfig(s) {
|
|
3238
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_SET_VIDEO_CONFIG_T, JSON.stringify(s));
|
|
3239
|
+
const {
|
|
3240
|
+
frameRate: e,
|
|
3241
|
+
resolution: _,
|
|
3242
|
+
maxBitrate: i,
|
|
3243
|
+
minBitrate: n
|
|
3244
|
+
} = s;
|
|
3245
|
+
if (!_e[e])
|
|
3246
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_SET_VIDEO_CONFIG_R, `param error, frameRate is illegal, value: ${e}`), { code: E.PARAM_ERROR };
|
|
3247
|
+
if (!ee[_])
|
|
3248
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_SET_VIDEO_CONFIG_R, `param error, resolution is illegal, value: ${_}`), { code: E.PARAM_ERROR };
|
|
3249
|
+
const { code: o, errorMsg: a } = Ae(n, i);
|
|
3250
|
+
return o !== E.SUCCESS && this._logger.error(r.L_CALLPLUS_CLIENT_SET_VIDEO_CONFIG_R, a), this._logger.info(r.L_CALLPLUS_CLIENT_SET_VIDEO_CONFIG_R, "success"), this._videoConfig = { ...s }, this._rtcModule.setVideoConfig(this._videoConfig), { code: E.SUCCESS };
|
|
3251
|
+
}
|
|
3252
|
+
/**
|
|
3253
|
+
* 创建音频配置构建器
|
|
3254
|
+
* @returns RCAudioConfigBuilder 用于构造音频采集时的配置项,可以设置麦克风设备 id
|
|
3255
|
+
* 设置完需调 build 方法,最终在 setAudioConfig 后生效
|
|
3256
|
+
*/
|
|
3257
|
+
createAudioConfigBuilder() {
|
|
3258
|
+
return new He(this._logger);
|
|
3259
|
+
}
|
|
3260
|
+
/**
|
|
3261
|
+
* 设置音频配置
|
|
3262
|
+
* 下次采集时生效,如重新建立通话
|
|
3263
|
+
*/
|
|
3264
|
+
setAudioConfig(s) {
|
|
3265
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_SET_AUDIO_CONFIG_T, JSON.stringify(s));
|
|
3266
|
+
const { sampleRate: e, minBitrate: _, maxBitrate: i } = s;
|
|
3267
|
+
if (e && !H(e))
|
|
3268
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_SET_AUDIO_CONFIG_R, `param error, sampleRate: type is number, value: ${e}`), { code: E.PARAM_ERROR };
|
|
3269
|
+
const { code: n, errorMsg: o } = Ae(_, i);
|
|
3270
|
+
return n !== E.SUCCESS && this._logger.error(r.L_CALLPLUS_CLIENT_SET_AUDIO_CONFIG_R, o), this._logger.info(r.L_CALLPLUS_CLIENT_SET_AUDIO_CONFIG_R, "success"), this._audioConfig = { ...s }, this._rtcModule.setAudioConfig(this._audioConfig), { code: E.SUCCESS };
|
|
3271
|
+
}
|
|
3272
|
+
/**
|
|
3273
|
+
* 发起呼叫
|
|
3274
|
+
* @param userIds 被叫人员 userId 列表,单人呼叫仅需在数组中放置对方一人的 userId
|
|
3275
|
+
* @param type 单人呼叫 or 多人呼叫
|
|
3276
|
+
* @param mediaType 通话媒体类型: 音频 or 音视频
|
|
3277
|
+
* @returns callId 呼叫成功后,产生的会话 id
|
|
3278
|
+
*/
|
|
3279
|
+
async startCall(s, e = M.SINGLE, _ = R.AUDIO_VIDEO) {
|
|
3280
|
+
this._clientCallId = ve();
|
|
3281
|
+
const i = +/* @__PURE__ */ new Date(), n = this._logger.createTraceId();
|
|
3282
|
+
if (this._logger.info(r.L_CALLPLUS_CLIENT_START_CALL_T, `userIds: ${s.join(",")}, callType: ${e}, mediaType: ${_}`, n), this._context.getConnectionStatus() !== W.CONNECTED)
|
|
3283
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_START_CALL_R, `errCode: ${E.SIGNAL_DISCONNECTED}`, n), { code: E.SIGNAL_DISCONNECTED };
|
|
3284
|
+
const o = this._context.getNaviInfo();
|
|
3285
|
+
if (!o || !ae(o))
|
|
3286
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_START_CALL_R, `errCode: ${E.RTC_SERVICE_UNAVAILABLE}`, n), { code: E.RTC_SERVICE_UNAVAILABLE };
|
|
3287
|
+
if (!(j(s) && s.every((I) => G(I))))
|
|
3288
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_START_CALL_R, `params err, userIds: not empty array, userId: not empty string, value: ${JSON.stringify(s)}`, n), { code: E.PARAM_ERROR };
|
|
3289
|
+
if (K(M[e]))
|
|
3290
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_START_CALL_R, `params err, callType is illegal, value: ${e}`, n), { code: E.PARAM_ERROR };
|
|
3291
|
+
if (K(R[_]))
|
|
3292
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_START_CALL_R, `params err, mediaType is illegal, value: ${_}`, n), { code: E.PARAM_ERROR };
|
|
3293
|
+
if (s.length > 1 && e === M.SINGLE)
|
|
3294
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_START_CALL_R, `params err, You can only call one person in a single call, userIds: ${s.join(",")}`, n), { code: E.PARAM_ERROR };
|
|
3295
|
+
if (this._callEngine.getLocalMainSession())
|
|
3296
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_START_CALL_R, `errCode: ${E.SESSION_EXIST}, session exist`, n), { code: E.SESSION_EXIST };
|
|
3297
|
+
const { code: a } = await this._rtcModule.createCallMediaTracks(_, n);
|
|
3298
|
+
if (a !== E.SUCCESS)
|
|
3299
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_START_CALL_R, `create meida tracks error code: ${a}`, n), { code: a };
|
|
3300
|
+
const { code: L, data: c } = await this._callEngine.startCall({
|
|
3301
|
+
toUsers: s.map((I) => ({ userId: I })),
|
|
3302
|
+
callType: e,
|
|
3303
|
+
mediaType: _,
|
|
3304
|
+
callId: this._clientCallId
|
|
3305
|
+
}, n);
|
|
3306
|
+
if (this._callPlusStatistics.reportStatisticsData(k.L_QS_START_CALL_S, L, i, null, this._clientCallId, null, { mediaType: _, callType: e, callId: (c == null ? void 0 : c.callId) || "" }), L !== E.SUCCESS)
|
|
3307
|
+
return this._rtcModule.destroyAllTracks(n), this._logger.error(r.L_CALLPLUS_CLIENT_START_CALL_R, `signal error code: ${L}`, n), { code: L };
|
|
3308
|
+
const { callId: T, clientCallId: S } = c;
|
|
3309
|
+
return this._needHangupCallId === S ? (this._callEngine.clearAllTimer(T, n), this._callEngine.hangup({ callId: T }, n), this._logger.info(r.L_CALLPLUS_CLIENT_START_CALL_R, `the ${T} call has been hangup`, n), { code: E.SUCCESS }) : (e === M.MULTI && await this._rtcModule.sessionConnected(T, n), this._logger.info(r.L_CALLPLUS_CLIENT_START_CALL_R, JSON.stringify({ data: c, code: L }), n), { code: E.SUCCESS, callId: T });
|
|
3310
|
+
}
|
|
3311
|
+
/**
|
|
3312
|
+
* 直接加入进行中的群组通话
|
|
3313
|
+
* @param callId 通话 id
|
|
3314
|
+
*/
|
|
3315
|
+
async joinMultiCall(s) {
|
|
3316
|
+
const e = this._logger.createTraceId();
|
|
3317
|
+
if (this._logger.info(r.L_CALLPLUS_CLIENT_JOIN_MULTI_CALL_T, `callId: ${s}`, e), this._context.getConnectionStatus() !== W.CONNECTED)
|
|
3318
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_JOIN_MULTI_CALL_R, `code: ${E.SIGNAL_DISCONNECTED}`, e), { code: E.SIGNAL_DISCONNECTED };
|
|
3319
|
+
const _ = this._context.getNaviInfo();
|
|
3320
|
+
if (!_ || !ae(_))
|
|
3321
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_JOIN_MULTI_CALL_R, `code: ${E.RTC_SERVICE_UNAVAILABLE}`, e), { code: E.RTC_SERVICE_UNAVAILABLE };
|
|
3322
|
+
if (!G(s))
|
|
3323
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_JOIN_MULTI_CALL_R, `params err, callId: not empty string, value: ${s}`, e), { code: E.PARAM_ERROR };
|
|
3324
|
+
const { code: i, data: n } = await this._callEngine.getCallSession({ callId: s }, e);
|
|
3325
|
+
if (i !== E.SUCCESS)
|
|
3326
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_JOIN_MULTI_CALL_R, `get call data error, code: ${i}`, e), { code: i };
|
|
3327
|
+
const { mediaType: o } = n, a = this._callEngine.getLocalMainSession();
|
|
3328
|
+
if (a && a.getCallId() !== s)
|
|
3329
|
+
return { code: E.SESSION_EXIST };
|
|
3330
|
+
const { code: L } = await this._rtcModule.createCallMediaTracks(o, e);
|
|
3331
|
+
if (L !== E.SUCCESS)
|
|
3332
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_JOIN_MULTI_CALL_R, `create meida tracks error code: ${L}`, e), { code: L };
|
|
3333
|
+
const { code: c } = await this._callEngine.joinCall({
|
|
3334
|
+
callId: s,
|
|
3335
|
+
mediaType: o
|
|
3336
|
+
}, e);
|
|
3337
|
+
return c !== E.SUCCESS ? (this._rtcModule.destroyAllTracks(e), this._logger.error(r.L_CALLPLUS_CLIENT_JOIN_MULTI_CALL_R, `signal error code: ${c}`, e), { code: c }) : (this._logger.info(r.L_CALLPLUS_CLIENT_JOIN_MULTI_CALL_R, `code: ${E.SUCCESS}`, e), await this._rtcModule.sessionConnected(s, e), { code: E.SUCCESS });
|
|
3338
|
+
}
|
|
3339
|
+
/**
|
|
3340
|
+
* 通话中邀请他人
|
|
3341
|
+
* 单人通话中邀请他人会引发通话类型变更
|
|
3342
|
+
* @param userIds 被邀请人列表
|
|
3343
|
+
* @returns busyUsers 返回忙线人员列表
|
|
3344
|
+
*/
|
|
3345
|
+
async invite(s) {
|
|
3346
|
+
var o;
|
|
3347
|
+
const e = this._logger.createTraceId();
|
|
3348
|
+
if (this._logger.info(r.L_CALLPLUS_CLIENT_INVITE_T, `callId: ${s.join(",")}`, e), !(j(s) && s.every((a) => G(a))))
|
|
3349
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_INVITE_R, `params err, userIds: not empty array, userId: not empty string, value: ${JSON.stringify(s)}`, e), { code: E.PARAM_ERROR };
|
|
3350
|
+
const { code: _, data: i } = await this._callEngine.invite({
|
|
3351
|
+
toUsers: s.map((a) => ({
|
|
3352
|
+
userId: a
|
|
3353
|
+
}))
|
|
3354
|
+
}, e);
|
|
3355
|
+
if (_ !== E.SUCCESS)
|
|
3356
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_INVITE_R, `signal error code: ${_}`, e), { code: _ };
|
|
3357
|
+
const n = [];
|
|
3358
|
+
return (o = i.busylineUsers) != null && o.length && n.push(...i.busylineUsers.map((a) => ({
|
|
3359
|
+
userId: a.userId,
|
|
3360
|
+
state: a.sessionStatus
|
|
3361
|
+
}))), this._logger.info(r.L_CALLPLUS_CLIENT_INVITE_R, `success busyUsers: ${JSON.stringify(n)}`, e), {
|
|
3362
|
+
code: E.SUCCESS,
|
|
3363
|
+
busyUsers: n
|
|
3364
|
+
};
|
|
3365
|
+
}
|
|
3366
|
+
/**
|
|
3367
|
+
* 接听通话
|
|
3368
|
+
* @param callId 通话 id
|
|
3369
|
+
*/
|
|
3370
|
+
async accept(s) {
|
|
3371
|
+
const e = +/* @__PURE__ */ new Date(), _ = this._logger.createTraceId();
|
|
3372
|
+
if (this._logger.info(r.L_CALLPLUS_CLIENT_ACCEPT_T, `callId: ${s}`, _), this._context.getConnectionStatus() !== W.CONNECTED)
|
|
3373
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_ACCEPT_R, `errCode: ${E.SIGNAL_DISCONNECTED}`, _), { code: E.SIGNAL_DISCONNECTED };
|
|
3374
|
+
const i = this._context.getNaviInfo();
|
|
3375
|
+
if (!i || !ae(i))
|
|
3376
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_ACCEPT_R, `errCode: ${E.RTC_SERVICE_UNAVAILABLE}`, _), { code: E.RTC_SERVICE_UNAVAILABLE };
|
|
3377
|
+
if (!G(s))
|
|
3378
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_ACCEPT_R, `params err, callId: not empty string, value: ${s}`, _), { code: E.PARAM_ERROR };
|
|
3379
|
+
const n = this._callEngine.getLocalMainSession(), o = this._callEngine.getHoldSession(s);
|
|
3380
|
+
if (!n && !o)
|
|
3381
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_ACCEPT_R, `errCode : ${E.NOT_IN_CALL}, session not exist`, _), { code: E.NOT_IN_CALL };
|
|
3382
|
+
if (s === (o == null ? void 0 : o.getCallId())) {
|
|
3383
|
+
const { code: S } = await this.hangup(n.getCallId());
|
|
3384
|
+
if (S !== E.SUCCESS)
|
|
3385
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_ACCEPT_R, `hangup mainSession error code: ${S}`, _), { code: S };
|
|
3386
|
+
this._callEngine.upgradeMainSession(s);
|
|
3387
|
+
}
|
|
3388
|
+
const L = n.getMediaType(), { code: c } = await this._rtcModule.createCallMediaTracks(L, _);
|
|
3389
|
+
if (c !== E.SUCCESS)
|
|
3390
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_ACCEPT_R, `create meida tracks error code: ${c}`, _), { code: c };
|
|
3391
|
+
const { code: T } = await this._callEngine.accept({ callId: s }, _);
|
|
3392
|
+
return this._callPlusStatistics.reportStatisticsData(k.L_QS_ACCEPT_CALL_S, T, e, n), T !== E.SUCCESS ? (this._rtcModule.destroyAllTracks(_), this._logger.error(r.L_CALLPLUS_CLIENT_ACCEPT_R, `signal error code: ${T}`, _), { code: T }) : (this._logger.info(r.L_CALLPLUS_CLIENT_ACCEPT_R, "success", _), this._rtcModule.sessionConnected(s, _), { code: E.SUCCESS });
|
|
3393
|
+
}
|
|
3394
|
+
async __innerHangup(s, e) {
|
|
3395
|
+
var n;
|
|
3396
|
+
const { callId: _ } = s;
|
|
3397
|
+
this._callEngine.setIsLocalClientHangup(!0), this._callEngine.clearAllTimer(_, e);
|
|
3398
|
+
const { code: i } = await this._callEngine.hangup(s, e);
|
|
3399
|
+
return i === ge.CALL_NOT_EXIST ? { code: E.SUCCESS } : (i === E.SUCCESS && _ === ((n = this._callEngine.getLocalMainSession()) == null ? void 0 : n.getCallId()) && await this._rtcModule.sessionClose(_, e), { code: i });
|
|
3400
|
+
}
|
|
3401
|
+
/**
|
|
3402
|
+
* 挂断通话
|
|
3403
|
+
* @param callId 为可选参数,不传时,挂断正在进行的主 session,传入时可指定挂断主通话或暂未建立连接的通话
|
|
3404
|
+
* 暂未建立连接的通话:指已在通话中时,收到呼叫但暂未接听的通话
|
|
3405
|
+
*/
|
|
3406
|
+
async hangup(s) {
|
|
3407
|
+
const e = +/* @__PURE__ */ new Date(), _ = this._logger.createTraceId();
|
|
3408
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_HANGUP_T, `callId: ${s}`, _);
|
|
3409
|
+
const i = this._callEngine.getLocalMainSession();
|
|
3410
|
+
if (!i)
|
|
3411
|
+
return { code: E.NOT_IN_CALL };
|
|
3412
|
+
if (s && !Oe(s))
|
|
3413
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_HANGUP_R, `params err, callId: type is string, value: ${s}`, _), { code: E.PARAM_ERROR };
|
|
3414
|
+
const n = i.getCallId();
|
|
3415
|
+
if (s && s !== n && !this._callEngine.getHoldSession(s))
|
|
3416
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_HANGUP_R, `params err, callId is invalid, value: ${s}`, _), { code: E.CALL_ID_INVALID };
|
|
3417
|
+
this._isLaunchHangup = !0, this._needHangupCallId = s || n;
|
|
3418
|
+
const a = this._callEngine.getHoldSession(this._needHangupCallId) || i, L = this._context.getCurrentId(), c = i.getUserList().filter((d) => d.userId === L)[0].state, T = [i.getCreatorUserId(), i.getInviterUserId()].includes(L), S = Ke(c, T), { code: I } = await this.__innerHangup({ callId: this._needHangupCallId, systemState: S }, _);
|
|
3419
|
+
return this._callPlusStatistics.reportStatisticsData(k.L_QS_HANGUP_CALL_S, I, e, a, this._clientCallId), I !== E.SUCCESS ? (this._logger.error(r.L_CALLPLUS_CLIENT_HANGUP_R, `signal error code : ${I}`, _), { code: I }) : (this._needHangupCallId = null, this._logger.info(r.L_CALLPLUS_CLIENT_HANGUP_R, "success", _), { code: E.SUCCESS });
|
|
3420
|
+
}
|
|
3421
|
+
/**
|
|
3422
|
+
* 通话中发起媒体类型变更请求
|
|
3423
|
+
* @param mediaType 媒体类型
|
|
3424
|
+
* @returns transactionId 客户端和服务端交互的事务 id,在取消或应答媒体类型切换时传入
|
|
3425
|
+
*/
|
|
3426
|
+
async requestChangeMediaType(s) {
|
|
3427
|
+
const e = this._logger.createTraceId();
|
|
3428
|
+
if (this._logger.info(r.L_CALLPLUS_CLIENT_REQUEST_CHANGE_MEDIA_TYPE_T, `mediaType: ${s}`, e), K(R[s]))
|
|
3429
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_REQUEST_CHANGE_MEDIA_TYPE_R, `params err, mediaType is illegal, value: ${s}`, e), { code: E.PARAM_ERROR };
|
|
3430
|
+
const _ = this.getCurrentCallSession(), i = _ == null ? void 0 : _.getMediaType();
|
|
3431
|
+
if (s === i)
|
|
3432
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_REQUEST_CHANGE_MEDIA_TYPE_R, `error code: ${E.MEDIATYPE_INVALID}`, e), { code: E.MEDIATYPE_INVALID };
|
|
3433
|
+
if (!this._callEngine.getLocalMainSession())
|
|
3434
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_REQUEST_CHANGE_MEDIA_TYPE_R, `error code : ${E.NOT_IN_CALL}, session not exist`, e), { code: E.NOT_IN_CALL };
|
|
3435
|
+
const n = _ == null ? void 0 : _.getUserList().filter((L) => L.userId !== this._context.getCurrentId()).map((L) => L.userId), { code: o, data: a } = await this._callEngine.requestChangeMediaType({ mediaType: s, toUserIds: n || [] }, e);
|
|
3436
|
+
return o !== E.SUCCESS ? (this._logger.error(r.L_CALLPLUS_CLIENT_REQUEST_CHANGE_MEDIA_TYPE_R, `signal error code: ${o}`, e), { code: o }) : (this._logger.info(r.L_CALLPLUS_CLIENT_REQUEST_CHANGE_MEDIA_TYPE_R, `success transactionId: ${a.transactionId}`, e), {
|
|
3437
|
+
code: E.SUCCESS,
|
|
3438
|
+
transactionId: a.transactionId
|
|
3439
|
+
});
|
|
3440
|
+
}
|
|
3441
|
+
/**
|
|
3442
|
+
* 取消切换媒体类型变更请求
|
|
3443
|
+
* @param transactionId 客户端和服务端交互的事务 id,为发起媒体类型变更请求返回的 transactionId
|
|
3444
|
+
*/
|
|
3445
|
+
async cancelChangeMediaType(s) {
|
|
3446
|
+
const e = this._logger.createTraceId();
|
|
3447
|
+
if (this._logger.info(r.L_CALLPLUS_CLIENT_CANCEL_CHANGE_MEDIA_TYPE_T, `transactionId: ${s}`, e), !G(s))
|
|
3448
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_CANCEL_CHANGE_MEDIA_TYPE_R, `param error, transactionId: not empty string, value: ${s}`, e), { code: E.PARAM_ERROR };
|
|
3449
|
+
if (!this._callEngine.getLocalMainSession())
|
|
3450
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_CANCEL_CHANGE_MEDIA_TYPE_R, `error code : ${E.NOT_IN_CALL}, session not exist`, e), { code: E.NOT_IN_CALL };
|
|
3451
|
+
const { code: _ } = await this._callEngine.cancelChangeMediaType({ transactionId: s }, e);
|
|
3452
|
+
return _ !== E.SUCCESS ? (this._logger.error(r.L_CALLPLUS_CLIENT_CANCEL_CHANGE_MEDIA_TYPE_R, `signal error code: ${_}`, e), { code: _ }) : (this._logger.info(r.L_CALLPLUS_CLIENT_CANCEL_CHANGE_MEDIA_TYPE_R, "success", e), { code: E.SUCCESS });
|
|
3453
|
+
}
|
|
3454
|
+
/**
|
|
3455
|
+
* 媒体类型变更应答
|
|
3456
|
+
* @param transactionId 客户端和服务端交互的事务 id,为 onReceivedChangeToVideo 监听收到 transactionId 参数值
|
|
3457
|
+
*/
|
|
3458
|
+
async replyChangeMediaType(s, e) {
|
|
3459
|
+
const _ = this._logger.createTraceId();
|
|
3460
|
+
if (this._logger.info(r.L_CALLPLUS_CLIENT_REPLY_CHANGE_MEDIA_TYPE_T, `transactionId: ${s}`, _), !G(s))
|
|
3461
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_REPLY_CHANGE_MEDIA_TYPE_R, `param error, transactionId: not empty string, value: ${s}`, _), { code: E.PARAM_ERROR };
|
|
3462
|
+
if (!ue(e))
|
|
3463
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_REPLY_CHANGE_MEDIA_TYPE_R, `param error, isAgree: type is boolean, value: ${e}`, _), { code: E.PARAM_ERROR };
|
|
3464
|
+
if (!this._callEngine.getLocalMainSession())
|
|
3465
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_REPLY_CHANGE_MEDIA_TYPE_R, `error code : ${E.NOT_IN_CALL}, session not exist`, _), { code: E.NOT_IN_CALL };
|
|
3466
|
+
const { code: i } = await this._callEngine.responseChangeMediaType({
|
|
3467
|
+
transactionId: s,
|
|
3468
|
+
agree: e
|
|
3469
|
+
}, _);
|
|
3470
|
+
return i !== E.SUCCESS ? (this._logger.error(r.L_CALLPLUS_CLIENT_REPLY_CHANGE_MEDIA_TYPE_R, `signal error: ${i}`, _), { code: i }) : (this._logger.info(r.L_CALLPLUS_CLIENT_REPLY_CHANGE_MEDIA_TYPE_R, "success", _), { code: E.SUCCESS });
|
|
3471
|
+
}
|
|
3472
|
+
/**
|
|
3473
|
+
* 获取当前进行中的通话
|
|
3474
|
+
* @returns RCCallPlusSession 对象或 null 为当前正在进行的通话对象
|
|
3475
|
+
*/
|
|
3476
|
+
getCurrentCallSession() {
|
|
3477
|
+
return this._callEngine.getLocalMainSession();
|
|
3478
|
+
}
|
|
3479
|
+
/**
|
|
3480
|
+
* 从服务器获取未结束的通话记录
|
|
3481
|
+
* @returns records 一组未结束的通话记录
|
|
3482
|
+
*/
|
|
3483
|
+
async getAvailableCallRecordsFromServer() {
|
|
3484
|
+
const s = this._logger.createTraceId();
|
|
3485
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_GET_AVAILABLE_CALL_RECORDS_FROM_SERVER_T, "", s);
|
|
3486
|
+
const { code: e, data: _ } = await this._callEngine.getOpenCallList(s);
|
|
3487
|
+
return e !== E.SUCCESS ? (this._logger.error(r.L_CALLPLUS_CLIENT_GET_AVAILABLE_CALL_RECORDS_FROM_SERVER_R, `signal error code: ${e}`, s), { code: e }) : (this._logger.info(r.L_CALLPLUS_CLIENT_GET_AVAILABLE_CALL_RECORDS_FROM_SERVER_R, `success, data: ${JSON.stringify(_)}`, s), {
|
|
3488
|
+
code: E.SUCCESS,
|
|
3489
|
+
records: _
|
|
3490
|
+
});
|
|
3491
|
+
}
|
|
3492
|
+
/**
|
|
3493
|
+
* 分页查找当前用户的全部通话记录
|
|
3494
|
+
* @param startTimestamp 起始时间戳,返回大于此时间戳的通话记录
|
|
3495
|
+
* @param count 每次获取的数量
|
|
3496
|
+
* @returns result.hasMore 是否有更多通话记录
|
|
3497
|
+
* @returns result.list 通话记录列表,类型为 IRCCallPlusCallRecord[],可通过 apiDoc 查看具体包含字段
|
|
3498
|
+
* @returns result.maxTime 列表中最大时间戳,如果 hasMore 为 true,继续获取时,传入此时间戳
|
|
3499
|
+
*/
|
|
3500
|
+
async getCallRecords(s, e) {
|
|
3501
|
+
const _ = this._logger.createTraceId();
|
|
3502
|
+
if (this._logger.info(r.L_CALLPLUS_CLIENT_GET_CALL_RECORDS_T, `startTimestamp: ${s}, count: ${e}`, _), !(H(s) && s >= 0))
|
|
3503
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_GET_CALL_RECORDS_R, `params error, startTimestamp: is a number >= 0, value: ${s}`, _), { code: E.PARAM_ERROR };
|
|
3504
|
+
if (!(H(e) && e > 0))
|
|
3505
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_GET_CALL_RECORDS_R, `params error, count: is a number >= 0, value: ${e}`, _), { code: E.PARAM_ERROR };
|
|
3506
|
+
const { code: i, data: n } = await this._callEngine.getCallLogList({
|
|
3507
|
+
timestamp: s,
|
|
3508
|
+
count: e
|
|
3509
|
+
}, _);
|
|
3510
|
+
return i !== E.SUCCESS ? (this._logger.error(r.L_CALLPLUS_CLIENT_GET_CALL_RECORDS_R, `signal error code: ${i}`, _), { code: i }) : (this._logger.info(r.L_CALLPLUS_CLIENT_GET_CALL_RECORDS_R, "success", _), {
|
|
3511
|
+
code: E.SUCCESS,
|
|
3512
|
+
result: n
|
|
3513
|
+
});
|
|
3514
|
+
}
|
|
3515
|
+
/**
|
|
3516
|
+
* 根据 callId 集合批量删除通话记录
|
|
3517
|
+
* @param callIds callId 列表
|
|
3518
|
+
*/
|
|
3519
|
+
async deleteCallRecordsFromServer(s) {
|
|
3520
|
+
const e = this._logger.createTraceId();
|
|
3521
|
+
if (this._logger.info(r.L_CALLPLUS_CLIENT_DELETE_CALL_RECORDS_BY_CALLID_T, `callIds: ${s.join(",")}`, e), !(j(s) && s.every((i) => G(i))))
|
|
3522
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_DELETE_CALL_RECORDS_BY_CALLID_R, `params err, callIds: not empty array, callId: not empty string, callIds: ${JSON.stringify(s)}`, e), { code: E.PARAM_ERROR };
|
|
3523
|
+
const { code: _ } = await this._callEngine.deleteCallLog(s, e);
|
|
3524
|
+
return _ !== E.SUCCESS ? (this._logger.error(r.L_CALLPLUS_CLIENT_DELETE_CALL_RECORDS_BY_CALLID_R, `signal error code: ${_}`, e), { code: _ }) : (this._logger.info(r.L_CALLPLUS_CLIENT_DELETE_CALL_RECORDS_BY_CALLID_R, "success", e), {
|
|
3525
|
+
code: E.SUCCESS
|
|
3526
|
+
});
|
|
3527
|
+
}
|
|
3528
|
+
/**
|
|
3529
|
+
* 清空所有通话记录
|
|
3530
|
+
*/
|
|
3531
|
+
async deleteAllCallRecordsFromServer() {
|
|
3532
|
+
const s = this._logger.createTraceId();
|
|
3533
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_DELETE_ALL_CALL_RECORDS_FROM_SERVER_T, "", s);
|
|
3534
|
+
const { code: e } = await this._callEngine.removeAllCallLog(s);
|
|
3535
|
+
return e !== E.SUCCESS ? (this._logger.error(r.L_CALLPLUS_CLIENT_DELETE_ALL_CALL_RECORDS_FROM_SERVER_R, `signal error code: ${e}`, s), { code: e }) : (this._logger.info(r.L_CALLPLUS_CLIENT_DELETE_ALL_CALL_RECORDS_FROM_SERVER_R, "success", s), { code: E.SUCCESS });
|
|
3536
|
+
}
|
|
3537
|
+
/**
|
|
3538
|
+
* 开启摄像头
|
|
3539
|
+
* @description 通话过程中打开摄像头,如果扩散资源失败,即对方没收到本端打开摄像头的通知时,此次行为失败
|
|
3540
|
+
* @returns track 摄像头视频资源
|
|
3541
|
+
*/
|
|
3542
|
+
async startCamera() {
|
|
3543
|
+
var n;
|
|
3544
|
+
const s = this._logger.createTraceId();
|
|
3545
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_START_CAMERA_T, "", s);
|
|
3546
|
+
const { code: e, track: _ } = await this._rtcModule.getCameraVideoTrack(s);
|
|
3547
|
+
if (e !== E.SUCCESS)
|
|
3548
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_START_CAMERA_R, `create video track error code: ${e}`, s), { code: e };
|
|
3549
|
+
if (this._callEngine.setUserDeviceEnable(this._context.getCurrentId(), R.VIDEO, !0, s), !(_ != null && _.isPublished()) && ((n = this._callEngine.getLocalMainSession()) == null ? void 0 : n.getState()) === p.ONCALL) {
|
|
3550
|
+
const { code: o } = await this._rtcModule.publishVideoTrack();
|
|
3551
|
+
return o !== D.SUCCESS ? (this._logger.error(r.L_CALLPLUS_CLIENT_START_CAMERA_R, `publish error code: ${o}`, s), { code: o }) : (this._logger.info(r.L_CALLPLUS_CLIENT_START_CAMERA_R, "success", s), { code: E.SUCCESS });
|
|
3552
|
+
}
|
|
3553
|
+
const { code: i } = await this._rtcModule.enableVideoTrack(s);
|
|
3554
|
+
return i !== D.SUCCESS && i !== E.SUCCESS ? (this._logger.error(r.L_CALLPLUS_CLIENT_START_CAMERA_R, `signal error code: ${i}`, s), { code: i }) : (this._logger.info(r.L_CALLPLUS_CLIENT_START_CAMERA_R, "success", s), { code: E.SUCCESS });
|
|
3555
|
+
}
|
|
3556
|
+
/**
|
|
3557
|
+
* 关闭摄像头
|
|
3558
|
+
*/
|
|
3559
|
+
async stopCamera() {
|
|
3560
|
+
const s = this._logger.createTraceId();
|
|
3561
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_STOP_CAMERA_T, "", s);
|
|
3562
|
+
const { code: e, track: _ } = await this._rtcModule.disableVideoTrack();
|
|
3563
|
+
return e !== E.SUCCESS && e !== D.SUCCESS ? (this._logger.error(r.L_CALLPLUS_CLIENT_STOP_CAMERA_R, `error code: ${e}`, s), { code: e }) : (this._rtcModule.destroyTrack(_), this._callEngine.setUserDeviceEnable(this._context.getCurrentId(), R.VIDEO, !1, s), this._logger.info(r.L_CALLPLUS_CLIENT_STOP_CAMERA_R, "success", s), { code: E.SUCCESS });
|
|
3564
|
+
}
|
|
3565
|
+
/**
|
|
3566
|
+
* 切换摄像头
|
|
3567
|
+
* 切换成功后 `ICallPlusEventListener` 监听器的 `onUserMediaAvailable` 中会收到新切换的摄像头资源可播放,此时调用 `callPlusClient.playMedia()` 可显示新摄像头的画面
|
|
3568
|
+
* @param cameraId 浏览器中取得的摄像头设备 id,可调 plugin-rtc 的 getCameras 方法取得
|
|
3569
|
+
* @description 通话前和通话中都可调用
|
|
3570
|
+
*/
|
|
3571
|
+
async switchCamera(s) {
|
|
3572
|
+
const e = this._logger.createTraceId();
|
|
3573
|
+
if (this._logger.info(r.L_CALLPLUS_CLIENT_SWITCH_CAMERA_T, `cameraId: ${s}`, e), !G(s))
|
|
3574
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_SWITCH_CAMERA_R, `param error, cameraId: not empty string, value: ${s}`, e), { code: E.PARAM_ERROR };
|
|
3575
|
+
const _ = this._callEngine.getLocalMainSession();
|
|
3576
|
+
if (!_)
|
|
3577
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_SWITCH_CAMERA_R, `errCode: ${E.NOT_IN_CALL}`, e), { code: E.NOT_IN_CALL };
|
|
3578
|
+
if (_.getMediaType() === R.AUDIO)
|
|
3579
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_SWITCH_CAMERA_R, `errCode: ${E.NOT_VIDEO_CALL}`, e), { code: E.NOT_VIDEO_CALL };
|
|
3580
|
+
this._videoConfig.cameraId = s, this._rtcModule.setVideoConfig(this._videoConfig);
|
|
3581
|
+
const { code: i } = await this._rtcModule.changeVideoDevice(e);
|
|
3582
|
+
return i !== E.SUCCESS ? (this._logger.error(r.L_CALLPLUS_CLIENT_SWITCH_CAMERA_R, `call client changeVideoDevice error code: ${i}`, e), { code: i }) : (this._logger.info(r.L_CALLPLUS_CLIENT_SWITCH_CAMERA_R, "success", e), { code: E.SUCCESS });
|
|
3583
|
+
}
|
|
3584
|
+
/**
|
|
3585
|
+
* 开启麦克风
|
|
3586
|
+
* @description 通话过程中打开麦克风,如果扩散资源失败,即对方没收到本端打开麦克风的通知时,此次行为失败
|
|
3587
|
+
*/
|
|
3588
|
+
async startMicrophone() {
|
|
3589
|
+
const s = this._logger.createTraceId();
|
|
3590
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_START_MICROPHONE_T, "", s);
|
|
3591
|
+
const { code: e, track: _ } = await this._rtcModule.getMicrophoneAudioTrack(s);
|
|
3592
|
+
if (e !== E.SUCCESS)
|
|
3593
|
+
return this._logger.error(r.L_CALLPLUS_CLIENT_START_MICROPHONE_R, `create microphone audio track error code: ${e}`, s), { code: e };
|
|
3594
|
+
if (this._callEngine.setUserDeviceEnable(this._context.getCurrentId(), R.AUDIO, !0, s), !_.isOwnerMuted())
|
|
3595
|
+
return this._logger.info(r.L_CALLPLUS_CLIENT_START_MICROPHONE_R, "success", s), { code: E.SUCCESS };
|
|
3596
|
+
const i = await _.unmute();
|
|
3597
|
+
return i !== D.SUCCESS ? (this._logger.error(r.L_CALLPLUS_CLIENT_START_MICROPHONE_R, `signal error code: ${e}`, s), {
|
|
3598
|
+
code: i
|
|
3599
|
+
}) : (this._logger.info(r.L_CALLPLUS_CLIENT_START_MICROPHONE_R, "success", s), {
|
|
3600
|
+
code: E.SUCCESS
|
|
3601
|
+
});
|
|
3602
|
+
}
|
|
3603
|
+
/**
|
|
3604
|
+
* 关闭麦克风
|
|
3605
|
+
* @description 通话过程中关闭麦克风,如果扩散资源失败,即对方没收到本端关闭麦克风的通知时,此次行为失败
|
|
3606
|
+
*/
|
|
3607
|
+
async stopMicrophone() {
|
|
3608
|
+
const s = this._logger.createTraceId();
|
|
3609
|
+
this._logger.info(r.L_CALLPLUS_CLIENT_STOP_MICROPHONE_T, "", s);
|
|
3610
|
+
const { code: e, track: _ } = await this._rtcModule.disableAudioTrack();
|
|
3611
|
+
return e !== E.SUCCESS && e !== D.SUCCESS ? (this._logger.error(r.L_CALLPLUS_CLIENT_STOP_MICROPHONE_R, `signal error code: ${e}`, s), { code: e }) : (this._callEngine.setUserDeviceEnable(this._context.getCurrentId(), R.AUDIO, !1, s), this._logger.info(r.L_CALLPLUS_CLIENT_STOP_MICROPHONE_R, "success", s), { code: E.SUCCESS });
|
|
3612
|
+
}
|
|
3613
|
+
/**
|
|
3614
|
+
* 麦克风是否开启
|
|
3615
|
+
*/
|
|
3616
|
+
isMicrophoneEnabled() {
|
|
3617
|
+
const s = this._rtcModule.getLocalAudioTrack();
|
|
3618
|
+
return !!s && !s.isOwnerMuted();
|
|
3619
|
+
}
|
|
3620
|
+
/**
|
|
3621
|
+
* 设置所有远端音频流是否可用
|
|
3622
|
+
* @param enable 为 true 时,静音所有远端音频流;为 false 时,启用所有远端音频流
|
|
3623
|
+
*/
|
|
3624
|
+
async setAllRemoteAudioEnable(s) {
|
|
3625
|
+
const e = this._logger.createTraceId();
|
|
3626
|
+
return this._rtcModule.setAllRemoteAudioEnable(s, e);
|
|
3627
|
+
}
|
|
3628
|
+
/**
|
|
3629
|
+
* 获取 SDK 版本信息
|
|
3630
|
+
* @returns SDK 版本号
|
|
3631
|
+
*/
|
|
3632
|
+
getVersion() {
|
|
3633
|
+
return "1.0.0";
|
|
3634
|
+
}
|
|
3635
|
+
/**
|
|
3636
|
+
* 获取摄像头列表
|
|
3637
|
+
*/
|
|
3638
|
+
async getCameras() {
|
|
3639
|
+
return await he.getCameras();
|
|
3640
|
+
}
|
|
3641
|
+
/**
|
|
3642
|
+
* 获取麦克风列表
|
|
3643
|
+
*/
|
|
3644
|
+
async getMicrophones() {
|
|
3645
|
+
return await he.getMicrophones();
|
|
3646
|
+
}
|
|
3647
|
+
}
|
|
3648
|
+
const r_ = (t) => t ? de(t) ? Object.keys(t).includes("rtcClient") ? de(t.rtcClient) ? !K(t.logStdout) && !be(t.logStdout) ? { isLegal: !1, msg: "Initialization 'logStdout' parameter must be of type 'function'" } : { isLegal: !0 } : { isLegal: !1, msg: "Initialization 'rtcClient' parameter must be of type 'object'" } : { isLegal: !1, code: E.NOT_INSTALL_RTC_PLUGIN } : { isLegal: !1, msg: "Initialization options must be an object" } : { isLegal: !1, msg: "Initialization missing parameter -> options" }, L_ = {
|
|
3649
|
+
tag: "RCCallPlus",
|
|
3650
|
+
verify(t) {
|
|
3651
|
+
return t.tag === "browser";
|
|
3652
|
+
},
|
|
3653
|
+
setup(t, s, e) {
|
|
3654
|
+
const _ = r_(e);
|
|
3655
|
+
if (!_.isLegal)
|
|
3656
|
+
throw new Error(`[RCCallLib installer steup]${_.msg}`);
|
|
3657
|
+
const i = t.createLogger("CallPlusLib", "RTC"), n = K(e.logOutputLevel) ? we.WARN : e.logOutputLevel;
|
|
3658
|
+
return i.setOutputLevel(n), i.warn(r.L_INDEX_INSTALL_CALL_PLUS_PLUGIN_O, "CallPlus Version: 1.0.0, Commit: 7f2df576f1c6c0cdc97989dfb1345bbf9c2e7a01"), new n_(t, i, s, e);
|
|
3659
|
+
}
|
|
3660
|
+
};
|
|
3661
|
+
export {
|
|
3662
|
+
He as RCAudioConfigBuilder,
|
|
3663
|
+
p as RCCallPlusCallState,
|
|
3664
|
+
n_ as RCCallPlusClient,
|
|
3665
|
+
E as RCCallPlusCode,
|
|
3666
|
+
S_ as RCCallPlusFrameRate,
|
|
3667
|
+
R as RCCallPlusMediaType,
|
|
3668
|
+
F as RCCallPlusMediaTypeChangeResult,
|
|
3669
|
+
h as RCCallPlusReason,
|
|
3670
|
+
l_ as RCCallPlusResolution,
|
|
3671
|
+
ie as RCCallPlusSession,
|
|
3672
|
+
C as RCCallPlusSessionUserState,
|
|
3673
|
+
M as RCCallPlusType,
|
|
3674
|
+
ke as RCVideoConfigBuilder,
|
|
3675
|
+
L_ as installer
|
|
3676
|
+
};
|
|
3677
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZXNtLmpzIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29yZS9hcGkvZW51bXMvUkNDYWxsUGx1c0NvZGUudHMiLCIuLi8uLi8uLi9zcmMvY29yZS9hcGkvZW51bXMvUkNDYWxsUGx1c0xvZ2dlclRhZy50cyIsIi4uLy4uLy4uL3NyYy9jb3JlL21vZHVsZXMvUkNDYWxsUGx1c1Nlc3Npb24udHMiLCIuLi8uLi8uLi9zcmMvY29yZS9lbnVtcy9SQ0NhbGxUeXBlLnRzIiwiLi4vLi4vLi4vc3JjL2NvcmUvZW51bXMvUkNDYWxsU2Vzc2lvblVzZXJTdGF0ZS50cyIsIi4uLy4uLy4uL3NyYy9jb3JlL2VudW1zL1JDQ2FsbFBsdXNNZWRpYVR5cGUudHMiLCIuLi8uLi8uLi9zcmMvY29yZS9lbnVtcy9SQ0NhbGxTZXNzaW9uU3RhdGUudHMiLCIuLi8uLi8uLi9zcmMvY29yZS9lbnVtcy9SQ0NhbGxQbHVzTWVkaWFUeXBlQ2hhbmdlUmVzdWx0LnRzIiwiLi4vLi4vLi4vc3JjL2NvcmUvYXBpL2VudW1zL1JDQ2FsbFBsdXNSZWFzb24udHMiLCIuLi8uLi8uLi9zcmMvY29yZS9hcGkvUkNBdWRpb0NvbmZpZ0J1aWxkZXIudHMiLCIuLi8uLi8uLi9zcmMvY29yZS9hcGkvUkNWaWRlb0NvbmZpZ0J1aWxkZXIudHMiLCIuLi8uLi8uLi9zcmMvY29yZS91dGlscy9oZWxwZXIudHMiLCIuLi8uLi8uLi9zcmMvY29yZS9lbnVtcy9SQ0NhbGxQbHVzU3RhdGlzdGljc1RhZy50cyIsIi4uLy4uLy4uL3NyYy9jb3JlL21vZHVsZXMvUkNDYWxsUEx1c1N0YXRpc3RpY3MudHMiLCIuLi8uLi8uLi9zcmMvY29yZS9lbnVtcy9EaWFsb2dBY3Rpb24udHMiLCIuLi8uLi8uLi9zcmMvY29yZS9lbnVtcy9EaWFsb2dUeXBlLnRzIiwiLi4vLi4vLi4vc3JjL2NvcmUvZW51bXMvU2VjcmV0Q2FsbFR5cGUudHMiLCIuLi8uLi8uLi9zcmMvY29yZS9tb2R1bGVzL1JDQ2FsbElubmVyU2Vzc2lvbi50cyIsIi4uLy4uLy4uL3NyYy9jb3JlL2VudW1zL0NhbGxTZXJ2ZXJBY3Rpb24udHMiLCIuLi8uLi8uLi9zcmMvY29yZS91dGlscy90aW1lcnMudHMiLCIuLi8uLi8uLi9zcmMvY29yZS91dGlscy9yZXRyeS50cyIsIi4uLy4uLy4uL3NyYy9jb3JlL2ludGVyZmFjZXMvSUNhbGxIb29rcy50cyIsIi4uLy4uLy4uL3NyYy9jb3JlL21vZHVsZXMvU2lnbmFsVHJhbnNwb3J0ZXIudHMiLCIuLi8uLi8uLi9zcmMvY29yZS91dGlscy9yYW5kb20udHMiLCIuLi8uLi8uLi9zcmMvY29yZS91dGlscy9pbmRleERCLnRzIiwiLi4vLi4vLi4vc3JjL2NvcmUvbW9kdWxlcy9BYm5vcm1hbENhbGwudHMiLCIuLi8uLi8uLi9zcmMvY29yZS9lbnVtcy9DYWxsU2VydmVyRXZlbnRUeXBlLnRzIiwiLi4vLi4vLi4vc3JjL2NvcmUvZW51bXMvUkNDYWxsUGx1c0lubmVyQ29kZS50cyIsIi4uLy4uLy4uL3NyYy9jb3JlL21vZHVsZXMvVGltZUNvcnJlY3Rpb25lci50cyIsIi4uLy4uLy4uL3NyYy9jb3JlL2VudW1zL0ZvcndhcmRUeXBlLnRzIiwiLi4vLi4vLi4vc3JjL2NvcmUvaW50ZXJmYWNlcy9JQ2FsbFBsdXNTdGF0aXN0aWNzLnRzIiwiLi4vLi4vLi4vc3JjL2NvcmUvZW51bXMvUkNDYWxsRGlyZWN0aW9uLnRzIiwiLi4vLi4vLi4vc3JjL2NvcmUvUkNDYWxsRW5naW5lLnRzIiwiLi4vLi4vLi4vc3JjL2NvcmUvZW51bXMvUlRDUmVzb3VyY2VUYWcudHMiLCIuLi8uLi8uLi9zcmMvY29yZS9tb2R1bGVzL1JUQ01vZHVsZS50cyIsIi4uLy4uLy4uL3NyYy9jb3JlL21vZHVsZXMvUkNDYWxsUGx1c1JlcG9ydE1vZHVsZS50cyIsIi4uLy4uLy4uL3NyYy9jb3JlL2VudW1zL0NhbGxTZXJ2ZXJFcnJvckNvZGUudHMiLCIuLi8uLi8uLi9zcmMvY29yZS9hcGkvUkNDYWxsUGx1c0NsaWVudC50cyIsIi4uLy4uLy4uL3NyYy9jb3JlL3V0aWxzL3ZhbGlkYXRpb24udHMiLCIuLi8uLi8uLi9zcmMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAZW51bVxuICovXG5leHBvcnQgY29uc3QgUkNDYWxsUGx1c0NvZGUgPSB7XG4gIC8qKlxuICAgKiDmiJDlip9cbiAgICovXG4gIFNVQ0NFU1M6IDAsXG4gIC8qKlxuICAgKiDlj4LmlbDplJnor69cbiAgICovXG4gIFBBUkFNX0VSUk9SOiA4MDAwMSxcbiAgLyoqXG4gICAqIOWtmOWcqOacque7k+adn+eahCBzZXNzaW9uXG4gICAqL1xuICBTRVNTSU9OX0VYSVNUOiA4MDAwMixcbiAgLyoqXG4gICAqIOacquWKoOWFpemAmuivnVxuICAgKi9cbiAgTk9UX0lOX0NBTEw6IDgwMDAzLFxuICAvKipcbiAgICog5aqS5L2T57G75Z6L6KKr56aB5q2iXG4gICAqL1xuICBNRURJQVRZUEVfSU5WQUxJRDogODAwMDQsXG4gIC8qKlxuICAgKiDlvZPliY3kuI3mmK/op4bpopHpgJror51cbiAgICovXG4gIE5PVF9WSURFT19DQUxMOiA4MDAwNSxcbiAgLyoqXG4gICAqIOW8gOmAmueahOmfs+inhumikeacjeWKoeayoeacieWPiuaXtueUn+aViOaIlumfs+inhumikeacjeWKoeW3suWFs+mXrVxuICAgKi9cbiAgUlRDX1NFUlZJQ0VfVU5BVkFJTEFCTEU6IDgwMDA2LFxuICAvKipcbiAgICog6LCD55So5Ye95pWw5pe277yM5Lyg5YWl55qE55So5oi35YiX6KGo5Li656m66ZSZ6K+vXG4gICAqL1xuICBVU0VSX0xJU1RfSU5WQUlMRDogODAwMDcsXG4gIC8qKlxuICAgKiDosIPnlKjlh73mlbDml7bvvIzkvKDlhaXnmoTpgJror50gSWQg5Li656m66ZSZ6K+vXG4gICAqL1xuICBDQUxMX0lEX0lOVkFMSUQ6IDgwMDA4LFxuICAvKipcbiAgICog5LqL5YqhIElkIOS4uuepuumUmeivr1xuICAgKi9cbiAgVFJBTlNBQ1RJT05fSURfSU5WQUxJRDogODAwMDksXG4gIC8qKlxuICAgKiDosIPnlKjlh73mlbDml7bvvIzkvKDlhaXnmoTnlKjmiLcgSWQg5Li656m66ZSZ6K+vXG4gICAqL1xuICBVU0VSX0lEX0lOVkFMSUQ6IDgwMDEwLFxuICAvKipcbiAgICog5Y+R6LW35Y2V5Lq65ZG85Y+r5pe277yM5Lq65ZGY5YiX6KGo5Lit5Y+q6IO95pyJ5LiA5Liq5Lq6XG4gICAqL1xuICBTSU5HTEVfQ0FMTF9OT1RfU1VQUE9SVF9NVUxUSV9QRVJTT046IDgwMDExLFxuICAvKipcbiAgICogaW0g5pyq6L+e5o6lXG4gICAqL1xuICBTSUdOQUxfRElTQ09OTkVDVEVEOiA4MDAxMixcbiAgLyoqXG4gICAqIOaRhOWDj+WktOacquaJk+W8gFxuICAgKi9cbiAgQ0FNRVJBX0NMT1NFRDogODAxMDAsXG4gIC8qKlxuICAgKiDpuqblhYvpo47mnKrmiZPlvIBcbiAgICovXG4gIE1JQ1JPUEhPTkVfQ0xPU0VEOiA4MDEwMSxcbiAgLyoqXG4gICAqIOaXoOWqkuS9k+i1hOa6kFxuICAgKi9cbiAgTUVESUFfUkVTT1VSQ0VfSU5WQUxJRUQ6IDgwMTAyLFxuICAvKipcbiAgICog5pyqIGluc3RhbGwgUlRDIOaPkuS7tlxuICAgKi9cbiAgTk9UX0lOU1RBTExfUlRDX1BMVUdJTjogODAxMDMsXG4gIC8qKlxuICAgKiDmkq3mlL7lvILluLhcbiAgICovXG4gIFBMQVlfTUVESUFfRkFJTEVEOiA4MDEwNCxcbiAgLyoqXG4gICAqIOaSreaUvuinhumikemcgOimgSB2aWRlbyDlhYPntKBcbiAgICovXG4gIFZJREVPX1ZJRVdfTk9UX1NFVDogODAxMDUsXG59IGFzIGNvbnN0O1xuIiwiZXhwb3J0IGVudW0gUkNDYWxsUGx1c0xvZ2dlclRhZyB7XG4gIExfSU5ERVhfSU5TVEFMTF9DQUxMX1BMVVNfUExVR0lOX08gPSAnTC1pbmRleF9pbnN0YWxsX2NhbGxfcGx1c19wbHVnaW4tTycsXG4gIC8qKlxuICAgKiDkuJrliqHlsYLkuovku7bms6jlhoxcbiAgICovXG4gIExfQ0FMTFBMVVNfQ0xJRU5UX1NFVF9FVkVOVF9MSVNURU5FUl9PID0gJ0wtY2FsbHBsdXNfY2xpZW50X3NldF9ldmVudF9saXN0ZW5lci1PJyxcbiAgLyoqXG4gICAqIOS4muWKoeWxguS6i+S7tuiwg+eUqFxuICAgKi9cbiAgTF9DQUxMUExVU19DTElFTlRfQ0FMTF9FVkVOVF9MSVNURU5FUl9PID0gJ0wtY2FsbHBsdXNfY2xpZW50X2NhbGxfZXZlbnRfbGlzdGVuZXItTycsXG4gIC8qKlxuICAgKiDpgJror53otKjph4/mlbDmja7nm5HlkKzms6jlhoxcbiAgICovXG4gIExfQ0FMTFBMVVNfQ0xJRU5UX1NFVF9TVEFUVVNfUkVQT1JUX0xJU1RFTkVSX08gPSAnTC1jYWxscGx1c19jbGllbnRfc2V0X3N0YXR1c19yZXBvcnRfbGlzdGVuZXItTycsXG4gIExfQ0FMTFBMVVNfQ0xJRU5UX0NBTExfU1RBVFVTX1JFUE9SVF9MSVNURU5FUl9PID0gJ0wtY2FsbHBsdXNfY2xpZW50X2NhbGxfc3RhdHVzX3JlcG9ydF9saXN0ZW5lci1PJyxcbiAgLyoqXG4gICAqIOiuvue9ruaRhOWDj+WktOinhumikemFjee9rumhuVxuICAgKi9cbiAgTF9DQUxMUExVU19DTElFTlRfU0VUX1ZJREVPX0NPTkZJR19UID0gJ0wtY2FsbHBsdXNfY2xpZW50X3NldF92aWRlb19jb25maWctVCcsXG4gIExfQ0FMTFBMVVNfQ0xJRU5UX1NFVF9WSURFT19DT05GSUdfUiA9ICdMLWNhbGxwbHVzX2NsaWVudF9zZXRfdmlkZW9fY29uZmlnLVInLFxuICBMX0NBTExQTFVTX1ZJREVPX0NPTkZJR19TRVRfRlJBTUVfUkFURV9PID0gJ0wtY2FsbHBsdXNfdmlkZW9fY29uZmlnX3NldF9mcmFtZV9yYXRlLU8nLFxuICBMX0NBTExQTFVTX1ZJREVPX0NPTkZJR19TRVRfUkVTT0xVVElPTl9PID0gJ0wtY2FsbHBsdXNfdmlkZW9fY29uZmlnX3NldF9yZXNvbHV0aW9uLU8nLFxuICBMX0NBTExQTFVTX1ZJREVPX0NPTkZJR19TRVRfQklUUkFURV9PID0gJ0wtY2FsbHBsdXNfdmlkZW9fY29uZmlnX3NldF9iaXRyYXRlLU8nLFxuICAvKipcbiAgICog6K6+572u6bqm5YWL6aOO6Z+z6aKR6YWN572u6aG5XG4gICAqL1xuICBMX0NBTExQTFVTX0NMSUVOVF9TRVRfQVVESU9fQ09ORklHX1QgPSAnTC1jYWxscGx1c19jbGllbnRfc2V0X2F1ZGlvX2NvbmZpZy1UJyxcbiAgTF9DQUxMUExVU19DTElFTlRfU0VUX0FVRElPX0NPTkZJR19SID0gJ0wtY2FsbHBsdXNfY2xpZW50X3NldF9hdWRpb19jb25maWctUicsXG4gIExfQ0FMTFBMVVNfQVVESU9fQ09ORklHX1NFVF9CSVRSQVRFX08gPSAnTC1jYWxscGx1c19hdWRpb19jb25maWdfc2V0X2JpdHJhdGUtTycsXG4gIExfQ0FMTFBMVVNfQVVESU9fQ09ORklHX1NFVF9TQU1QTEVfUkFURV9PID0gJ0wtY2FsbHBsdXNfYXVkaW9fY29uZmlnX3NldF9zYW1wbGVfcmF0ZS1PJyxcbiAgLyoqXG4gICAqIOmihOiniFxuICAgKi9cbiAgTF9DQUxMUExVU19DTElFTlRfUFJFVklFV19UID0gJ0wtY2FsbHBsdXNfY2xpZW50X3ByZXZpZXctVCcsXG4gIExfQ0FMTFBMVVNfQ0xJRU5UX1BSRVZJRVdfUiA9ICdMLWNhbGxwbHVzX2NsaWVudF9wcmV2aWV3LVInLFxuICAvKipcbiAgICog5byA5aeL5ZG85Y+rXG4gICAqL1xuICBMX0NBTExQTFVTX0NMSUVOVF9TVEFSVF9DQUxMX1QgPSAnTC1jYWxscGx1c19jbGllbnRfc3RhcnRfY2FsbC1UJyxcbiAgTF9DQUxMUExVU19DTElFTlRfU1RBUlRfQ0FMTF9SID0gJ0wtY2FsbHBsdXNfY2xpZW50X3N0YXJ0X2NhbGwtUicsXG4gIC8qKlxuICAgKiDliqDlhaXpgJror53ku7vliqFcbiAgICovXG4gIExfQ0FMTFBMVVNfQ0xJRU5UX0pPSU5fTVVMVElfQ0FMTF9UID0gJ0wtY2FsbHBsdXNfY2xpZW50X2pvaW5fbXVsdGlfY2FsbC1UJyxcbiAgLyoqXG4gICAqIOWKoOWFpemAmuivnee7k+aenFxuICAgKi9cbiAgTF9DQUxMUExVU19DTElFTlRfSk9JTl9NVUxUSV9DQUxMX1IgPSAnTC1jYWxscGx1c19jbGllbnRfam9pbl9tdWx0aV9jYWxsLVInLFxuICAvKipcbiAgICog5o6l5ZCs6YCa6K+d5Lu75YqhXG4gICAqL1xuICBMX0NBTExQTFVTX0NMSUVOVF9BQ0NFUFRfVCA9ICdMLWNhbGxwbHVzX2NsaWVudF9hY2NlcHQtVCcsXG4gIC8qKlxuICAgKiDmjqXlkKzpgJror53nu5PmnpxcbiAgICovXG4gIExfQ0FMTFBMVVNfQ0xJRU5UX0FDQ0VQVF9SID0gJ0wtY2FsbHBsdXNfY2xpZW50X2FjY2VwdC1SJyxcbiAgLyoqXG4gICAqIOaMguaWrVxuICAgKi9cbiAgTF9DQUxMUExVU19DTElFTlRfSEFOR1VQX1QgPSAnTC1jYWxscGx1c19jbGllbnRfaGFuZ3VwLVQnLFxuICBMX0NBTExQTFVTX0NMSUVOVF9IQU5HVVBfUiA9ICdMLWNhbGxwbHVzX2NsaWVudF9oYW5ndXAtUicsXG4gIC8qKlxuICAgKiDpgoDor7dcbiAgICovXG4gIExfQ0FMTFBMVVNfQ0xJRU5UX0lOVklURV9UID0gJ0wtY2FsbHBsdXNfY2xpZW50X2ludml0ZS1UJyxcbiAgTF9DQUxMUExVU19DTElFTlRfSU5WSVRFX1IgPSAnTC1jYWxscGx1c19jbGllbnRfaW52aXRlLVInLFxuICAvKipcbiAgICog5Y+R6LW35aqS5L2T57G75Z6L5YiH5o2i6K+35rGCXG4gICAqL1xuICBMX0NBTExQTFVTX0NMSUVOVF9SRVFVRVNUX0NIQU5HRV9NRURJQV9UWVBFX1QgPSAnTC1jYWxscGx1c19jbGllbnRfcmVxdWVzdF9jaGFuZ2VfbWVkaWFfdHlwZS1UJyxcbiAgTF9DQUxMUExVU19DTElFTlRfUkVRVUVTVF9DSEFOR0VfTUVESUFfVFlQRV9SID0gJ0wtY2FsbHBsdXNfY2xpZW50X3JlcXVlc3RfY2hhbmdlX21lZGlhX3R5cGUtUicsXG4gIC8qKlxuICAgKiDlj5bmtojlqpLkvZPnsbvlnovliIfmjaLor7fmsYJcbiAgICovXG4gIExfQ0FMTFBMVVNfQ0xJRU5UX0NBTkNFTF9DSEFOR0VfTUVESUFfVFlQRV9UID0gJ0wtY2FsbHBsdXNfY2xpZW50X2NhbmNlbF9jaGFuZ2VfbWVkaWFfdHlwZS1UJyxcbiAgTF9DQUxMUExVU19DTElFTlRfQ0FOQ0VMX0NIQU5HRV9NRURJQV9UWVBFX1IgPSAnTC1jYWxscGx1c19jbGllbnRfY2FuY2VsX2NoYW5nZV9tZWRpYV90eXBlLVInLFxuICAvKipcbiAgICog5aqS5L2T57G75Z6L5YiH5o2i5bqU562UXG4gICAqL1xuICBMX0NBTExQTFVTX0NMSUVOVF9SRVBMWV9DSEFOR0VfTUVESUFfVFlQRV9UID0gJ0wtY2FsbHBsdXNfY2xpZW50X3JlcGx5X2NoYW5nZV9tZWRpYV90eXBlLVQnLFxuICBMX0NBTExQTFVTX0NMSUVOVF9SRVBMWV9DSEFOR0VfTUVESUFfVFlQRV9SID0gJ0wtY2FsbHBsdXNfY2xpZW50X3JlcGx5X2NoYW5nZV9tZWRpYV90eXBlLVInLFxuICAvKipcbiAgICog6I635Y+W5b2T5YmN6L+b6KGM5Lit55qE6YCa6K+d5Lu75YqhXG4gICAqL1xuICBMX0NBTExQTFVTX0NMSUVOVF9HRVRfQ1VSUkVOVF9DQUxMX1NFU1NJT05fVCA9ICdMLWNhbGxwbHVzX2NsaWVudF9nZXRfY3VycmVudF9jYWxsX3Nlc3Npb24tVCcsXG4gIExfQ0FMTFBMVVNfQ0xJRU5UX0dFVF9DVVJSRU5UX0NBTExfU0VTU0lPTl9SID0gJ0wtY2FsbHBsdXNfY2xpZW50X2dldF9jdXJyZW50X2NhbGxfc2Vzc2lvbi1SJyxcbiAgLyoqXG4gICAqIOiOt+WPluacque7k+adn+eahOmAmuivneWIl+ihqFxuICAgKiBBdmFpbGFibGVDYWxsU2Vzc2lvbnNGcm9tU2VydmVyXG4gICAqL1xuICBMX0NBTExQTFVTX0NMSUVOVF9HRVRfQVZBSUxBQkxFX0NBTExfUkVDT1JEU19GUk9NX1NFUlZFUl9UID0gJ0wtY2FsbHBsdXNfY2xpZW50X2dldF9hdmFpbGFibGVfY2FsbF9zZXNzaW9uc19mcm9tX3NlcnZlci1UJyxcbiAgTF9DQUxMUExVU19DTElFTlRfR0VUX0FWQUlMQUJMRV9DQUxMX1JFQ09SRFNfRlJPTV9TRVJWRVJfUiA9ICdMLWNhbGxwbHVzX2NsaWVudF9nZXRfYXZhaWxhYmxlX2NhbGxfc2Vzc2lvbnNfZnJvbV9zZXJ2ZXItUicsXG4gIC8qKlxuICAgKiDojrflj5bpgJror53orrDlvZVcbiAgICovXG4gIExfQ0FMTFBMVVNfQ0xJRU5UX0dFVF9DQUxMX1JFQ09SRFNfVCA9ICdMLWNhbGxwbHVzX2NsaWVudF9nZXRfY2FsbF9yZWNvcmRzLVQnLFxuICBMX0NBTExQTFVTX0NMSUVOVF9HRVRfQ0FMTF9SRUNPUkRTX1IgPSAnTC1jYWxscGx1c19jbGllbnRfZ2V0X2NhbGxfcmVjb3Jkcy1SJyxcbiAgLyoqXG4gICAqIOagueaNriBjYWxsSWQg5riF55CG6YCa6K+d6K6w5b2VXG4gICAqL1xuICBMX0NBTExQTFVTX0NMSUVOVF9ERUxFVEVfQ0FMTF9SRUNPUkRTX0JZX0NBTExJRF9UID0gJ0wtY2FsbHBsdXNfY2xpZW50X2RlbGV0ZV9jYWxsX3JlY29yZHNfYnlfY2FsbElkLVQnLFxuICBMX0NBTExQTFVTX0NMSUVOVF9ERUxFVEVfQ0FMTF9SRUNPUkRTX0JZX0NBTExJRF9SID0gJ0wtY2FsbHBsdXNfY2xpZW50X2RlbGV0ZV9jYWxsX3JlY29yZHNfYnlfY2FsbElkLVInLFxuICAvKipcbiAgICog5riF55CG5omA5pyJ6YCa6K+d6K6w5b2VXG4gICAqL1xuICBMX0NBTExQTFVTX0NMSUVOVF9ERUxFVEVfQUxMX0NBTExfUkVDT1JEU19GUk9NX1NFUlZFUl9UID0gJ0wtY2FsbHBsdXNfY2xpZW50X2RlbGV0ZV9hbGxfY2FsbF9yZWNvcmRzX2Zyb21fc2VydmVyLVQnLFxuICBMX0NBTExQTFVTX0NMSUVOVF9ERUxFVEVfQUxMX0NBTExfUkVDT1JEU19GUk9NX1NFUlZFUl9SID0gJ0wtY2FsbHBsdXNfY2xpZW50X2RlbGV0ZV9hbGxfY2FsbF9yZWNvcmRzX2Zyb21fc2VydmVyLVInLFxuICAvKipcbiAgICog5omT5byA5pGE5YOP5aS0XG4gICAqL1xuICBMX0NBTExQTFVTX0NMSUVOVF9TVEFSVF9DQU1FUkFfVCA9ICdMLWNhbGxwbHVzX2NsaWVudF9zdGFydF9jYW1lcmEtVCcsXG4gIExfQ0FMTFBMVVNfQ0xJRU5UX1NUQVJUX0NBTUVSQV9SID0gJ0wtY2FsbHBsdXNfY2xpZW50X3N0YXJ0X2NhbWVyYS1SJyxcbiAgLyoqXG4gICAqIOWFs+mXreaRhOWDj+WktFxuICAgKi9cbiAgTF9DQUxMUExVU19DTElFTlRfU1RPUF9DQU1FUkFfVCA9ICdMLWNhbGxwbHVzX2NsaWVudF9zdG9wX2NhbWVyYS1UJyxcbiAgTF9DQUxMUExVU19DTElFTlRfU1RPUF9DQU1FUkFfUiA9ICdMLWNhbGxwbHVzX2NsaWVudF9zdG9wX2NhbWVyYS1SJyxcbiAgLyoqXG4gICAqIOWIh+aNouaRhOWDj+WktFxuICAgKi9cbiAgTF9DQUxMUExVU19DTElFTlRfU1dJVENIX0NBTUVSQV9UID0gJ0wtY2FsbHBsdXNfY2xpZW50X3N3aXRjaF9jYW1lcmEtVCcsXG4gIExfQ0FMTFBMVVNfQ0xJRU5UX1NXSVRDSF9DQU1FUkFfUiA9ICdMLWNhbGxwbHVzX2NsaWVudF9zd2l0Y2hfY2FtZXJhLVInLFxuICAvKipcbiAgICog5omT5byA6bqm5YWL6aOOXG4gICAqL1xuICBMX0NBTExQTFVTX0NMSUVOVF9TVEFSVF9NSUNST1BIT05FX1QgPSAnTC1jYWxscGx1c19jbGllbnRfc3RhcnRfbWljcm9waG9uZS1UJyxcbiAgTF9DQUxMUExVU19DTElFTlRfU1RBUlRfTUlDUk9QSE9ORV9SID0gJ0wtY2FsbHBsdXNfY2xpZW50X3N0YXJ0X21pY3JvcGhvbmUtUicsXG4gIC8qKlxuICAgKiDlhbPpl63puqblhYvpo45cbiAgICovXG4gIExfQ0FMTFBMVVNfQ0xJRU5UX1NUT1BfTUlDUk9QSE9ORV9UID0gJ0wtY2FsbHBsdXNfY2xpZW50X3N0b3BfbWljcm9waG9uZS1UJyxcbiAgTF9DQUxMUExVU19DTElFTlRfU1RPUF9NSUNST1BIT05FX1IgPSAnTC1jYWxscGx1c19jbGllbnRfc3RvcF9taWNyb3Bob25lLVInLFxuICAvKipcbiAgICog6K6+572uIHZpZGVvIHZpZXdcbiAgICovXG4gIExfQ0FMTFBMVVNfQ0xJRU5UX1NFVF9WSURFT19WSUVXX1QgPSAnTC1jYWxscGx1c19jbGllbnRfc2V0X3ZpZGVvX3ZpZXctVCcsXG4gIExfQ0FMTFBMVVNfQ0xJRU5UX1NFVF9WSURFT19WSUVXX1IgPSAnTC1jYWxscGx1c19jbGllbnRfc2V0X3ZpZGVvX3ZpZXctUicsXG4gIExfUlRDX01PRFVMRV9TRVRfVklERU9fVklFV19PID0gJ0wtcnRjX21vZHVsZV9zZXRfdmlkZW9fdmlldy1PJyxcbiAgLyoqXG4gICAqIOWIoOmZpCB2aWRlbyB2aWV3XG4gICAqL1xuICBMX0NBTExQTFVTX0NMSUVOVF9SRU1PVkVfVklERU9fVklFV19UID0gJ0wtY2FsbHBsdXNfY2xpZW50X3JlbW92ZV92aWRlb192aWV3LVQnLFxuICBMX0NBTExQTFVTX0NMSUVOVF9SRU1PVkVfVklERU9fVklFV19SID0gJ0wtY2FsbHBsdXNfY2xpZW50X3JlbW92ZV92aWRlb192aWV3LVInLFxuICBMX1JUQ19NT0RVTEVfUkVNT1ZFX1ZJREVPX1ZJRVdfTyA9ICdMLXJ0Y19tb2R1bGVfcmVtb3ZlX3ZpZGVvX3ZpZXctTycsXG4gIC8qKlxuICAgKiDmkq3mlL7lqpLkvZNcbiAgICovXG4gIExfQ0FMTFBMVVNfQ0xJRU5UX1BMQVlfTUVESUFfVCA9ICdMLWNhbGxwbHVzX2NsaWVudF9wbGF5X21lZGlhLVQnLFxuICBMX0NBTExQTFVTX0NMSUVOVF9QTEFZX01FRElBX1IgPSAnTC1jYWxscGx1c19jbGllbnRfcGxheV9tZWRpYS1SJyxcbiAgTF9SVENfTU9EVUxFX1BMQVlfTUVESUFfVCA9ICdMLXJ0Y19tb2R1bGVfcGxheV9tZWRpYS1UJyxcbiAgTF9SVENfTU9EVUxFX1BMQVlfTUVESUFfUiA9ICdMLXJ0Y19tb2R1bGVfcGxheV9tZWRpYS1SJyxcbiAgLyoqXG4gICAqIOmdmemfs+i/nOerr+mfs+mikVxuICAgKi9cbiAgTF9SVENfTU9EVUxFX1NFVF9BTExfUkVNT1RFX0FVRElPX0VOQUJMRV9UID0gJ0wtcnRjX21vZHVsZV9zZXRfYWxsX3JlbW90ZV9hdWRpb19lbmJhbGUtVCcsXG4gIExfUlRDX01PRFVMRV9TRVRfQUxMX1JFTU9URV9BVURJT19FTkFCTEVfUiA9ICdMLXJ0Y19tb2R1bGVfc2V0X2FsbF9yZW1vdGVfYXVkaW9fZW5hYmxlLVInLFxuICAvKipcbiAgICog6K6i6ZiFXG4gICAqL1xuICBMX1JUQ19NT0RVTEVfU1VCU0NSSUJFX1QgPSAnTC1ydGNfbW9kdWxlX3N1YnNjcmliZS1UJyxcbiAgTF9SVENfTU9EVUxFX1NVQlNDUklCRV9SID0gJ0wtcnRjX21vZHVsZV9zdWJzY3JpYmUtUicsXG4gIC8qKlxuICAgKiDlj5bmtojorqLpmIVcbiAgICovXG4gIExfUlRDX01PRFVMRV9VTlNVQlNDUklCRV9UID0gJ0wtcnRjX21vZHVsZV91bnN1YnNjcmliZS1UJyxcbiAgTF9SVENfTU9EVUxFX1VOU1VCU0NSSUJFX1IgPSAnTC1ydGNfbW9kdWxlX3Vuc3Vic2NyaWJlLVInLFxuICAvKipcbiAgICog5Li75Yqo5Y+R5biDXG4gICAqL1xuICBMX1JUQ19NT0RVTEVfUFVCTElTSF9UID0gJ0wtcnRjX21vZHVsZV9wdWJsaXNoLVQnLFxuICBMX1JUQ19NT0RVTEVfUFVCTElTSF9SID0gJ0wtcnRjX21vZHVsZV9wdWJsaXNoLVInLFxuICAvKipcbiAgICog5Y+W5raI5Y+R5biDXG4gICAqL1xuICBMX1JUQ19NT0RVTEVfVU5QVUJMSVNIX1QgPSAnTC1ydGNfbW9kdWxlX3VucHVibGlzaC1UJyxcbiAgTF9SVENfTU9EVUxFX1VOUFVCTElTSF9SID0gJ0wtcnRjX21vZHVsZV91bnB1Ymxpc2gtUicsXG4gIC8qKlxuICAgKiDplIDmr4HmiYDmnInpn7Pop4bpopHotYTmupBcbiAgICovXG4gIExfUlRDX01PRFVMRV9ERVNUUk9ZX0FMTF9UUkFDS1NfTyA9ICdMLXJ0Y19tb2R1bGVfZGVzdHJveV9hbGxfdHJhY2tzLU8nLFxuICAvKipcbiAgICogc2Vzc2lvbiDlu7rnq4vlkI4gUlRDIOaooeWdl+eahOWkhOeQhlxuICAgKi9cbiAgTF9SVENfTU9EVUxFX1NFU1NJT05fQ09OTkVDVF9UID0gJ0wtcnRjX21vZHVsZV9zZXNzaW9uX2Nvbm5lY3QtVCcsXG4gIExfUlRDX01PRFVMRV9TRVNTSU9OX0NPTk5FQ1RfUCA9ICdMLXJ0Y19tb2R1bGVfc2Vzc2lvbl9jb25uZWN0LVAnLFxuICBMX1JUQ19NT0RVTEVfU0VTU0lPTl9DT05ORUNUX1IgPSAnTC1ydGNfbW9kdWxlX3Nlc3Npb25fY29ubmVjdC1SJyxcbiAgLyoqXG4gICAqIHNlc3Npb24g57uT5p2f5ZCOIFJUQyDmqKHlnZfnmoTlpITnkIZcbiAgICovXG4gIExfUlRDX01PRFVMRV9TRVNTSU9OX0NMT1NFX1QgPSAnTC1ydGNfbW9kdWxlX3Nlc3Npb25fY2xvc2UtVCcsXG4gIExfUlRDX01PRFVMRV9TRVNTSU9OX0NMT1NFX1AgPSAnTC1ydGNfbW9kdWxlX3Nlc3Npb25fY2xvc2UtUCcsXG4gIExfUlRDX01PRFVMRV9TRVNTSU9OX0NMT1NFX1IgPSAnTC1ydGNfbW9kdWxlX3Nlc3Npb25fY2xvc2UtUicsXG4gIC8qKlxuICAgKiDliJvlu7rop4bpopHotYTmupBcbiAgICovXG4gIExfUlRDX01PRFVMRV9DUkVBVEVfVklERU9fVFJBQ0tfVCA9ICdMLXJ0Y19tb2R1bGVfY3JlYXRlX3ZpZGVvX3RyYWNrLVQnLFxuICBMX1JUQ19NT0RVTEVfQ1JFQVRFX1ZJREVPX1RSQUNLX1IgPSAnTC1ydGNfbW9kdWxlX2NyZWF0ZV92aWRlb190cmFjay1SJyxcbiAgLyoqXG4gICAqIOWIm+W7uumfs+mikei1hOa6kFxuICAgKi9cbiAgTF9SVENfTU9EVUxFX0NSRUFURV9BVURJT19UUkFDS19UID0gJ0wtcnRjX21vZHVsZV9jcmVhdGVfYXVkaW9fdHJhY2stVCcsXG4gIExfUlRDX01PRFVMRV9DUkVBVEVfQVVESU9fVFJBQ0tfUiA9ICdMLXJ0Y19tb2R1bGVfY3JlYXRlX2F1ZGlvX3RyYWNrLVInLFxuICAvKipcbiAgICog5pS25Yiw6LWE5rqQ5Y+R5biDXG4gICAqL1xuICBMX1JUQ19NT0RVTEVfUkVDRUlWRV9UUkFDS19QVUJMSVNIX08gPSAnTC1ydGNfbW9kdWxlX3JlY2VpdmVfdHJhY2tfcHVibGlzaC1PJyxcbiAgLyoqXG4gICAqIOaUtuWIsOi1hOa6kOWPlua2iOWPkeW4g1xuICAgKi9cbiAgTF9SVENfTU9EVUxFX1JFQ0VJVkVfVFJBQ0tfVU5QVUJMSVNIX08gPSAnTC1ydGNfbW9kdWxlX3JlY2VpdmVfdHJhY2tfdW5wdWJsaXNoLU8nLFxuICAvKipcbiAgICog5pS25Yiw6LWE5rqQ54q25oCB5Y+Y5pu0XG4gICAqL1xuICBMX1JUQ19NT0RVTEVfUkVDRUlWRV9UUkFDS19FTkFCTEVfQ0hBTkdFX08gPSAnTC1ydGNfbW9kdWxlX3JlY2VpdmVfdHJhY2tfZW5hYmxlX2NoYW5nZS1PJyxcbiAgLyoqXG4gICAqIOaUtuWIsOiiq+i4ouWHuuaIv+mXtFxuICAgKi9cbiAgTF9SVENfTU9EVUxFX1JFQ0VJVkVfS0lDS19PRkZfTyA9ICdMLXJ0Y19tb2R1bGVfcmVjZWl2ZV9raWNrX29mZi1PJyxcbiAgLyoqXG4gICAqIOaUtuWIsCBwZWVyY29ubmVjdGlvbiDlvILluLjlhbPpl61cbiAgICovXG4gIExfUlRDX01PRFVMRV9SRUNFSVZFX1BFRVJDT05ORUNUSU9OX0VYQ0VQVF9DTE9TRV9PID0gJ0wtcnRjX21vZHVsZV9yZWNlaXZlX3BlZXJjb25uZWN0aW9uX2V4Y2VwdF9jbG9zZS1PJyxcbiAgLyoqXG4gICAqIOWIh+aNouWqkuS9k+exu+Wei1xuICAgKi9cbiAgTF9SVENfTU9EVUxFX0NIQU5HRV9NRURJQV9UWVBFX1QgPSAnTC1ydGNfbW9kdWxlX2NoYW5nZV9tZWRpYV90eXBlLVQnLFxuICBMX1JUQ19NT0RVTEVfQ0hBTkdFX01FRElBX1RZUEVfUiA9ICdMLXJ0Y19tb2R1bGVfY2hhbmdlX21lZGlhX3R5cGUtUicsXG4gIC8qKlxuICAgKiDliqDlhaXmiL/pl7RcbiAgICovXG4gIExfUlRDX01PRFVMRV9KT0lOX1JUQ19ST09NX1QgPSAnTC1ydGNfbW9kdWxlX2pvaW5fcnRjX3Jvb20tVCcsXG4gIExfUlRDX01PRFVMRV9KT0lOX1JUQ19ST09NX1IgPSAnTC1ydGNfbW9kdWxlX2pvaW5fcnRjX3Jvb20tUicsXG4gIC8qKlxuICAgKiDpgIDlh7rmiL/pl7RcbiAgICovXG4gIExfUlRDX01PRFVMRV9RVUlUX1JUQ19ST09NX1QgPSAnTC1ydGNfbW9kdWxlX3F1aXRfcnRjX3Jvb20tVCcsXG4gIExfUlRDX01PRFVMRV9RVUlUX1JUQ19ST09NX1IgPSAnTC1ydGNfbW9kdWxlX3F1aXRfcnRjX3Jvb20tUicsXG5cbiAgLy8gc2lnbmFsIOaooeWdl+aXpeW/l+agh+etvlxuICAvKipcbiAgICog5byA5aeL5ZG85Y+rXG4gICAqL1xuICBMX1NJR05BTF9UUkFOU1BPUlRFUl9TSU5HTEVfQ0FMTF9UID0gJ0wtc2lnbmFsX3RyYW5zcG9ydGVyX3NpbmdsZV9jYWxsLVQnLFxuICBMX1NJR05BTF9UUkFOU1BPUlRFUl9HUk9VUF9DQUxMX1QgPSAnTC1zaWduYWxfdHJhbnNwb3J0ZXJfZ3JvdXBfY2FsbC1UJyxcbiAgLyoqXG4gICAqIOmCgOivt1xuICAgKi9cbiAgTF9TSUdOQUxfVFJBTlNQT1JURVJfSU5WSVRFX1QgPSAnTC1zaWduYWxfdHJhbnNwb3J0ZXJfaW52aXRlLVQnLFxuICAvKipcbiAgICog5ZON6ZODXG4gICAqL1xuICBMX1NJR05BTF9UUkFOU1BPUlRFUl9SSU5HX1QgPSAnTC1zaWduYWxfdHJhbnNwb3J0ZXJfcmluZy1UJyxcbiAgLyoqXG4gICAqIOaOpeWQrFxuICAgKi9cbiAgTF9TSUdOQUxfVFJBTlNQT1JURVJfQUNDRVBUX1QgPSAnTC1zaWduYWxfdHJhbnNwb3J0ZXJfYWNjZXB0LVQnLFxuICBMX1NJR05BTF9UUkFOU1BPUlRFUl9BQ0NFUFRfUiA9ICdMLXNpZ25hbF90cmFuc3BvcnRlcl9hY2NlcHQtUicsXG4gIC8qKlxuICAgKiDliqDlhaXpgJror51cbiAgICovXG4gIExfU0lHTkFMX1RSQU5TUE9SVEVSX0pPSU5fQ0FMTF9UID0gJ0wtc2lnbmFsX3RyYW5zcG9ydGVyX2pvaW5fY2FsbC1UJyxcbiAgLyoqXG4gICAqIOaMguaWremAmuivnVxuICAgKi9cbiAgTF9TSUdOQUxfVFJBTlNQT1JURVJfSEFOR1VQX1QgPSAnTC1zaWduYWxfdHJhbnNwb3J0ZXJfaGFuZ3VwLVQnLFxuICAvKipcbiAgICog6YCa6K+d54q25oCB5LiK5oqlXG4gICAqL1xuICBMX1NJR05BTF9UUkFOU1BPUlRFUl9DQUxMX1NUQVRVU19VUF9UID0gJ0wtc2lnbmFsX3RyYW5zcG9ydGVyX2NhbGxfc3RhdHVzX3VwLVQnLFxuICAvKipcbiAgICog6YCa6K+d5LqL5Lu25LiK5oqlXG4gICAqL1xuICBMX1NJR05BTF9UUkFOU1BPUlRFUl9DQUxMX0VWRU5UX1VQX1QgPSAnTC1zaWduYWxfdHJhbnNwb3J0ZXJfY2FsbF9ldmVudF91cC1UJyxcbiAgLyoqXG4gICAqIOmAmuivneWvueivneS6i+S7tuS4iuaKpVxuICAgKi9cbiAgTF9TSUdOQUxfVFJBTlNQT1JURVJfQ0FMTF9ESUFMT0dfVVBfVCA9ICdMLXNpZ25hbF90cmFuc3BvcnRlcl9jYWxsX2RpYWxvZ191cC1UJyxcbiAgLyoqXG4gICAqIOWIoOmZpOmAmuivneiusOW9lVxuICAgKi9cbiAgTF9TSUdOQUxfVFJBTlNQT1JURVJfREVMRVRFX0NBTExfUkVDT1JEX1QgPSAnTC1zaWduYWxfdHJhbnNwb3J0ZXJfZGVsZXRlX2NhbGxfcmVjb3JkLVQnLFxuICAvKipcbiAgICog6I635Y+W6YCa6K+d6K6w5b2VXG4gICAqL1xuICBMX1NJR05BTF9UUkFOU1BPUlRFUl9HRVRfQ0FMTF9SRUNPUkRfVCA9ICdMLXNpZ25hbF90cmFuc3BvcnRlcl9nZXRfY2FsbF9yZWNvcmQtVCcsXG4gIC8qKlxuICAgKiDmn6Xor6IgY2FsbCBzZXJ2ZXIg5b2T5YmN5pe26Ze05oizXG4gICAqL1xuICBMX1NJR05BTF9UUkFOU1BPUlRFUl9HRVRfQ0FMTF9TRVJWRVJfVElNRV9UID0gJ0wtc2lnbmFsX3RyYW5zcG9ydGVyX2dldF9jYWxsX3NlcnZlcl90aW1lLVQnLFxuICAvKipcbiAgICog6I635Y+W5oyH5a6a6YCa6K+d55qE5pe26Ze05L+h5oGvXG4gICAqL1xuICBMX1NJR05BTF9UUkFOU1BPUlRFUl9HRVRfQ0FMTF9USU1FX0lORk9fVCA9ICdMLXNpZ25hbF90cmFuc3BvcnRlcl9nZXRfY2FsbF90aW1lX2luZm8tVCcsXG4gIC8qKlxuICAgKiDojrflj5bnlKjmiLfmnKrnu5PmnZ/nmoTpgJror53liJfooajkv6Hmga9cbiAgICovXG4gIExfU0lHTkFMX1RSQU5TUE9SVEVSX0dFVF9BVkFJTEFCTEVfQ0FMTF9MSVNUX1QgPSAnTC1zaWduYWxfdHJhbnNwb3J0ZXJfZ2V0X2F2YWlsYWJsZV9jYWxsX2xpc3QtVCcsXG4gIC8qKlxuICAgKiDmuIXpmaTpgJror53orrDlvZVcbiAgICovXG4gIExfU0lHTkFMX1RSQU5TUE9SVEVSX0NMRUFSX0NBTExfUkVDT1JEX1QgPSAnTC1zaWduYWxfdHJhbnNwb3J0ZXJfY2xlYXJfY2FsbF9yZWNvcmQtVCcsXG4gIC8qKlxuICAgKiDmoLnmja4gY2FsbElkIOiOt+WPlumAmuivneS/oeaBr1xuICAgKi9cbiAgTF9TSUdOQUxfVFJBTlNQT1JURVJfR0VUX0NBTExfSU5GT19CWV9DQUxMSURfVCA9ICdMLXNpZ25hbF90cmFuc3BvcnRlcl9nZXRfY2FsbF9pbmZvX2J5X2NhbGxJZC1UJyxcbiAgLyoqXG4gICAqIOeUqOaIt+ezu+e7n+eKtuaAgeS4iuaKpVxuICAgKi9cbiAgTF9TSUdOQUxfVFJBTlNQT1JURVJfVVNFUl9TWVNURU1fU1RBVEVfVVBfVCA9ICdMLXNpZ25hbF90cmFuc3BvcnRlcl91c2VyX3N5c3RlbV9zdGF0ZV91cC1UJyxcbiAgLyoqXG4gICAqIOaUtuWIsCBjYWxsIHNpZ25hbCDmtojmga9cbiAgICovXG4gIExfU0lHTkFMX1RSQU5TUE9SVEVSX1JFQ0VJVkVfQ0FMTF9TSUdOQUxfREFUQV9PID0gJ0wtc2lnbmFsX3RyYW5zcG9ydGVyX3JlY2VpdmVfY2FsbF9zaWduYWxfZGF0YS1PJyxcbiAgLyoqXG4gICAqIGltIOeKtuaAgeWPmOWMllxuICAgKi9cbiAgTF9TSUdOQUxfVFJBTlNQT1JURVJfSU1fU1RBVEVfQ0hBTkdFX08gPSAnTC1zaWduYWxfdHJhbnNwb3J0ZXJfaW1fc3RhdGVfY2hhbmdlLU8nLFxuICAvKipcbiAgICog5pS25Yiw6YCa6K+d6YKA6K+3XG4gICAqL1xuICBMX1NJR05BTF9UUkFOU1BPUlRFUl9SRUNFSVZFX0lOVklURV9PID0gJ0wtc2lnbmFsX3RyYW5zcG9ydGVyX3JlY2VpdmVfaW52aXRlLU8nLFxuICAvKipcbiAgICog5pS25Yiw6YCa6K+d54q25oCB5Y+Y5pu0XG4gICAqL1xuICBMX1NJR05BTF9UUkFOU1BPUlRFUl9SRUNFSVZFX0NBTExfU1RBVFVTX08gPSAnTC1zaWduYWxfdHJhbnNwb3J0ZXJfcmVjZWl2ZV9jYWxsX3N0YXR1cy1PJyxcbiAgLyoqXG4gICAqIGNhbGwgZW5naW5lIOabtOaWsOS6uuWRmOeKtuaAgVxuICAgKi9cbiAgTF9DQUxMX0VOR0lORV9VUERBVEVfVVNFUlNfU1RBVEVfTyA9ICdMLWNhbGxfZW5naW5lX3VwZGF0ZV91c2Vyc19zdGF0ZS1PJyxcbiAgLyoqXG4gICAqIGltIOeKtuaAgeWPmOabtFxuICAgKi9cbiAgTF9DQUxMX0VOR0lORV9JTV9TVEFURV9DSEFOR0VfTyA9ICdMLWNhbGxfZW5naW5lX2ltX3N0YXRlX2NoYW5nZS1PJyxcbiAgLyoqXG4gICAqIOWPkei1t+WRvOWPq+OAgeaUtuWIsOmCgOivt+i2heaXtlxuICAgKi9cbiAgTF9DQUxMX0VOR0lORV9DQUxMX1RJTUVPVVRfTyA9ICdMLWNhbGxfZW5naW5lX2NhbGxfdGltZW91dC1PJyxcbiAgLyoqXG4gICAqIOW8gOWQr+mAmuivneWumuaXtuWZqFxuICAgKi9cbiAgTF9DQUxMX0VOR0lORV9TVEFSVF9DQUxMX1RJTUVSX08gPSAnTC1jYWxsX2VuZ2luZV9zdGFydF9jYWxsX3RpbWVyLU8nLFxuICAvKipcbiAgICog5riF6Zmk6YCa6K+d5a6a5pe25ZmoXG4gICAqL1xuICBMX0NBTExfRU5HSU5FX1NUT1BfQ0FMTF9USU1FUl9PID0gJ0wtY2FsbF9lbmdpbmVfc3RvcF9jYWxsX3RpbWVyLU8nLFxuICAvKipcbiAgICog5LiK5oqlIG9uUGhvbmVFbmRcbiAgICovXG4gIExfQ0FMTF9FTkdJTkVfVVBfT05fUEhPTkVfRU5EX1QgPSAnTC1jYWxsX2VuZ2luZV91cF9vbl9waG9uZV9lbmQtVCcsXG4gIExfQ0FMTF9FTkdJTkVfVVBfT05fUEhPTkVfRU5EX1IgPSAnTC1jYWxsX2VuZ2luZV91cF9vbl9waG9uZV9lbmQtUicsXG4gIC8qKlxuICAgKiDmlLbliLDpppbluKfml7bpl7TkuIvlj5FcbiAgICovXG4gIExfQ0FMTF9FTkdJTkVfUkVDRUlWRV9GSVJTVF9GUkFNRV9USU1FX08gPSAnTC1jYWxsX2VuZ2luZV9yZWNlaXZlX2ZpcnN0X2ZyYW1lX3RpbWUtTycsXG4gIC8qKlxuICAgKiDmlLbliLDlqpLkvZPnsbvlnovliIfmjaLkuovku7ZcbiAgICovXG4gIExfQ0FMTF9FTkdJTkVfUkVDRUlWRV9NRURJQVRZUEVfQ0hBTkdFX08gPSAnTC1jYWxsX2VuZ2luZV9yZWNlaXZlX21lZGlhdHlwZV9jaGFuZ2UtTycsXG4gIC8qKlxuICAgKiDmlLbliLDpgJror53nu5PmnZ9cbiAgICovXG4gIExfQ0FMTF9FTkdJTkVfUkVDRUlWRV9DTE9TRV9TRVNTSU9OX08gPSAnTC1jYWxsX2VuZ2luZV9yZWNlaXZlX2Nsb3NlX3Nlc3Npb24tTycsXG4gIC8qKlxuICAgKiDmlLbliLDpgJror53ml6Xlv5dcbiAgICovXG4gIExfQ0FMTF9FTkdJTkVfUkVDRUlWRV9DQUxMX1JFQ09SRF9PID0gJ0wtY2FsbF9lbmdpbmVfcmVjZWl2ZV9jYWxsX3JlY29yZC1PJyxcbiAgLyoqXG4gICAqIOaUtuWIsOihpeWBv+aVsOaNrlxuICAgKi9cbiAgTF9DQUxMX0VOR0lORV9SRUNFSVZFX0NPTVBMRU1FTlRBUllfREFUQV9PID0gJ0wtY2FsbF9lbmdpbmVfcmVjZWl2ZV9jb21wbGVtZW50YXJ5X2RhdGEtTycsXG4gIC8qKlxuICAgKiDliJvlu7ogc2Vzc2lvblxuICAgKi9cbiAgTF9DQUxMX0VOR0lORV9DUkVBVEVfU0VTU0lPTl9CWV9TRVJWRVJfVCA9ICdMLWNhbGxfZW5naW5lX2NyZWF0ZV9zZXNzaW9uX2J5X3NlcnZlci1UJyxcbiAgTF9DQUxMX0VOR0lORV9DUkVBVEVfU0VTU0lPTl9CWV9TRVJWRVJfUiA9ICdMLWNhbGxfZW5naW5lX2NyZWF0ZV9zZXNzaW9uX2J5X3NlcnZlci1SJyxcbiAgLyoqXG4gICAqIOS4iuaKpemmluW4p+aXtumXtFxuICAgKi9cbiAgTF9DQUxMX0VOR0lORV9VUF9GSVJTVF9GUkFNRV9USU1FX1QgPSAnTC1jYWxsX2VuZ2luZV91cF9maXJzdF9mcmFtZV90aW1lLVQnLFxuICBMX0NBTExfRU5HSU5FX1VQX0ZJUlNUX0ZSQU1FX1RJTUVfUiA9ICdMLWNhbGxfZW5naW5lX3VwX2ZpcnN0X2ZyYW1lX3RpbWUtUicsXG4gIC8qKlxuICAgKiDlvIDlkK/ml7bpl7TmoKHmraNcbiAgICovXG4gIExfVElNRV9DT1JSRUNUX1NUQVJUX08gPSAnTC10aW1lX2NvcnJlY3Rfc3RhcnQtTycsXG4gIC8qKlxuICAgKiDlgZzmraLmoKHml7ZcbiAgICovXG4gIExfVElNRV9DT1JSRUNUX1NUT1BfTyA9ICdMLXRpbWVfY29ycmVjdF9zdG9wLU8nLFxuICAvKipcbiAgICog6YeN5paw5byA5ZCv5qCh5pe2XG4gICAqL1xuICBMX1RJTUVfQ09SUkVDVF9SRVNUQVJUX08gPSAnTC10aW1lX2NvcnJlY3RfcmVzdGFydC1PJyxcbiAgLyoqXG4gICAqIOS7juacjeWKoeerr+iOt+WPlumAmuivneaXtumVv+OAgemAmuivneW8gOWni+aXtumXtFxuICAgKi9cbiAgTF9USU1FX0NPUlJFQ1RfR0VUX0NBTExfQ0xJRU5UX1RJTUVfQllfU0VSVkVSX1QgPSAnTC10aW1lX2NvcnJlY3RfZ2V0X2NhbGxfY2xpZW50X3RpbWVfYnlfc2VydmVyLVQnLFxuICBMX1RJTUVfQ09SUkVDVF9HRVRfQ0FMTF9DTElFTlRfVElNRV9CWV9TRVJWRVJfUCA9ICdMLXRpbWVfY29ycmVjdF9nZXRfY2FsbF9jbGllbnRfdGltZV9ieV9zZXJ2ZXItUCcsXG4gIExfVElNRV9DT1JSRUNUX0dFVF9DQUxMX0NMSUVOVF9USU1FX0JZX1NFUlZFUl9SID0gJ0wtdGltZV9jb3JyZWN0X2dldF9jYWxsX2NsaWVudF90aW1lX2J5X3NlcnZlci1SJyxcbiAgLyoqXG4gICAqIOiuoeeul+WuouaIt+err+W8gOWni+aXtumXtFxuICAgKi9cbiAgTF9USU1FX0NPUlJFQ1RfQ0FMQ19DTElFTlRfU1RBUlRfVElNRV9UID0gJ0wtdGltZV9jb3JyZWN0X2NhbGNfY2xpZW50X3N0YXJ0X3RpbWUtVCcsXG4gIExfVElNRV9DT1JSRUNUX0NBTENfQ0xJRU5UX1NUQVJUX1RJTUVfUiA9ICdMLXRpbWVfY29ycmVjdF9jYWxjX2NsaWVudF9zdGFydF90aW1lLVInLFxuICAvKipcbiAgICog5a2Y5YKo5a6i5oi356uv5ZKM5pyN5Yqh56uv5pe26Ze05YGP5beuXG4gICAqL1xuICBMX1RJTUVfQ09SUkVDVF9TRVRfREVMVEFfVElNRV9PID0gJ0wtdGltZV9jb3JyZWN0X3NldF9kZWx0YV90aW1lLU8nLFxuICAvKipcbiAgICog5b6q546v5LiJ5qyh5qCh5q2j57uZ5a6i5oi356uv55qE5pe26Ze0XG4gICAqL1xuICBMX1RJTUVfQ09SUkVDVF9MT09QX0NPUlJFQ1RfQ0xJTkVUX1RJTUVfVCA9ICdMLXRpbWVfY29ycmVjdF9sb29wX2NvcnJlY3RfY2xpZW50X3RpbWUtVCcsXG4gIExfVElNRV9DT1JSRUNUX0xPT1BfQ09SUkVDVF9DTElORVRfVElNRV9SID0gJ0wtdGltZV9jb3JyZWN0X2xvb3BfY29ycmVjdF9jbGllbnRfdGltZS1SJyxcbiAgLyoqXG4gICAqIHNlc3Npb24g5YaF6YOo5pu05paw5Lq65ZGY54q25oCBXG4gICAqL1xuICBMX0lOTkVSX1NFU1NJT05fVVBEQVRFX1VTRVJfU1RBVEVfTyA9ICdMLWlubmVyX3Nlc3Npb25fdXBkYXRlX3VzZXJfc3RhdGUtTycsXG4gIC8qKlxuICAgKiDorr7nva4gc2Vzc2lvbiDkurrlkZjorr7lpIfnirbmgIFcbiAgICovXG4gIExfSU5ORVJfU0VTU0lPTl9TRVRfVVNFUl9ERVZJQ0VfRU5BQkxFX08gPSAnTC1pbm5lcl9zZXNzaW9uX3NldF91c2VyX2RldmljZV9lbmFibGUtTycsXG4gIC8qKlxuICAgKiDojrflj5bpgJror53lvIDlp4vml7bpl7RcbiAgICovXG4gIExfQ0FMTF9QTFVTX1NFU1NJT05fR0VUX0NSRUFURV9USU1FX1QgPSAnTC1jYWxsX3BsdXNfc2Vzc2lvbl9nZXRfY3JlYXRlX3RpbWUtVCcsXG4gIExfQ0FMTF9QTFVTX1NFU1NJT05fR0VUX0NSRUFURV9USU1FX1IgPSAnTC1jYWxsX3BsdXNfc2Vzc2lvbl9nZXRfY3JlYXRlX3RpbWUtUicsXG4gIC8qKlxuICAgKiDojrflj5bpgJror53ml7bplb9cbiAgICovXG4gIExfQ0FMTF9QTFVTX1NFU1NJT05fR0VUX0RVUkFUSU9OX1QgPSAnTC1jYWxsX3BsdXNfc2Vzc2lvbl9nZXRfZHVyYXRpb24tVCcsXG4gIExfQ0FMTF9QTFVTX1NFU1NJT05fR0VUX0RVUkFUSU9OX1IgPSAnTC1jYWxsX3BsdXNfc2Vzc2lvbl9nZXRfZHVyYXRpb24tUicsXG59XG4iLCJpbXBvcnQgeyBCYXNpY0xvZ2dlciB9IGZyb20gJ0Byb25nY2xvdWQvZW5naW5lJztcbmltcG9ydCB7XG4gIFJDQ2FsbFBsdXNUeXBlLCBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZSwgUkNDYWxsUGx1c01lZGlhVHlwZSwgUkNDYWxsUGx1c0NhbGxTdGF0ZSxcbn0gZnJvbSAnLi4vYXBpL2ludGVyZmFjZSc7XG5pbXBvcnQgeyBSQ0NhbGxJbm5lclNlc3Npb24gfSBmcm9tICcuL1JDQ2FsbElubmVyU2Vzc2lvbic7XG5pbXBvcnQgeyBSQ0NhbGxFbmdpbmUgfSBmcm9tICcuLi9SQ0NhbGxFbmdpbmUnO1xuaW1wb3J0IHsgUkNDYWxsUGx1c0NvZGUgfSBmcm9tICcuLi9hcGkvZW51bXMvUkNDYWxsUGx1c0NvZGUnO1xuaW1wb3J0IHsgUkNDYWxsUGx1c0xvZ2dlclRhZyB9IGZyb20gJy4uL2FwaS9lbnVtcy9SQ0NhbGxQbHVzTG9nZ2VyVGFnJztcblxuLyoqXG4gKiDlr7nlpJYgc2Vzc2lvbiDlrp7kvovvvIzku4XmnInojrflj5bmlrnms5XvvIzml6Dms5Xkv67mlLlcbiAqL1xuZXhwb3J0IGNsYXNzIFJDQ2FsbFBsdXNTZXNzaW9uIHtcbiAgcHJpdmF0ZSBfc3RhcnRUaW1lOiBudW1iZXIgPSAwXG5cbiAgcHJpdmF0ZSBfZHVyYXRpb246IG51bWJlciA9IDBcblxuICBwcml2YXRlIF9jYWxsSWQ6IHN0cmluZyA9ICcnXG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBfc2Vzc2lvbjogUkNDYWxsSW5uZXJTZXNzaW9uLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NhbGxFbmdpbmU6IFJDQ2FsbEVuZ2luZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9sb2dnZXI6IEJhc2ljTG9nZ2VyLFxuICApIHtcbiAgICB0aGlzLl9jYWxsSWQgPSB0aGlzLl9zZXNzaW9uLmdldENhbGxJZCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPliBDYWxsSWRcbiAgICovXG4gIHB1YmxpYyBnZXRDYWxsSWQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fY2FsbElkO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPliBzZXNzaW9uIOeKtuaAgVxuICAgKi9cbiAgcHVibGljIGdldFN0YXRlKCk6IFJDQ2FsbFBsdXNDYWxsU3RhdGUge1xuICAgIHJldHVybiB0aGlzLl9zZXNzaW9uLmdldFNlc3Npb25TdGF0ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPlumAmuivneexu+Wei1xuICAgKi9cbiAgcHVibGljIGdldENhbGxUeXBlKCk6IFJDQ2FsbFBsdXNUeXBlIHtcbiAgICByZXR1cm4gdGhpcy5fc2Vzc2lvbi5nZXRDYWxsVHlwZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPlumAmuivneWqkuS9k+exu+Wei1xuICAgKi9cbiAgcHVibGljIGdldE1lZGlhVHlwZSgpOiBSQ0NhbGxQbHVzTWVkaWFUeXBlIHtcbiAgICByZXR1cm4gdGhpcy5fc2Vzc2lvbi5nZXRNZWRpYVR5cGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDojrflj5bpgJror53kurrlkZjliJfooahcbiAgICovXG4gIHB1YmxpYyBnZXRVc2VyTGlzdCgpOiB7IHVzZXJJZDogc3RyaW5nLCBzdGF0ZTogUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUgfVtdIHtcbiAgICByZXR1cm4gdGhpcy5fc2Vzc2lvbi5nZXRVc2VyTGlzdCgpLm1hcCgodXNlcikgPT4ge1xuICAgICAgY29uc3Qge1xuICAgICAgICB1c2VySWQsIHVzZXJTdGF0ZSwgY2FtZXJhRW5hYmxlLCBtaWNyb3Bob25lRW5hYmxlLFxuICAgICAgfSA9IHVzZXI7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB1c2VySWQsXG4gICAgICAgIHN0YXRlOiB1c2VyU3RhdGUsXG4gICAgICAgIGNhbWVyYUVuYWJsZSxcbiAgICAgICAgbWljcm9waG9uZUVuYWJsZSxcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICog6I635Y+W6YCa6K+d5Y+R6LW36ICFIHVzZXJJZFxuICAgKi9cbiAgZ2V0Q3JlYXRvclVzZXJJZCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9zZXNzaW9uLmdldFN0YXJ0Q2FsbGVySWQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDojrflj5bpgJror53pgoDor7fogIUgdXNlcklkXG4gICAqIOWRvOWFpeacieWAvO+8jOWRvOWHuuaXtu+8jOWAvOS4uuacrOWcsOeUqOaItyBVc2VySWRcbiAgICovXG4gIGdldEludml0ZXJVc2VySWQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fc2Vzc2lvbi5nZXRDYWxsZXJJZCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPlumAmuivnei1t+Wni+aXtumXtFxuICAgKi9cbiAgYXN5bmMgZ2V0Q3JlYXRlVGltZXN0YW1wKCk6IFByb21pc2U8e2NvZGU6IG51bWJlciwgc3RhcnRUaW1lPzogbnVtYmVyfT4ge1xuICAgIGNvbnN0IHRyYWNlSWQgPSB0aGlzLl9sb2dnZXIuY3JlYXRlVHJhY2VJZCgpO1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMX1BMVVNfU0VTU0lPTl9HRVRfQ1JFQVRFX1RJTUVfVCwgJycsIHRyYWNlSWQpO1xuICAgIGlmICh0aGlzLl9zdGFydFRpbWUpIHtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MsIHN0YXJ0VGltZTogdGhpcy5fc3RhcnRUaW1lIH07XG4gICAgfVxuICAgIGNvbnN0IHsgY29kZSwgY2xpZW50U3RhcnRUaW1lIH0gPSBhd2FpdCB0aGlzLl9jYWxsRW5naW5lLmdldENhbGxTdGFyaW5nVGltZSh7IGNhbGxJZDogdGhpcy5fY2FsbElkIH0sIHRyYWNlSWQpO1xuICAgIGlmIChjb2RlICE9PSBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExfUExVU19TRVNTSU9OX0dFVF9DUkVBVEVfVElNRV9SLCBgZXJyQ29kZTogJHtjb2RlfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZSB9O1xuICAgIH1cblxuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMX1BMVVNfU0VTU0lPTl9HRVRfQ1JFQVRFX1RJTUVfUiwgJ3N1Y2Nlc3MnLCB0cmFjZUlkKTtcbiAgICB0aGlzLl9zdGFydFRpbWUgPSBjbGllbnRTdGFydFRpbWUhO1xuICAgIHJldHVybiB7XG4gICAgICBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTLFxuICAgICAgc3RhcnRUaW1lOiB0aGlzLl9zdGFydFRpbWUsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDojrflj5bpgJror53ml7bplb9cbiAgICog6YCa6K+d5pyq57uT5p2f5YmN77yM5YC85Li6IDBcbiAgICovXG4gIGFzeW5jIGdldER1cmF0aW9uKCk6IFByb21pc2U8e2NvZGU6IG51bWJlciwgZHVyYXRpb24/OiBudW1iZXJ9PiB7XG4gICAgY29uc3QgdHJhY2VJZCA9IHRoaXMuX2xvZ2dlci5jcmVhdGVUcmFjZUlkKCk7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExfUExVU19TRVNTSU9OX0dFVF9EVVJBVElPTl9ULCAnJywgdHJhY2VJZCk7XG5cbiAgICBpZiAodGhpcy5fZHVyYXRpb24pIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMX1BMVVNfU0VTU0lPTl9HRVRfRFVSQVRJT05fUiwgYGNvZGU6ICR7UkNDYWxsUGx1c0NvZGUuU1VDQ0VTU30sIGR1cmF0aW9uOiAke3RoaXMuX2R1cmF0aW9ufWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUywgZHVyYXRpb246IHRoaXMuX2R1cmF0aW9uIH07XG4gICAgfVxuXG4gICAgY29uc3QgeyBjb2RlLCBkYXRhIH0gPSBhd2FpdCB0aGlzLl9jYWxsRW5naW5lLmdldENhbGxUaW1lSW5mbyh0aGlzLl9jYWxsSWQsIHRyYWNlSWQpO1xuICAgIGlmIChjb2RlICE9PSBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExfUExVU19TRVNTSU9OX0dFVF9EVVJBVElPTl9SLCBgY29kZTogJHtjb2RlfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZSB9O1xuICAgIH1cblxuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMX1BMVVNfU0VTU0lPTl9HRVRfRFVSQVRJT05fUiwgYGNvZGU6ICR7UkNDYWxsUGx1c0NvZGUuU1VDQ0VTU30sIGR1cmF0aW9uOiAke2RhdGEhLmR1cmF0aW9ufWAsIHRyYWNlSWQpO1xuICAgIHRoaXMuX2R1cmF0aW9uID0gZGF0YSEuZHVyYXRpb247XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MsXG4gICAgICBkdXJhdGlvbjogdGhpcy5fZHVyYXRpb24sXG4gICAgfTtcbiAgfVxufVxuIiwiLyoqXG4gKiDlkbzlj6vnsbvlnotcbiAqL1xuZXhwb3J0IGVudW0gUkNDYWxsUGx1c1R5cGUge1xuICAvKipcbiAgICog5Y2V5ZG8XG4gICAqL1xuICBTSU5HTEUsXG4gIC8qKlxuICAgKiDlpJrkurrlkbzlj6tcbiAgICovXG4gIE1VTFRJXG59XG4iLCJleHBvcnQgZW51bSBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZSB7XG4gIC8qKlxuICAgKiBJRExFXG4gICAqL1xuICBJRExFID0gMCxcbiAgLyoqXG4gICAqIOWPkei1t+WRvOWPq1xuICAgKi9cbiAgQ0FMTElORyA9IDEwMCxcbiAgLyoqXG4gICAqIOiiq+mCgOivt1xuICAgKi9cbiAgSU5WSVRFRCA9IDEwMSxcbiAgLyoqXG4gICAqIOWTjemTg1xuICAgKi9cbiAgUklOR0lORyA9IDEwMixcbiAgLyoqXG4gICAqIOW3seaWueW/meeijOebtOaOpeaMguaWrVxuICAgKi9cbiAgQlVTWUxJTkVfUklOR0lORyA9IDEwMyxcbiAgLyoqXG4gICAqIOW3seaWueW/meeijOetieW+heaOpeWQrOWFtuS7lumAmuivnVxuICAgKi9cbiAgQlVTWUxJTkVfV0FJVCA9IDEwNCxcbiAgLyoqXG4gICAqIOmAmuivnei/nuaOpeS4rVxuICAgKi9cbiAgQ09OTkVDVElORyA9IDIwMCxcbiAgLyoqXG4gICAqIOato+WcqOmAmuivneS4rVxuICAgKi9cbiAgT05DQUxMID0gMzAwLFxuICAvKipcbiAgICog5q2j5Zyo57O757uf6YCa6K+d5LitXG4gICAqL1xuICBPTlBIT05FID0gMzAxLFxuICAvKipcbiAgICog6YCa6K+d57uT5p2fXG4gICAqL1xuICBFTkRFRCA9IDEwMDAsXG4gIC8qKlxuICAgKiDov5znq6/mnKrmjqXlkKxcbiAgICovXG4gIE5PX0FOU1dFUiA9IDEwMDEsXG4gIC8qKlxuICAgKiDlt7Hnq6/otoXml7bmnKrmjqXlkKxcbiAgICovXG4gIE1JU1NFRCA9IDEwMDIsXG4gIC8qKlxuICAgKiDpgJror53lj5bmtohcbiAgICovXG4gIENBTkNFTExFRCA9IDEwMDMsXG4gIC8qKlxuICAgKiDpgJror53mi5Lnu51cbiAgICovXG4gIERFQ0xJTkVEID0gMTAwNCxcbiAgLyoqXG4gICAqIOW8guW4uFxuICAgKi9cbiAgRVJST1IgPSAyMDAwXG59XG4iLCIvKipcbiAqIOWRvOWPq+WqkuS9k+exu+Wei1xuICovXG5leHBvcnQgZW51bSBSQ0NhbGxQbHVzTWVkaWFUeXBlIHtcbiAgLyoqXG4gICAqIOmfs+mikVxuICAgKi9cbiAgQVVESU8sXG4gIC8qKlxuICAgKiDpn7Pop4bpopFcbiAgICovXG4gIEFVRElPX1ZJREVPLFxuICAvKipcbiAgICog6KeG6aKRXG4gICAqL1xuICBWSURFTyxcbn1cbiIsIi8qKlxuICog6YCa6K+d54q25oCBXG4gKi9cbmV4cG9ydCBlbnVtIFJDQ2FsbFBsdXNDYWxsU3RhdGUge1xuICAvKipcbiAgICog5Yid5aeL54q25oCBXG4gICAqL1xuICBJRExFID0gMCxcbiAgLyoqXG4gICAqIOato+WcqOWRvOWPq1xuICAgKi9cbiAgQ0FMTElORyA9IDEwMCxcbiAgLyoqXG4gICAqIOiiq+mCgOivt1xuICAgKi9cbiAgSU5WSVRFRCA9IDEwMSxcbiAgLyoqXG4gICAqIOWTjemTg1xuICAgKi9cbiAgUklOR0lORyA9IDEwMixcbiAgLyoqXG4gICAqIOW/mee6v+WTjemTg1xuICAgKi9cbiAgQlVTWUxJTkVfUklOR0lORyA9IDEwMyxcbiAgLyoqXG4gICAqIOW/mee6v+etieW+hVxuICAgKi9cbiAgQlVTWUxJTkVfV0FJVCA9IDEwNCxcbiAgLyoqXG4gICAqIOmAmuivnei/nuaOpeS4rVxuICAgKi9cbiAgQ09OTkVDVElORyA9IDIwMCxcbiAgLyoqXG4gICAqIOmAmuivneS4rVxuICAgKi9cbiAgT05DQUxMID0gMzAwLFxuICAvKipcbiAgICog6YCa6K+d57uT5p2fXG4gICAqL1xuICBFTkRFRCA9IDEwMDAsXG4gIC8qKlxuICAgKiDov5znq6/mnKrmjqXlkKxcbiAgICovXG4gIE5PQU5TV0VSID0gMTAwMSxcbiAgLyoqXG4gICAqIOW3seerr+acquaOpeWQrFxuICAgKi9cbiAgTUlTU0VEID0gMTAwMixcbiAgLyoqXG4gICAqIOW3seerr+WPlua2iOmAmuivnVxuICAgKi9cbiAgQ0FOQ0VMRUQgPSAxMDAzLFxuICAvKipcbiAgICog6L+c56uv5ouS57udXG4gICAqL1xuICBERUNMSU5FRCA9IDEwMDQsXG5cbiAgRVJST1IgPSAyMDAwXG59XG4iLCJleHBvcnQgZW51bSBSQ0NhbGxQbHVzTWVkaWFUeXBlQ2hhbmdlUmVzdWx0IHtcbiAgLyoqXG4gICAqIOivt+axguaWueWPlua2iOWqkuS9k+exu+Wei+WPmOabtFxuICAgKi9cbiAgQ0FOQ0VMX0NIQU5HRV9NRURJQV9UWVBFID0gMCxcbiAgLyoqXG4gICAqIOW6lOetlOaWueaLkue7neWqkuS9k+exu+Wei+WIh+aNolxuICAgKi9cbiAgUkVGVVNFX0NIQU5HRV9NRURJQV9UWVBFID0gMSxcbiAgLyoqXG4gICAqIOacjeWKoeS7suijgeWFgeiuuOWqkuS9k+exu+Wei+WIh+aNolxuICAgKi9cbiAgU0VSVkVSX0FMTE9XX01FRElBX1RZUEUgPSAyLFxuICAvKipcbiAgICog5aqS5L2T57G75Z6L5YiH5o2i6LaF5pe2XG4gICAqL1xuICBDSEFOR0VfTUVESUFfVFlQRV9USU1FT1VUID0gMyxcbn1cbiIsImV4cG9ydCBlbnVtIFJDQ2FsbFBsdXNSZWFzb24ge1xuICBJRExFID0gMCxcbiAgQ0FMTElORyA9IDEwMCxcbiAgSU5WSVRFRCA9IDEwMSxcbiAgUklOR0lORyA9IDEwMixcbiAgQlVTWUxJTkVfUklOR0lORyA9IDEwMyxcbiAgQlVTWUxJTkVfV0FJVCA9IDEwNCxcbiAgQ09OTkVDVElORyA9IDIwMCxcbiAgT05DQUxMID0gMzAwLFxuICBPTl9QSE9ORSA9IDMwMSxcbiAgT05fUEhPTkVfRU5EID0gMzAyLFxuICAvKipcbiAgICog6L6T5YWl6K6+5aSH5LiN5Y+v55SoXG4gICAqL1xuICBPTl9ERVZJQ0VfRElTQUJMRSA9IDMwMyxcbiAgLyoqXG4gICAqIOi+k+WFpeiuvuWkh+WPr+eUqFxuICAgKi9cbiAgT05fREVWSUNFX0VOQUJMRSA9IDMwNCxcbiAgLyoqXG4gICAqIOacrOerr+W8guW4uOemu+W8gFxuICAgKi9cbiAgQUJOT1JNQUxfRU5EID0gOTk5LFxuICAvKipcbiAgICog6YCa6K+d57uT5p2fXG4gICAqL1xuICBFTkRFRCA9IDEwMDAsXG4gIC8qKlxuICAgKiDov5znq6/mnKrmjqXlkKxcbiAgICovXG4gIE5PX0FOU1dFUiA9IDEwMDEsXG4gIC8qKlxuICAgKiDlt7Hnq6/mnKrmjqXlkKxcbiAgICovXG4gIE1JU1NFRCA9IDEwMDIsXG4gIC8qKlxuICAgKiDlt7Hnq6/pgJror53lj5bmtohcbiAgICovXG4gIENBTkNFTExFRCA9IDEwMDMsXG4gIC8qKlxuICAgKiDov5znq6/mi5Lnu51cbiAgICovXG4gIERFQ0xJTkVEID0gMTAwNCxcbiAgLyoqXG4gICAqIOWFtuS7luerr+WRvOWHuijlvZPliY3nq6/ooqvouKIpXG4gICAqL1xuICBPVEhFUl9DTElFTlRfQ0FMTElORyA9IDEwMTAsXG4gIC8qKlxuICAgKiDlhbbku5bnq6/lt7LmjqXlkKxcbiAgICovXG4gIE9USEVSX0NMSUVOVF9BQ0NFUFQgPSAxMDExLFxuICAvKipcbiAgICog5Yqg5YWlIFJUQyDmiL/pl7TlpLHotKVcbiAgICovXG4gIEpPSU5fUk9PTV9FUlIgPSAxMTA1LFxuICAvKipcbiAgICog5Y+R5biD6LWE5rqQ5aSx6LSlXG4gICAqL1xuICBQVUJMSVNIX0VSUiA9IDExMDYsXG4gIC8qKlxuICAgKiDorqLpmIXotYTmupDlpLHotKVcbiAgICovXG4gIFNVQlNDUklCRV9FUlIgPSAxMTA3LFxuICAvKipcbiAgICog5o6l5ZCs57O757uf6YCa6K+dXG4gICAqL1xuICBBQ0NFUFRfQ0FSUklFUiA9IDExMDgsXG4gIC8qKlxuICAgKiDooqvnpoHmraLpgJror51cbiAgICovXG4gIEtJQ0tFRF9CWV9TRVJWRVIgPSAxMTA5LFxuICAvKipcbiAgICogUlRDIFBpbmcg5aSx6LSl6KKr6Lii5Ye65oi/6Ze0XG4gICAqL1xuICBDT05ORUNUSU9OX0VSUiA9IDExMTAsXG4gIC8qKlxuICAgKiDnlKjmiLfpgIDlh7rnmbvlvZXooqvouKLlh7rmiL/pl7RcbiAgICovXG4gIExPR09VVCA9IDExMTEsXG4gIC8qKlxuICAgKiDnlKjmiLfooqvlhbbku5bnq6/nmbvlvZXmjKTkuIvnur9cbiAgICovXG4gIE9USEVSX0NMSUVOVF9MT0dJTiA9IDExMTIsXG4gIC8qKlxuICAgKiDlhbbku5bnq6/liqDlhaXmlrDpgJror51cbiAgICovXG4gIE9USEVSX0NMSUVOVF9KT0lORUQgPSAxMTEzLFxuICAvKipcbiAgICog5YW25LuW56uv5bey5Zyo5YW25LuW6YCa6K+d5Lit77yI5bex56uvIEExIOWFtuS7luerr+ato+WcqOmAmuivneS4re+8jEEyIOWkmuerr+WPiOWKoOWFpeaIv+mXtOiiq+aLkue7neWQjumAmuivnee7k+adnyBBMiDnmoTnirbmgIHvvIlcbiAgICovXG4gIE9USEVSX0NMSUVOVF9JTl9ST09NID0gMTExNCxcbiAgLyoqXG4gICAqIOWFtuS7luerr+W3suaMguaWrVxuICAgKi9cbiAgT1RIRVJfQ0xJRU5UX0hBTkdVUCA9IDExNTEsXG4gIC8qKlxuICAgKiDov5znq6/nlKjmiLfliqDlhaXmiL/pl7TlpLHotKVcbiAgICovXG4gIFJFTU9URV9KT0lOX1JUQ19FUlJPUiA9IDEyMDUsXG4gIC8qKlxuICAgKiDov5znq6/nlKjmiLflj5HluIPotYTmupDlpLHotKVcbiAgICovXG4gIFJFTU9URV9QVUJMSVNIX0VSUk9SID0gMTIwNixcbiAgLyoqXG4gICAqIOi/nOerr+eUqOaIt+iuoumYhei1hOa6kOWksei0pVxuICAgKi9cbiAgUkVNT1RFX1NVQlNDUklCRV9FUlJPUiA9IDEyMDcsXG4gIC8qKlxuICAgKiDov5znq6/nlKjmiLflt7Looqso5bCB56aBKeemgeatoumAmuivnVxuICAgKi9cbiAgUkVNT1RFX0tJQ0tFRF9CWV9TRVJWRVIgPSAxMjA5LFxuICAvKipcbiAgICog6L+c56uv55So5oi3VURQ6L+e5o6l5pat5byAXG4gICAqL1xuICBSRU1PVEVfQ09OTkVDVElPTl9FUlJPUiA9IDEyMTAsXG4gIC8qKlxuICAgKiDov5znq6/nlKjmiLfpgIDlh7pJTeeZu+W9lVxuICAgKi9cbiAgUkVNT1RFX0xPR09VVCA9IDEyMTEsXG4gIC8qKlxuICAgKiDov5znq6/nlKjmiLfooqvlhbbku5bnq6/nmbvlvZXmjKTkuIvnur9cbiAgICovXG4gIFJFTU9URV9PVEhFUl9DTElFTlRfTE9HSU4gPSAxMjEyLFxuICAvKipcbiAgICog6L+c56uv55So5oi36KKr5YW25LuW56uv5Yqg5YWl5oi/6Ze0IGpvaW5Sb29tIOi4ouWHulxuICAgKi9cbiAgUkVNT1RFX09USEVSX0pPSU5FRF9SVEMgPSAxMjEzLFxuICAvKipcbiAgICog6L+c56uv55So5oi355qE5YW25LuW56uv5bey57uP5Zyo5oi/6Ze05Lit77yM5LiN5YWB6K64IGpvaW5Sb29tIOi/m+ihjOmfs+inhumikemAmuivnVxuICAgKi9cbiAgUkVNT1RFX09USEVSX0NMSUVOVF9JTl9SVEMgPSAxMjE0XG59XG4iLCJpbXBvcnQgeyBCYXNpY0xvZ2dlciwgaXNOdW1iZXIgfSBmcm9tICdAcm9uZ2Nsb3VkL2VuZ2luZSc7XG5pbXBvcnQgeyBJQXVkaW9Db25maWcgfSBmcm9tICcuL2ludGVyZmFjZSc7XG5pbXBvcnQgeyBSQ0NhbGxQbHVzTG9nZ2VyVGFnIH0gZnJvbSAnLi9lbnVtcy9SQ0NhbGxQbHVzTG9nZ2VyVGFnJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUkNBdWRpb0NvbmZpZ0J1aWxkZXIge1xuICBwcml2YXRlIF9hdWRpb0NvbmZpZzogSUF1ZGlvQ29uZmlnID0ge31cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIF9sb2dnZXI6IEJhc2ljTG9nZ2VyLFxuICApIHt9XG5cbiAgLyoqXG4gICAqIOaMh+Wumum7mOiupOm6puWFi+mjjlxuICAgKiBtaWNyb3Bob25lSWQg5Y+W5YC85Y+v5Y+C6ICDIGh0dHBzOi8vZG9jLnJvbmdjbG91ZC5jbi9ydGMvV2ViLzUuWC9kZXZpY2UjJUU4JThFJUI3JUU1JThGJTk2JUU5JUJBJUE2JUU1JTg1JThCJUU5JUEzJThFJUU4JUFFJUJFJUU1JUE0JTg3JUU1JTg4JTk3JUU4JUExJUE4XG4gICAqL1xuICBzZXREZWZhdWx0TWljcm9waG9uZUlkKG1pY3JvcGhvbmVJZDogc3RyaW5nKTogUkNBdWRpb0NvbmZpZ0J1aWxkZXIge1xuICAgIHRoaXMuX2F1ZGlvQ29uZmlnLm1pY3JvcGhvbmVJZCA9IG1pY3JvcGhvbmVJZDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiDorr7nva7mnIDlsI/jgIHmnIDlpKfnoIHnjodcbiAgICog5Y2V5L2NIGticHNcbiAgICog5LiN6K6+572u5pe277yM5Y+W5Yqo5oCB56CB546H6K6h566X57uT5p6cXG4gICAqIEBwYXJhbSBtaW4g5pyA5bCP56CB546HXG4gICAqIEBwYXJhbSBtYXgg5pyA5aSn56CB546HXG4gICAqL1xuICBzZXRCaXRyYXRlKG1pbjogbnVtYmVyLCBtYXg6IG51bWJlcik6IFJDQXVkaW9Db25maWdCdWlsZGVyIHtcbiAgICBpZiAoIWlzTnVtYmVyKG1pbikgfHwgIWlzTnVtYmVyKG1heCkgfHwgbWF4IDw9IDAgfHwgbWluIDw9IDAgfHwgbWF4IDwgbWluKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0FVRElPX0NPTkZJR19TRVRfQklUUkFURV9PLCBgcGFyYW1zIGVycm9yIC0+IG1heDogJHttYXh9LG1pbjogJHttaW59LCBtYXggYW5kIG1pbiBpcyBhIG51bWJlciA+IDAsIG1heCBzaG91bGQgPiBtaW5gKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICB0aGlzLl9hdWRpb0NvbmZpZy5taW5CaXRyYXRlID0gbWluO1xuICAgIHRoaXMuX2F1ZGlvQ29uZmlnLm1heEJpdHJhdGUgPSBtYXg7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICog6K6+572u6Z+z6aKR6YeH5qC3546H77yM5LiN5bu66K6u6Ieq6KGM5L+u5pS5XG4gICAqIEBwYXJhbSBzYW1wbGVSYXRlIOmHh+agt+eOh1xuICAgKi9cbiAgc2V0U2FtcGxlUmF0ZShzYW1wbGVSYXRlOiBudW1iZXIpOiBSQ0F1ZGlvQ29uZmlnQnVpbGRlciB7XG4gICAgaWYgKCFpc051bWJlcihzYW1wbGVSYXRlKSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19BVURJT19DT05GSUdfU0VUX1NBTVBMRV9SQVRFX08sIGBwYXJhbXMgZXJyb3IgLT4gc2FtcGxlUmF0ZTogJHtzYW1wbGVSYXRlfWApO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHRoaXMuX2F1ZGlvQ29uZmlnLnNhbXBsZVJhdGUgPSBzYW1wbGVSYXRlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqIOaehOW7uumFjee9riAqL1xuICBidWlsZCgpOiBJQXVkaW9Db25maWcge1xuICAgIHJldHVybiB0aGlzLl9hdWRpb0NvbmZpZztcbiAgfVxufVxuIiwiaW1wb3J0IHsgQmFzaWNMb2dnZXIsIGlzTnVtYmVyIH0gZnJvbSAnQHJvbmdjbG91ZC9lbmdpbmUnO1xuaW1wb3J0IHsgUkNDYWxsUGx1c0ZyYW1lUmF0ZSwgUkNDYWxsUGx1c1Jlc29sdXRpb24sIElWaWRlb0NvbmZpZyB9IGZyb20gJy4vaW50ZXJmYWNlJztcbmltcG9ydCB7IFJDQ2FsbFBsdXNMb2dnZXJUYWcgfSBmcm9tICcuL2VudW1zL1JDQ2FsbFBsdXNMb2dnZXJUYWcnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSQ1ZpZGVvQ29uZmlnQnVpbGRlciB7XG4gIHByaXZhdGUgX3ZpZGVvQ29uZmlnOiBJVmlkZW9Db25maWcgPSB7XG4gICAgcmVzb2x1dGlvbjogUkNDYWxsUGx1c1Jlc29sdXRpb24uVzY0MF9INDgwLFxuICAgIGZyYW1lUmF0ZTogUkNDYWxsUGx1c0ZyYW1lUmF0ZS5GUFNfMTUsXG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIF9sb2dnZXI6IEJhc2ljTG9nZ2VyLFxuICApIHt9XG5cbiAgLyoqIOmSiOWvueS4jeWQjOinhumikea1geWIhuWIq+mFjee9ruW4p+eOhyAqL1xuICBzZXRGcmFtZVJhdGUoZnBzOiBSQ0NhbGxQbHVzRnJhbWVSYXRlKTogUkNWaWRlb0NvbmZpZ0J1aWxkZXIge1xuICAgIGlmICghUkNDYWxsUGx1c0ZyYW1lUmF0ZVtmcHNdKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX1ZJREVPX0NPTkZJR19TRVRfRlJBTUVfUkFURV9PLCBgcGFyYW1zIGVycm9yIC0+IGZwczogJHtmcHN9YCk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdGhpcy5fdmlkZW9Db25maWcuZnJhbWVSYXRlID0gZnBzO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqIOmSiOWvueS4jeWQjOinhumikea1geWIhuWIq+mFjee9ruWIhui+qOeOhyAqL1xuICBzZXRWaWRlb1Jlc29sdXRpb24ocmVzb2x1dGlvbjogUkNDYWxsUGx1c1Jlc29sdXRpb24pOiBSQ1ZpZGVvQ29uZmlnQnVpbGRlciB7XG4gICAgaWYgKCFSQ0NhbGxQbHVzUmVzb2x1dGlvbltyZXNvbHV0aW9uXSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19WSURFT19DT05GSUdfU0VUX1JFU09MVVRJT05fTywgYHBhcmFtcyBlcnJvciAtPiByZXNvbHV0aW9uOiAke3Jlc29sdXRpb259YCk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdGhpcy5fdmlkZW9Db25maWcucmVzb2x1dGlvbiA9IHJlc29sdXRpb247XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICog6K6+572u6buY6K6kIGNhbWVyYUlkXG4gICAqIGNhbWVyYUlkIOWPluWAvOWPr+WPguiAgyBodHRwczovL2RvYy5yb25nY2xvdWQuY24vcnRjL1dlYi81LlgvZGV2aWNlIyVFOCU4RSVCNyVFNSU4RiU5NiVFNiU5MSU4NCVFNSU4MyU4RiVFNSVBNCVCNCVFOCVBRSVCRSVFNSVBNCU4NyVFNSU4OCU5NyVFOCVBMSVBOFxuICAgKiDkvZznlKjkuo7pooTop4jlip/og73jgIHlkbzlj6vlj5bmtYHnrYlcbiAgICovXG4gIHNldERlZmF1bHRDYW1lcmFJZChjYW1lcmFJZDogc3RyaW5nKTogUkNWaWRlb0NvbmZpZ0J1aWxkZXIge1xuICAgIHRoaXMuX3ZpZGVvQ29uZmlnLmNhbWVyYUlkID0gY2FtZXJhSWQ7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICog6K6+572u5pyA5bCP44CB5pyA5aSn56CB546HXG4gICAqIOWNleS9jSBrYnBzXG4gICAqIOS4jeiuvue9ruaXtu+8jOWPluWKqOaAgeeggeeOh+iuoeeul+e7k+aenFxuICAgKiBAcGFyYW0gbWluIOacgOWwj+eggeeOh1xuICAgKiBAcGFyYW0gbWF4IOacgOWkp+eggeeOh1xuICAgKi9cbiAgc2V0Qml0cmF0ZShtaW46IG51bWJlciwgbWF4OiBudW1iZXIpOiBSQ1ZpZGVvQ29uZmlnQnVpbGRlciB7XG4gICAgaWYgKCFpc051bWJlcihtaW4pIHx8ICFpc051bWJlcihtYXgpIHx8IG1heCA8PSAwIHx8IG1pbiA8PSAwIHx8IG1heCA8IG1pbikge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19WSURFT19DT05GSUdfU0VUX0JJVFJBVEVfTywgYHBhcmFtcyBlcnJvciAtPiBtYXg6ICR7bWF4fSxtaW46ICR7bWlufSwgbWF4IGFuZCBtaW4gaXMgYSBudW1iZXIgPiAwLCBtYXggc2hvdWxkID4gbWluYCk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdGhpcy5fdmlkZW9Db25maWcubWluQml0cmF0ZSA9IG1pbjtcbiAgICB0aGlzLl92aWRlb0NvbmZpZy5tYXhCaXRyYXRlID0gbWF4O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8g5p6E5bu66YWN572uXG4gIGJ1aWxkKCk6IElWaWRlb0NvbmZpZyB7XG4gICAgcmV0dXJuIHRoaXMuX3ZpZGVvQ29uZmlnO1xuICB9XG59XG4iLCJpbXBvcnQgeyBJTmF2aUluZm8sIGlzTnVtYmVyIH0gZnJvbSAnQHJvbmdjbG91ZC9lbmdpbmUnO1xuaW1wb3J0IHsgUkNDYWxsUGx1c0NvZGUsIFJDQ2FsbFBsdXNSZWFzb24gfSBmcm9tICcuLi9hcGkvaW50ZXJmYWNlJztcbmltcG9ydCB7IFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlIH0gZnJvbSAnLi4vZW51bXMvUkNDYWxsU2Vzc2lvblVzZXJTdGF0ZSc7XG5pbXBvcnQge1xuICBJQWNjZXB0SW5mbywgSVJDQ2FsbFBsdXNDYWxsUmVjb3JkLCBJSGFuZ3VwSW5mbywgSU90aGVyTWVtSW5mbywgSVJpbmdpbmdJbmZvLFxufSBmcm9tICcuLi9pbnRlcmZhY2VzL0lSQ0NhbGxDbGllbnQnO1xuaW1wb3J0IHsgSVN0YXR1c0Rvd25Db250LCBJU3luY0NhbGxMb2dSZXMgfSBmcm9tICcuLi9pbnRlcmZhY2VzL0lTaWduYWxUcmFuc3BvcnRlcic7XG5cbi8qKlxuICogY2FsbCBzZXJ2ZXIgbG9nIOi9rOaNolxuICovXG5leHBvcnQgY29uc3QgdHJhbjJDYWxsTG9nID0gKGNhbGxMb2dMaXN0OiBJU3luY0NhbGxMb2dSZXMpOiBJUkNDYWxsUGx1c0NhbGxSZWNvcmQgPT4ge1xuICBjb25zdCB7XG4gICAgY2FsbElkLFxuICAgIGNhbGxUeXBlLFxuICAgIGNhbGxEaXIsXG4gICAgbWVkaWFUeXBlLFxuICAgIGNhbGxpbmdVc2VySWQsXG4gICAgY2FsbFVzZXJJZHMsXG4gICAgY2FsbFN0YXR1cyxcbiAgICBzZXNzaW9uU3RhdHVzLFxuICAgIHN0YXJ0VGltZSxcbiAgICBlbmRUaW1lLFxuICAgIGR1cmF0aW9uLFxuICAgIHNlY3JldENoYXQsXG4gICAgc3luY1RpbWUsXG4gICAgc3lzU3RhdHVzLFxuICAgIGNydFRpbWUsXG4gIH0gPSBjYWxsTG9nTGlzdDtcbiAgcmV0dXJuIHtcbiAgICBjYWxsSWQsXG4gICAgY2FsbFR5cGUsXG4gICAgY2FsbERpcmVjdGlvbjogY2FsbERpcixcbiAgICBtZWRpYVR5cGUsXG4gICAgLy8gaXNTZWNyZXRDaGF0OiBCb29sZWFuKHNlY3JldENoYXQpLFxuICAgIGNhbGxlclVzZXJJZDogY2FsbGluZ1VzZXJJZCxcbiAgICBjYWxsVXNlcklkcyxcbiAgICBzZXNzaW9uU3RhdGU6IGNhbGxTdGF0dXMsXG4gICAgdXNlclN0YXRlOiBzZXNzaW9uU3RhdHVzLFxuICAgIHN0YXJ0VGltZXN0YW1wOiBzdGFydFRpbWUsXG4gICAgZW5kVGltZXN0YW1wOiBlbmRUaW1lLFxuICAgIGR1cmF0aW9uLFxuICAgIHN5bmNUaW1lc3RhbXA6IHN5bmNUaW1lLFxuICAgIHN5c3RlbVN0YXRlOiBzeXNTdGF0dXMsXG4gICAgY3JlYXRlVGltZXN0YW1wOiBjcnRUaW1lLFxuICB9O1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBJUGFyc2VTdGF0dXMge1xuICByaW5naW5nRGF0YTogSVJpbmdpbmdJbmZvW107XG4gIGhhbmd1cERhdGE6IElIYW5ndXBJbmZvW107XG4gIGFjY2VwdERhdGE6IElBY2NlcHRJbmZvW107XG4gIG90aGVySW52aXRlZERhdGE6IElPdGhlck1lbUluZm9bXTtcbn1cblxuLyoqXG4gKiBwYXJzZVN0YXR1c1xuICovXG5leHBvcnQgY29uc3QgcGFyc2VTdGF0dXNEYXRhID0gKGRhdGE6IElTdGF0dXNEb3duQ29udCk6IElQYXJzZVN0YXR1cyA9PiB7XG4gIGNvbnN0IHsgY2FsbElkLCBjYWxsU3RhdHVzIH0gPSBkYXRhO1xuICBjb25zdCByaW5naW5nRGF0YTogSVJpbmdpbmdJbmZvW10gPSBbXTtcbiAgY29uc3QgaGFuZ3VwRGF0YTogSUhhbmd1cEluZm9bXSA9IFtdO1xuICBjb25zdCBhY2NlcHREYXRhOiBJQWNjZXB0SW5mb1tdID0gW107XG4gIGNvbnN0IG90aGVySW52aXRlZERhdGE6IElPdGhlck1lbUluZm9bXSA9IFtdO1xuICBkYXRhLmNhbGxTZXNzaW9uVXNlcnMuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgIGNvbnN0IHsgdXNlcklkLCBzZXNzaW9uU3RhdHVzLCBzeXNTdGF0dXMgfSA9IGl0ZW07XG4gICAgc3dpdGNoIChzZXNzaW9uU3RhdHVzKSB7XG4gICAgICBjYXNlIFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLklOVklURUQ6XG4gICAgICAgIG90aGVySW52aXRlZERhdGEucHVzaCh7XG4gICAgICAgICAgY2FsbElkLFxuICAgICAgICAgIHVzZXJJZCxcbiAgICAgICAgICB1c2VyU3RhdGU6IHNlc3Npb25TdGF0dXMsXG4gICAgICAgIH0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUuUklOR0lORzpcbiAgICAgICAgLy8g6YCa55+l5ZON6ZODXG4gICAgICAgIHJpbmdpbmdEYXRhLnB1c2goeyBjYWxsSWQsIGZyb21Vc2VySWQ6IHVzZXJJZCB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLkNPTk5FQ1RJTkc6XG4gICAgICAgIC8vIOmAmuefpeWvueaWueW3suaOpeWQrFxuICAgICAgICBhY2NlcHREYXRhLnB1c2goeyBmcm9tVXNlcklkOiB1c2VySWQgfSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZS5DQU5DRUxMRUQ6XG4gICAgICBjYXNlIFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLkRFQ0xJTkVEOlxuICAgICAgY2FzZSBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZS5FTkRFRDpcbiAgICAgIGNhc2UgUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUuSURMRTpcbiAgICAgICAgaGFuZ3VwRGF0YS5wdXNoKHtcbiAgICAgICAgICBjYWxsSWQsXG4gICAgICAgICAgZnJvbVVzZXJJZDogdXNlcklkLFxuICAgICAgICAgIHVzZXJTdGF0ZTogc2Vzc2lvblN0YXR1cyxcbiAgICAgICAgICBzeXN0ZW1TdGF0ZTogc3lzU3RhdHVzLFxuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBicmVhaztcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgcmluZ2luZ0RhdGEsXG4gICAgaGFuZ3VwRGF0YSxcbiAgICBhY2NlcHREYXRhLFxuICAgIG90aGVySW52aXRlZERhdGEsXG4gIH07XG59O1xuXG4vKipcbiAqIOWug+ajgOafpeWFg+e0oOaYr+WQpuaYr+inhumikeiKgueCuVxuICogQHBhcmFtIHthbnl9IGVsZW1lbnQgLSDmgqjopoHmo4Dmn6XnmoTlhYPntKDmmK/lkKbkuLrop4bpopHlhYPntKDjgIJcbiAqIEByZXR1cm5zIOS4gOS4quW4g+WwlOWAvOOAglxuICovXG5leHBvcnQgY29uc3QgdmFsaWRhdGVWaWRlb05vZGVOYW1lID0gKGVsZW1lbnQ6IGFueSkgPT4gZWxlbWVudCAmJiBlbGVtZW50Lm5vZGVOYW1lICYmIGVsZW1lbnQubm9kZU5hbWUudG9VcHBlckNhc2UoKSA9PT0gJ1ZJREVPJztcblxuLyoqXG4gKiDmoLnmja7nlKjmiLflvZPliY3nmoQgc3lzdGVtU3RhdGUg5ZKM5paw5LiL5Y+R55qEIHN5c3RlbVN0YXRlLOadpeWIpOaWreaWsCBzeXN0ZW1TdGF0ZSDmmK/lkKbml6DmlYhcbiAqIOS+i++8muW9k+WJjeeUqOaIt+W3suWcqCBjYWxsIOS4re+8jOWPiOaUtuWIsOatpOeUqOaIt+eahCDlk43pk4PjgIHov57mjqXkuK0g562JXG4gKi9cbmV4cG9ydCBjb25zdCB2YWxpZGF0ZVN5c1N0YXRlID0gKGNydFN0YXRlOiBSQ0NhbGxQbHVzUmVhc29uLCBuZXdTdGF0ZTogUkNDYWxsUGx1c1JlYXNvbikgPT4ge1xuICBsZXQgaXNJblZhbGlkID0gZmFsc2U7XG4gIGNvbnN0IGludmFsaWRTdGF0ZXMgPSBbXG4gICAgUkNDYWxsUGx1c1JlYXNvbi5JTlZJVEVELFxuICAgIFJDQ2FsbFBsdXNSZWFzb24uUklOR0lORyxcbiAgICBSQ0NhbGxQbHVzUmVhc29uLkJVU1lMSU5FX1JJTkdJTkcsXG4gICAgUkNDYWxsUGx1c1JlYXNvbi5CVVNZTElORV9XQUlULFxuICAgIFJDQ2FsbFBsdXNSZWFzb24uQ09OTkVDVElORyxcbiAgICBSQ0NhbGxQbHVzUmVhc29uLk9OQ0FMTCxcbiAgXTtcbiAgc3dpdGNoIChjcnRTdGF0ZSkge1xuICAgIGNhc2UgUkNDYWxsUGx1c1JlYXNvbi5PTkNBTEw6XG4gICAgICBpZiAoaW52YWxpZFN0YXRlcy5pbmNsdWRlcyhuZXdTdGF0ZSkpIHtcbiAgICAgICAgaXNJblZhbGlkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBicmVhaztcbiAgfVxuICByZXR1cm4gaXNJblZhbGlkO1xufTtcblxuLyoqXG4gICAqIOagueaNrueUqOaIt+W9k+WJjeeahCB1c2VyU3RhdGUg5ZKM5paw5LiL5Y+R55qEIHVzZXJTdGF0ZSzmnaXliKTmlq3mlrAgdXNlclN0YXRlIOaYr+WQpuaXoOaViFxuICAgKiDml6DmlYjnmoTnlKjmiLfnirbmgIFcbiAgICovXG5leHBvcnQgY29uc3QgdmFsaWRhdGVVc2VyU3RhdGUgPSAoY3J0U3RhdGU6IFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLCBuZXdTdGF0ZTogUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUpID0+IHtcbiAgbGV0IGlzSW5WYWxpZCA9IGZhbHNlO1xuICBjb25zdCBpbnZhbGlkU3RhdGVzID0gW1xuICAgIFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLklOVklURUQsXG4gICAgUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUuUklOR0lORyxcbiAgICBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZS5CVVNZTElORV9SSU5HSU5HLFxuICAgIFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLkJVU1lMSU5FX1dBSVQsXG4gICAgUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUuQ09OTkVDVElORyxcbiAgICBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZS5PTkNBTEwsXG4gIF07XG4gIHN3aXRjaCAoY3J0U3RhdGUpIHtcbiAgICBjYXNlIFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLk9OQ0FMTDpcbiAgICAgIGlmIChpbnZhbGlkU3RhdGVzLmluY2x1ZGVzKG5ld1N0YXRlKSkge1xuICAgICAgICBpc0luVmFsaWQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIGJyZWFrO1xuICB9XG4gIHJldHVybiBpc0luVmFsaWQ7XG59O1xuXG4vKipcbiAqIOiOt+WPluaMguaWreaXtueahOS6uuWRmOezu+e7n+eKtuaAgVxuICogQHBhcmFtIHVzZXJTdGF0ZSDkurrlkZjnirbmgIFcbiAqIEBwYXJhbSBpc0NhbGxlZSDmmK/lkKbmmK/ooqvlj6tcbiAqIEByZXR1cm5zIOS6uuWRmOezu+e7n+eKtuaAgVxuICovXG5leHBvcnQgY29uc3QgZ2V0SGFuZ3VwU3lzdGVtU3RhdGUgPSAodXNlclN0YXRlOiBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZSwgaXNDYWxsZWU6IGJvb2xlYW4pID0+IHtcbiAgbGV0IHN5c3RlbVN0YXRlO1xuICBzd2l0Y2ggKHVzZXJTdGF0ZSkge1xuICAgIGNhc2UgUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUuQ0FMTElORzpcbiAgICAgIHN5c3RlbVN0YXRlID0gUkNDYWxsUGx1c1JlYXNvbi5DQU5DRUxMRUQ7XG4gICAgICBicmVhaztcbiAgICBjYXNlIFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLlJJTkdJTkc6XG4gICAgY2FzZSBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZS5JTlZJVEVEOlxuICAgICAgc3lzdGVtU3RhdGUgPSBSQ0NhbGxQbHVzUmVhc29uLkRFQ0xJTkVEO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZS5DT05ORUNUSU5HOlxuICAgICAgc3lzdGVtU3RhdGUgPSBpc0NhbGxlZSA/IFJDQ2FsbFBsdXNSZWFzb24uREVDTElORUQgOiBSQ0NhbGxQbHVzUmVhc29uLkNBTkNFTExFRDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUuT05DQUxMOlxuICAgICAgc3lzdGVtU3RhdGUgPSBSQ0NhbGxQbHVzUmVhc29uLkVOREVEO1xuICAgICAgYnJlYWs7XG4gIH1cbiAgcmV0dXJuIHN5c3RlbVN0YXRlO1xufTtcblxuLyoqXG4gKiDliKTmlq3mmK/lkKblvIDlp4vpn7Pop4bpopHmnI3liqFcbiAqL1xuZXhwb3J0IGNvbnN0IGlzU3VwcG9ydE1lZGlhU2VydmVyID0gKG5hdmlJbmZvOiBJTmF2aUluZm8pID0+IHtcbiAgY29uc3QgeyB2b2lwQ2FsbEluZm8gfSA9IG5hdmlJbmZvO1xuICBpZiAoIXZvaXBDYWxsSW5mbykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IHsgc3RyYXRlZ3kgfSA9IEpTT04ucGFyc2Uodm9pcENhbGxJbmZvKTtcbiAgaWYgKHN0cmF0ZWd5ICE9PSAxKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5leHBvcnQgY29uc3QgdmFsaWRhdGVCaXRyYXRlID0gKG1pbkJpdHJhdGU/OiBudW1iZXIsIG1heEJpdHJhdGU/OiBudW1iZXIpID0+IHtcbiAgaWYgKG1pbkJpdHJhdGUgfHwgbWluQml0cmF0ZSA9PT0gMCkge1xuICAgIGlmICghaXNOdW1iZXIobWluQml0cmF0ZSkgfHwgbWluQml0cmF0ZSA8PSAwKSB7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5QQVJBTV9FUlJPUiwgZXJyb3JNc2c6IGBwYXJhbXMgZXJyb3IgLT4gbWluQml0cmF0ZTogYSBudW1iZXIgb2YgPiAwLCB2YWx1ZTogJHttaW5CaXRyYXRlfWAgfTtcbiAgICB9XG4gIH1cblxuICBpZiAobWF4Qml0cmF0ZSB8fCBtYXhCaXRyYXRlID09PSAwKSB7XG4gICAgaWYgKCFpc051bWJlcihtYXhCaXRyYXRlKSB8fCBtYXhCaXRyYXRlIDw9IDApIHtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlBBUkFNX0VSUk9SLCBlcnJvck1zZzogYHBhcmFtcyBlcnJvciAtPiBtYXhCaXRyYXRlOiBhIG51bWJlciBvZiA+IDAsIHZhbHVlOiAke21heEJpdHJhdGV9YCB9O1xuICAgIH1cbiAgfVxuXG4gIGlmIChtaW5CaXRyYXRlICYmIG1heEJpdHJhdGUgJiYgbWF4Qml0cmF0ZSA8IG1pbkJpdHJhdGUpIHtcbiAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5QQVJBTV9FUlJPUiwgZXJyb3JNc2c6IGBwYXJhbXMgZXJyb3IgLT4gbWF4Qml0cmF0ZTogJHttYXhCaXRyYXRlfSwgbWluQml0cmF0ZTogJHttaW5CaXRyYXRlfSwgbWF4Qml0cmF0ZSBzaG91bGQgPiBtaW5CaXRyYXRlYCB9O1xuICB9XG5cbiAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyB9O1xufTtcbiIsImV4cG9ydCBlbnVtIFJDQ2FsbFBsdXNTdGF0aXN0aWNzVGFnIHtcbiAgLyoqXG4gICAqIOWPkei1t+mAmuivnVxuICAgKi9cbiAgTF9RU19TVEFSVF9DQUxMX1MgPSAnQ2FsbC1zdGFydC1TJyxcbiAgLyoqXG4gICAqIOaOpeWQrOmAmuivnVxuICAgKi9cbiAgTF9RU19BQ0NFUFRfQ0FMTF9TID0gJ0NhbGwtYWNjZXB0LVMnLFxuICAvKipcbiAgICog5oyC5pat6YCa6K+dXG4gICAqL1xuICBMX1FTX0hBTkdVUF9DQUxMX1MgPSAnQ2FsbC1oYW5ndXAtUycsXG4gIC8qKlxuICAgKiDmlLbliLDpgJror51cbiAgICovXG4gIExfUVNfUkVDRUlWRV9DQUxMX1MgPSAnQ2FsbC1yZWN2LVMnLFxuICAvKipcbiAgICog5byC5bi45oyC5patXG4gICAqL1xuICBMX1FTX0FCTk9STUFMX0hBTkdVUF9TID0gJ0NhbGwtaW50ZXJydXB0LVMnXG59XG4iLCJpbXBvcnQgeyBCYXNpY0xvZ2dlciwgUGx1Z2luQ29udGV4dCB9IGZyb20gJ0Byb25nY2xvdWQvZW5naW5lJztcbmltcG9ydCB7IFJDQ2FsbFBsdXNJbnZpdGVTb3VyY2UgfSBmcm9tICcuLi9pbnRlcmZhY2VzL0lDYWxsUGx1c1N0YXRpc3RpY3MnO1xuaW1wb3J0IHtcbiAgUkNDYWxsUGx1c01lZGlhVHlwZSwgUkNDYWxsUGx1c1Nlc3Npb24sIFJDQ2FsbFBsdXNUeXBlLFxufSBmcm9tICcuLi9hcGkvaW50ZXJmYWNlJztcbmltcG9ydCB7IFJDQ2FsbFBsdXNTdGF0aXN0aWNzVGFnIH0gZnJvbSAnLi4vZW51bXMvUkNDYWxsUGx1c1N0YXRpc3RpY3NUYWcnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSQ0NhbGxQTHVzU3RhdGlzdGljcyB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2xvZ2dlcjogQmFzaWNMb2dnZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBfY29udGV4dDogUGx1Z2luQ29udGV4dCxcbiAgKSB7XG4gIH1cblxuICBwdWJsaWMgcmVwb3J0U3RhdGlzdGljc0RhdGEoXG4gICAgdGFnOiBSQ0NhbGxQbHVzU3RhdGlzdGljc1RhZyxcbiAgICBjb2RlOiBudW1iZXIsXG4gICAgc3RhcnRUaW1lOiBudW1iZXIsXG4gICAgc2Vzc2lvbjogUkNDYWxsUGx1c1Nlc3Npb24gfCBudWxsLFxuICAgIGNsaWVudENhbGxJZD86IHN0cmluZyxcbiAgICBpbnZpdGVTb3VyY2U/OiBSQ0NhbGxQbHVzSW52aXRlU291cmNlIHwgbnVsbCxcbiAgICBleHRyYT86IHtcbiAgICAgIG1lZGlhVHlwZTogUkNDYWxsUGx1c01lZGlhVHlwZSxcbiAgICAgIGNhbGxUeXBlOiBSQ0NhbGxQbHVzVHlwZSxcbiAgICAgIGNhbGxJZDogc3RyaW5nLFxuICAgIH0sXG4gICkge1xuICAgIGNvbnN0IG5vd1RpbWUgPSArbmV3IERhdGUoKTtcbiAgICBjb25zdCB7IG1lZGlhVHlwZSwgY2FsbFR5cGUsIGNhbGxJZCB9ID0gc2Vzc2lvbiA/IHsgbWVkaWFUeXBlOiBzZXNzaW9uLmdldE1lZGlhVHlwZSgpLCBjYWxsVHlwZTogc2Vzc2lvbi5nZXRDYWxsVHlwZSgpLCBjYWxsSWQ6IHNlc3Npb24uZ2V0Q2FsbElkKCkgfSA6IGV4dHJhITtcbiAgICBjb25zdCBjb21tb25EYXRhID0ge1xuICAgICAgY3I6ICd1bmtub3duJyxcbiAgICAgIG5ldDogJ3Vua25vd24nLFxuICAgICAgY29kOiBjb2RlLFxuICAgICAgbXRwOiBtZWRpYVR5cGUsXG4gICAgICBjdHA6IGNhbGxUeXBlLFxuICAgICAgY2lkOiBjYWxsSWQsXG4gICAgICB0aW1lOiBub3dUaW1lLFxuICAgICAgdWlkOiB0aGlzLl9jb250ZXh0LmdldEN1cnJlbnRJZCgpLFxuICAgIH07XG5cbiAgICBjbGllbnRDYWxsSWQgJiYgT2JqZWN0LmFzc2lnbihjb21tb25EYXRhLCB7IGNjaWQ6IGNsaWVudENhbGxJZCB9KTtcblxuICAgIGxldCBkYXRhID0gbnVsbDtcblxuICAgIHN3aXRjaCAodGFnKSB7XG4gICAgICAvKipcbiAgICAgICAqIOaUtuWIsOWRvOWPq1xuICAgICAgICovXG4gICAgICBjYXNlIFJDQ2FsbFBsdXNTdGF0aXN0aWNzVGFnLkxfUVNfUkVDRUlWRV9DQUxMX1M6XG4gICAgICAgIGRhdGEgPSB7XG4gICAgICAgICAgLi4uY29tbW9uRGF0YSxcbiAgICAgICAgICByZjogaW52aXRlU291cmNlLFxuICAgICAgICB9O1xuICAgICAgICBicmVhaztcbiAgICAgIC8qKlxuICAgICAgICog5byC5bi45oyC5patXG4gICAgICAgKi9cbiAgICAgIGNhc2UgUkNDYWxsUGx1c1N0YXRpc3RpY3NUYWcuTF9RU19BQk5PUk1BTF9IQU5HVVBfUzpcbiAgICAgICAgZGF0YSA9IHtcbiAgICAgICAgICAuLi5jb21tb25EYXRhLFxuICAgICAgICB9O1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIC8qKlxuICAgICAgICAgKiDlj5HotbfjgIHmjqXlkKzjgIHmjILmlq3pgJror51cbiAgICAgICAgICovXG4gICAgICAgIGRhdGEgPSB7XG4gICAgICAgICAgLi4uY29tbW9uRGF0YSxcbiAgICAgICAgICBkdXI6IG5vd1RpbWUgLSBzdGFydFRpbWUsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oJ0wtY2FsbC1wbHVzLXN0YXRpc3RpYycsIEpTT04uc3RyaW5naWZ5KGRhdGEpLCB0YWcpO1xuXG4gICAgdGhpcy5fbG9nZ2VyLl9fc3RhdGlzdGljcyh0YWcsIEpTT04uc3RyaW5naWZ5KGRhdGEpKTtcbiAgfVxufVxuIiwiLyoqXG4gKiDlr7nor53liqjkvZxcbiAqL1xuZXhwb3J0IGVudW0gRGlhbG9nQWN0aW9uIHtcbiAgLyoqXG4gICAqIOivt+axglxuICAgKi9cbiAgUkVRVUVTVCA9ICdyZXF1ZXN0JyxcbiAgLyoqXG4gICAqIOaOpeWPl1xuICAgKi9cbiAgQUNDRVBUID0gJ2FjY2VwdCcsXG4gIC8qKlxuICAgKiDmi5Lnu51cbiAgICovXG4gIFJFRlVTRSA9ICdyZWZ1c2UnLFxuICAvKipcbiAgICog6K+35rGC5Y+W5raIXG4gICAqL1xuICBDQU5DRUwgPSAnY2FuY2VsJyxcbiAgLyoqXG4gICAqIOmAmuefpVxuICAgKi9cbiAgTk9USUNFID0gJ25vdGljZScsXG4gIC8qKlxuICAgKiDotoXml7ZcbiAgICovXG4gIFRJTUVPVVQgPSAndGltZW91dCdcbn1cbiIsIi8qKlxuICog5a+56K+d57G75Z6LXG4gKi9cbmV4cG9ydCBlbnVtIERpYWxvZ1R5cGUge1xuICBTV0lUQ0hfTUVESUFfVFlQRSA9IDFcbn1cbiIsIi8qKlxuICog6YCa6K+d6aKd5aSW57G75Z6L77yI56e75Yqo56uv54m55pyJ77yJXG4gKi9cbmV4cG9ydCBlbnVtIFNlY3JldENhbGxUeXBlIHtcbiAgLyoqXG4gICAqIOaZrumAmumAmuivnVxuICAgKi9cbiAgTk9STUFMLFxuICAvKipcbiAgICog5a+G6IGKXG4gICAqL1xuICBTRUNSRVRcbn1cbiIsImltcG9ydCB7IEJhc2ljTG9nZ2VyLCBFdmVudEVtaXR0ZXIgfSBmcm9tICdAcm9uZ2Nsb3VkL2VuZ2luZSc7XG5pbXBvcnQgeyBEaWFsb2dBY3Rpb24gfSBmcm9tICcuLi9lbnVtcy9EaWFsb2dBY3Rpb24nO1xuaW1wb3J0IHsgUkNDYWxsUGx1c01lZGlhVHlwZSB9IGZyb20gJy4uL2VudW1zL1JDQ2FsbFBsdXNNZWRpYVR5cGUnO1xuaW1wb3J0IHsgUkNDYWxsUGx1c0NhbGxTdGF0ZSB9IGZyb20gJy4uL2VudW1zL1JDQ2FsbFNlc3Npb25TdGF0ZSc7XG5pbXBvcnQgeyBSQ0NhbGxQbHVzVHlwZSB9IGZyb20gJy4uL2VudW1zL1JDQ2FsbFR5cGUnO1xuaW1wb3J0IHsgUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUgfSBmcm9tICcuLi9lbnVtcy9SQ0NhbGxTZXNzaW9uVXNlclN0YXRlJztcbmltcG9ydCB7IElTZXNzaW9uVXNlciB9IGZyb20gJy4uL2ludGVyZmFjZXMvSVJDQ2FsbENsaWVudCc7XG5pbXBvcnQgeyB2YWxpZGF0ZVN5c1N0YXRlLCB2YWxpZGF0ZVVzZXJTdGF0ZSB9IGZyb20gJy4uL3V0aWxzL2hlbHBlcic7XG5pbXBvcnQgeyBSQ0NhbGxQbHVzTG9nZ2VyVGFnIH0gZnJvbSAnLi4vYXBpL2VudW1zL1JDQ2FsbFBsdXNMb2dnZXJUYWcnO1xuaW1wb3J0IHsgUkNDYWxsUGx1c1JlYXNvbiB9IGZyb20gJy4uL2FwaS9lbnVtcy9SQ0NhbGxQbHVzUmVhc29uJztcblxuZXhwb3J0IGVudW0gQ2FsbFRpbWVyRXZlbnRUeXBlIHtcbiAgSU5WSVRFUiA9ICdpbnZpdGVyJyxcbiAgSU5WSVRFRSA9ICdpbnZpdGVlJ1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElPbGREaWFsb2dEYXRhe1xuICB0cmFuc2FjdGlvbklkPzogc3RyaW5nO1xuICBhY3Rpb246IERpYWxvZ0FjdGlvbjtcbiAgbWVkaWFUeXBlOiBSQ0NhbGxQbHVzTWVkaWFUeXBlO1xufVxuXG4vKipcbiAqIFNESyDlhoXpg6jkvb/nlKggU2Vzc2lvbiDlrp7kvotcbiAqL1xuZXhwb3J0IGNsYXNzIFJDQ2FsbElubmVyU2Vzc2lvbiBleHRlbmRzIEV2ZW50RW1pdHRlciB7XG4gIC8qKlxuICAgKiDor7fmsYLmm7TmlrDnmoQgbWVkaWFUeXBlXG4gICAqL1xuICBwcml2YXRlIF9yZXFNZWRpYVR5cGUhOiBSQ0NhbGxQbHVzTWVkaWFUeXBlIHwgbnVsbFxuXG4gIC8qKlxuICAgKiDpgoDor7fogIXotoXml7borqHml7blmahcbiAgICovXG4gIHByaXZhdGUgX2ludml0ZXJUaW1lcklkITogbnVtYmVyXG5cbiAgLyoqXG4gICAqIOiiq+mCgOivt+iAhei2heaXtuiuoeaXtuWZqFxuICAgKi9cbiAgcHJpdmF0ZSBfaW52aXRlZVRpbWVySWQhOiBudW1iZXJcblxuICAvKipcbiAgICog5b2T5YmNIHNlc3Npb24g5Lq65ZGY5L+h5oGv5YiX6KGoXG4gICAqL1xuICAvLyBwcml2YXRlIF9jYWxsVXNlcnM6IElTZXNzaW9uVXNlcltdID0gW11cblxuICAvKipcbiAgICog5penIGRpYWxvZyDmlbDmja7vvIznlKjkuo7lr7nmr5RcbiAgICovXG4gIHByaXZhdGUgX29sZERpYWxvZ0RhdGEhOiBJT2xkRGlhbG9nRGF0YVxuXG4gIC8qKlxuICAgKiDorrDlvZXmmK/lkKbmnKzlnLDmnInmjILmlq1cbiAgICovXG4gIHByaXZhdGUgaXNMb2NhbENsaWVudEhhbmd1cDogYm9vbGVhbiA9IGZhbHNlXG5cbiAgLyoqXG4gICAqIOaehOmAoOWZqFxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgICogQ2FsbCBJRFxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NhbGxJZDogc3RyaW5nLFxuICAgIC8qKlxuICAgICAqIHNlc3Npb24g54q25oCBXG4gICAgICovXG4gICAgcHJpdmF0ZSBfc3RhdGU6IFJDQ2FsbFBsdXNDYWxsU3RhdGUsXG4gICAgLyoqXG4gICAgICog6YCa6K+d57G75Z6LXG4gICAgICovXG4gICAgcHJpdmF0ZSBfY2FsbFR5cGU6IFJDQ2FsbFBsdXNUeXBlLFxuICAgIC8qKlxuICAgICAqIOmAmuivneWqkuS9k+exu+Wei1xuICAgICAqL1xuICAgIHByaXZhdGUgX21lZGlhVHlwZTogUkNDYWxsUGx1c01lZGlhVHlwZSxcbiAgICAvKipcbiAgICAgKiBzZXNzaW9uIOWRvOWPq+WPkei1t+iAhVxuICAgICAqL1xuICAgIHByaXZhdGUgX3N0YXJ0Q2FsbGVySWQ6IHN0cmluZyxcbiAgICAvKipcbiAgICAgKiDmnKzmrKEgc2Vzc2lvbiDnmoTpgoDor7fogIVcbiAgICAgKi9cbiAgICBwcml2YXRlIF9jYWxsZXJJZDogc3RyaW5nLFxuICAgIC8qKlxuICAgICAqIOW9k+WJjSBzZXNzaW9uIOS6uuWRmOS/oeaBr+WIl+ihqFxuICAgICAqL1xuICAgIHByaXZhdGUgX2NhbGxVc2VyczogSVNlc3Npb25Vc2VyW10sXG4gICAgcHJpdmF0ZSByZWFkb25seSBfbG9nZ2VyOiBCYXNpY0xvZ2dlcixcbiAgKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDojrflj5YgQ2FsbElEXG4gICAqL1xuICBwdWJsaWMgZ2V0Q2FsbElkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX2NhbGxJZDtcbiAgfVxuXG4gIC8qKlxuICAgKiDojrflj5bnirbmgIFcbiAgICovXG4gIHB1YmxpYyBnZXRTZXNzaW9uU3RhdGUoKTogUkNDYWxsUGx1c0NhbGxTdGF0ZSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRlO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPlumAmuivneexu+Wei1xuICAgKi9cbiAgcHVibGljIGdldENhbGxUeXBlKCk6IFJDQ2FsbFBsdXNUeXBlIHtcbiAgICByZXR1cm4gdGhpcy5fY2FsbFR5cGU7XG4gIH1cblxuICAvKipcbiAgICog6I635Y+W5aqS5L2T57G75Z6LXG4gICAqL1xuICBwdWJsaWMgZ2V0TWVkaWFUeXBlKCk6IFJDQ2FsbFBsdXNNZWRpYVR5cGUge1xuICAgIHJldHVybiB0aGlzLl9tZWRpYVR5cGU7XG4gIH1cblxuICAvKipcbiAgICog6I635Y+WIHNlc3Npb24g5Y+R6LW36ICFXG4gICAqL1xuICBwdWJsaWMgZ2V0U3RhcnRDYWxsZXJJZCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9zdGFydENhbGxlcklkO1xuICB9XG5cbiAgLyoqXG4gICAqIOacrOasoSBzZXNzaW9uIOmCgOivt+iAhVxuICAgKi9cbiAgcHVibGljIGdldENhbGxlcklkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX2NhbGxlcklkO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPliBzZXNzaW9uIHVzZXIgbGlzdFxuICAgKi9cbiAgcHVibGljIGdldFVzZXJMaXN0KCk6IElTZXNzaW9uVXNlcltdIHtcbiAgICByZXR1cm4gdGhpcy5fY2FsbFVzZXJzO1xuICB9XG5cbiAgLyoqXG4gICAqIOivt+axguabtOaWsOeahCBtZWRpYVR5cGVcbiAgICovXG4gIHB1YmxpYyBnZXRSZXFNZWRpYVR5cGUoKTogUkNDYWxsUGx1c01lZGlhVHlwZSB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9yZXFNZWRpYVR5cGU7XG4gIH1cblxuICAvKipcbiAgICogaW52aXRlclRpbWVySWRcbiAgICovXG4gIHB1YmxpYyBnZXRJbnZpdGVyVGltZXJJZCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9pbnZpdGVyVGltZXJJZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBpbnZpdGVlVGltZXJJZFxuICAgKi9cbiAgcHVibGljIGdldEludml0ZWVUaW1lcklkKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX2ludml0ZWVUaW1lcklkO1xuICB9XG5cbiAgcHVibGljIGdldEFsbFRpbWVySWRzKCk6IG51bWJlcltdIHtcbiAgICByZXR1cm4gW3RoaXMuX2ludml0ZXJUaW1lcklkLCB0aGlzLl9pbnZpdGVlVGltZXJJZF07XG4gIH1cblxuICBwdWJsaWMgc2V0VXNlckRldmljZUVuYWJsZSh1c2VySWQ6IHN0cmluZywgbWVkaWFUeXBlOiBSQ0NhbGxQbHVzTWVkaWFUeXBlLCBlbmFibGU6IGJvb2xlYW4sIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9JTk5FUl9TRVNTSU9OX1NFVF9VU0VSX0RFVklDRV9FTkFCTEVfTywgYHVzZXJJZDogJHt1c2VySWR9LCBtZWRpYVR5cGU6ICR7bWVkaWFUeXBlfSwgZW5hYmxlOiAke2VuYWJsZX1gLCB0cmFjZUlkKTtcbiAgICBjb25zdCB1c2VyU3RhdGUgPSB0aGlzLl9jYWxsVXNlcnMuZmluZCgoaXRlbSkgPT4gdXNlcklkID09PSBpdGVtLnVzZXJJZCk7XG4gICAgaWYgKG1lZGlhVHlwZSA9PT0gUkNDYWxsUGx1c01lZGlhVHlwZS5BVURJTykge1xuICAgICAgdXNlclN0YXRlIS5taWNyb3Bob25lRW5hYmxlID0gZW5hYmxlO1xuICAgIH0gZWxzZSB7XG4gICAgICB1c2VyU3RhdGUhLmNhbWVyYUVuYWJsZSA9IGVuYWJsZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog5pu05paw5Lq65ZGY5YiX6KGoLCDlubbov5Tlm57mm7TmlrDnmoTkurrlkZjliJfooahcbiAgICog5qC55o2u5Lq65ZGY54q25oCB5Y675re75Yqg44CB5Yig6Zmk44CB5pu05pawXG4gICAqIOagueaNrueKtuaAgeaXtumXtO+8jOWIpOaWreaYr+WQpuabtOaWsO+8jOaXoOaXtumXtOaIs+eahOS4uuacrOWcsOeKtuaAgeiwg+aVtO+8jOebtOaOpeabtOaWsFxuICAgKi9cbiAgcHVibGljIHVwZGF0ZVVzZXJMaXN0KHVzZXJzOiBJU2Vzc2lvblVzZXJbXSwgdHJhY2VJZDogc3RyaW5nKTogSVNlc3Npb25Vc2VyW10ge1xuICAgIGNvbnN0IGNoYW5nZWRVc2VyczogSVNlc3Npb25Vc2VyW10gPSBbXTtcbiAgICB1c2Vycy5mb3JFYWNoKCh1c2VyKSA9PiB7XG4gICAgICBjb25zdCB7XG4gICAgICAgIHVzZXJTdGF0ZTogbmV3VXNlclN0YXRlLFxuICAgICAgICBzdGF0ZVRpbWU6IG5ld1N0YXRlVGltZSxcbiAgICAgICAgc3lzdGVtU3RhdGU6IG5ld1N5c1N0YXRlLFxuICAgICAgfSA9IHVzZXI7XG4gICAgICBjb25zdCBuZWVkQWRkU3RhdGVzID0gW1JDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLkNBTExJTkcsIFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLklOVklURUQsIFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLkJVU1lMSU5FX1dBSVRdO1xuICAgICAgaWYgKG5lZWRBZGRTdGF0ZXMuaW5jbHVkZXMobmV3VXNlclN0YXRlKSkge1xuICAgICAgICAvLyDnm7TmjqXmt7vliqDmlbDmja5cbiAgICAgICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0lOTkVSX1NFU1NJT05fVVBEQVRFX1VTRVJfU1RBVEVfTywgYHB1c2ggdXNlcjogJHtKU09OLnN0cmluZ2lmeSh1c2VyKX1gLCB0cmFjZUlkKTtcbiAgICAgICAgdGhpcy5fY2FsbFVzZXJzLnB1c2godXNlcik7XG4gICAgICAgIGNoYW5nZWRVc2Vycy5wdXNoKHVzZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8g5pu05paw5pWw5o2uXG4gICAgICAgIGxldCBoYXNVc2VyID0gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fY2FsbFVzZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgdXNlcklkLCBzdGF0ZVRpbWU6IG9sZFN0YXRlVGltZSwgc3lzdGVtU3RhdGU6IG9sZFN5c3RlbVN0YXRlLCB1c2VyU3RhdGU6IG9sZFVzZXJTdGF0ZSxcbiAgICAgICAgICB9ID0gdGhpcy5fY2FsbFVzZXJzW2ldO1xuICAgICAgICAgIGlmICh1c2VySWQgPT09IHVzZXIudXNlcklkKSB7XG4gICAgICAgICAgICBoYXNVc2VyID0gdHJ1ZTtcbiAgICAgICAgICAgIGNvbnN0IGlzSW52YWxpZFN5c1N0YXRlID0gdmFsaWRhdGVTeXNTdGF0ZShvbGRTeXN0ZW1TdGF0ZSwgbmV3U3lzU3RhdGUpO1xuICAgICAgICAgICAgY29uc3QgaXNJbnZhbGlkVXNlclN0YXRlID0gdmFsaWRhdGVVc2VyU3RhdGUob2xkVXNlclN0YXRlLCBuZXdVc2VyU3RhdGUpO1xuXG4gICAgICAgICAgICBjb25zdCBpc0ludmFsaWRPbnBob25lRW5kID0gbmV3U3lzU3RhdGUgPT09IFJDQ2FsbFBsdXNSZWFzb24uT05fUEhPTkVfRU5EICYmIG9sZFN5c3RlbVN0YXRlICE9PSBSQ0NhbGxQbHVzUmVhc29uLk9OX1BIT05FICYmIG5ld1VzZXJTdGF0ZSAhPT0gUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUuSURMRTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiDml6DmlYjnmoTnirbmgIHvvJpcbiAgICAgICAgICAgICAqIOaWsOS4i+WPkeeKtuaAgeeahOaXtumXtOWwj+S6juW9k+WJjeeKtuaAgeeahOaXtumXtCDkuJQgc3lzdGVtU3RhdGUg5ZKMIHVzZXJTdGF0ZSDlnYfmmK/ml6DmlYjnmoRcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYgKChuZXdTdGF0ZVRpbWUgJiYgb2xkU3RhdGVUaW1lICYmIG5ld1N0YXRlVGltZSA8IG9sZFN0YXRlVGltZSkgfHwgKGlzSW52YWxpZFN5c1N0YXRlICYmIGlzSW52YWxpZFVzZXJTdGF0ZSkpIHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2dnZXIud2FybihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfSU5ORVJfU0VTU0lPTl9VUERBVEVfVVNFUl9TVEFURV9PLCBgdGltZW91dCB1c2VyIHN0YXRlOiBvbGQ6JHtKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICB1c2VySWQsIG9sZFN0YXRlVGltZSwgb2xkU3lzdGVtU3RhdGUsIG9sZFVzZXJTdGF0ZSxcbiAgICAgICAgICAgICAgICB9KX07IG5ldzoke0pTT04uc3RyaW5naWZ5KHVzZXIpfWAsIHRyYWNlSWQpO1xuICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0lOTkVSX1NFU1NJT05fVVBEQVRFX1VTRVJfU1RBVEVfTywgYHVwZGF0ZVVzZXJMaXN0IGVycjogJHsoZXJyIGFzIEVycm9yKS5tZXNzYWdlfWAsIHRyYWNlSWQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8g55u05o6l6KaG55uW5pu05pawXG4gICAgICAgICAgICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9JTk5FUl9TRVNTSU9OX1VQREFURV9VU0VSX1NUQVRFX08sIGB1cGRhdGVVc2VyTGlzdCAtPiBjb3ZlciAke0pTT04uc3RyaW5naWZ5KHVzZXIpfWAsIHRyYWNlSWQpO1xuICAgICAgICAgICAgICB0aGlzLl9jYWxsVXNlcnNbaV0gPSB1c2VyO1xuICAgICAgICAgICAgICAhaXNJbnZhbGlkT25waG9uZUVuZCAmJiBjaGFuZ2VkVXNlcnMucHVzaCh1c2VyKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIOaXoOatpOeUqOaIt+ebtOaOpea3u+WKoFxuICAgICAgICBpZiAoIWhhc1VzZXIpIHtcbiAgICAgICAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfSU5ORVJfU0VTU0lPTl9VUERBVEVfVVNFUl9TVEFURV9PLCBgdXBkYXRlVXNlckxpc3QgLT4gbm91c2VyIHB1c2ggJHtKU09OLnN0cmluZ2lmeSh1c2VyKX1gLCB0cmFjZUlkKTtcbiAgICAgICAgICB0aGlzLl9jYWxsVXNlcnMucHVzaCh1c2VyKTtcbiAgICAgICAgICBjaGFuZ2VkVXNlcnMucHVzaCh1c2VyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBjaGFuZ2VkVXNlcnM7XG4gIH1cblxuICBwdWJsaWMgc2V0T2xkRGlhbG9nRGF0YShkYXRhOiBJT2xkRGlhbG9nRGF0YSkge1xuICAgIHRoaXMuX29sZERpYWxvZ0RhdGEgPSBkYXRhO1xuICB9XG5cbiAgLyoqID09PT09PeengeacieaWueazlT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuICAvKipcbiAgICog5pu05pawIHNlc3Npb24g54q25oCBXG4gICAqL1xuICBwdWJsaWMgdXBkYXRlU2Vzc2lvblN0YXRlKHN0YXRlOiBSQ0NhbGxQbHVzQ2FsbFN0YXRlKSB7XG4gICAgdGhpcy5fc3RhdGUgPSBzdGF0ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiDmm7TmlrDpgJror53nsbvlnovvvIjljYfpmY3nuqforr7nva7vvIlcbiAgICovXG4gIHB1YmxpYyB1cGRhdGVDYWxsVHlwZShjYWxsVHlwZTogUkNDYWxsUGx1c1R5cGUpIHtcbiAgICB0aGlzLl9jYWxsVHlwZSA9IGNhbGxUeXBlO1xuICB9XG5cbiAgLyoqXG4gICAqIOabtOaWsOWqkuS9k+exu+Wei++8iOWNh+mZjee6p++8iVxuICAgKi9cbiAgcHVibGljIHVwZGF0ZU1lZGlhVHlwZShtZWRpYVR5cGU6IFJDQ2FsbFBsdXNNZWRpYVR5cGUpIHtcbiAgICB0aGlzLl9tZWRpYVR5cGUgPSBtZWRpYVR5cGU7XG4gIH1cblxuICAvKipcbiAgICog5pu05paw6K+35rGC55qE5aqS5L2T57G75Z6L77yI5Y2H6ZmN57qn77yJXG4gICAqL1xuICBwdWJsaWMgdXBkYXRlUmVxTWVkaWFUeXBlKG1lZGlhVHlwZTogUkNDYWxsUGx1c01lZGlhVHlwZSB8IG51bGwpIHtcbiAgICB0aGlzLl9yZXFNZWRpYVR5cGUgPSBtZWRpYVR5cGU7XG4gIH1cblxuICAvKipcbiAgICog5pu05pawIGludnRlciB0aW1lciBpZFxuICAgKi9cbiAgcHVibGljIHVwZGF0ZVRpbWVySWQodHlwZTogQ2FsbFRpbWVyRXZlbnRUeXBlLCB0aW1lcklkOiBudW1iZXIpIHtcbiAgICBpZiAodHlwZSA9PT0gQ2FsbFRpbWVyRXZlbnRUeXBlLklOVklURVIpIHtcbiAgICAgIHRoaXMuX2ludml0ZXJUaW1lcklkID0gdGltZXJJZDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5faW52aXRlZVRpbWVySWQgPSB0aW1lcklkO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDojrflj5ZcbiAgICovXG4gIHB1YmxpYyBnZXRPbGREaWFsb2dEYXRhKCk6IElPbGREaWFsb2dEYXRhIHtcbiAgICByZXR1cm4gdGhpcy5fb2xkRGlhbG9nRGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiDorr7nva7mmK/lkKbmmK/lt7Hnq6/mjILmlq1cbiAgICovXG4gIHB1YmxpYyBzZXRJc0xvY2FsQ2xpZW50SGFuZ3VwKGlzTG9jYWxDbGllbnRIYW5ndXA6IGJvb2xlYW4pIHtcbiAgICB0aGlzLmlzTG9jYWxDbGllbnRIYW5ndXAgPSBpc0xvY2FsQ2xpZW50SGFuZ3VwO1xuICB9XG5cbiAgcHVibGljIGdldElzTG9jYWxDbGllbnRIYW5ndXAoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaXNMb2NhbENsaWVudEhhbmd1cDtcbiAgfVxufVxuIiwiZXhwb3J0IGVudW0gQ2FsbFNlcnZlckFjdGlvbiB7XG4gIC8qKlxuICAgKiDlvIDlp4vljZXkurrlkbzlj6tcbiAgICovXG4gIFNUQVJUX1NJTkdMRV9DQUxMID0gJ3N0YXJ0U2luZ2xlQ2FsbCcsXG4gIC8qKlxuICAgKiDlvIDlp4vlpJrkurrlkbzlj6tcbiAgICovXG4gIFNUQVJUX0dST1VQX0NBTEwgPSAnc3RhcnRHcm91cENhbGwnLFxuICAvKipcbiAgICog6YKA6K+35aW95Y+L5Yqg5YWl6YCa6K+dXG4gICAqL1xuICBJTlZJVEVfQ0FMTCA9ICdpbnZpdGVDYWxsJyxcbiAgLyoqXG4gICAqIOS4i+WPkemCgOivt+mAmuivneaVsOaNrlxuICAgKi9cbiAgUFVCX0lOVklURV9DQUxMID0gJ3B1Ykludml0ZUNhbGwnLFxuICAvKipcbiAgICog6YCa6K+d5ZON6ZODXG4gICAqL1xuICBSSU5HSU5HX0NBTEwgPSAncmluZ0NhbGwnLFxuICAvKipcbiAgICog5o6l5Y+X6YCa6K+dXG4gICAqL1xuICBBQ0NFUFRfQ0FMTCA9ICdhY2NlcHRDYWxsJyxcbiAgLyoqXG4gICAqIOWKoOWFpemAmuivnVxuICAgKi9cbiAgSk9JTl9DQUxMID0gJ2pvaW5DYWxsJyxcbiAgLyoqXG4gICAqIOaMguaWremAmuivnVxuICAgKi9cbiAgSEFOR1VQX0NBTEwgPSAnaGFuZ3VwQ2FsbCcsXG4gIC8qKlxuICAgKiDpgJror53nirbmgIHkuIrmiqVcbiAgICovXG4gIFNUQVRVU19VUF9DQUxMID0gJ3N0YXR1c1VwQ2FsbCcsXG4gIC8qKlxuICAgKiDpgJror53nirbmgIHkuIvlj5FcbiAgICovXG4gIFNUQVRVU19ET1dOX0NBTEwgPSAnc3RhdHVzRG93bkNhbGwnLFxuICAvKipcbiAgICog6YCa6K+d5LqL5Lu25LiK5oqlXG4gICAqL1xuICBFVkVOVF9VUF9DQUxMID0gJ2V2ZW50VXBDYWxsJyxcbiAgLyoqXG4gICAqIOmAmuivneS6i+S7tuS4i+WPkVxuICAgKi9cbiAgRVZFTlRfRE9XTl9DQUxMID0gJ2V2ZW50RG93bkNhbGwnLFxuICAvKipcbiAgICog5a+56K+d5pWw5o2u5LiK6KGMXG4gICAqL1xuICBESUFMT0dfVVBfQ0FMTCA9ICdkaWFsb2dVcENhbGwnLFxuICAvKipcbiAgICog5a+56K+d5pWw5o2u5LiL6KGMXG4gICAqL1xuICBESUFMT0dfRE9XTl9DQUxMID0gJ2RpYWxvZ0Rvd25DYWxsJyxcbiAgLyoqXG4gICAqIOiOt+WPlueUqOaIt+S8muivneaVsOaNruWIl+ihqFxuICAgKi9cbiAgR0VUX0NBTExfVVNFUl9TRVNTSU9OX0xJU1QgPSAnZ2V0Q2FsbFVTZXJTZXNzaW9uTGlzdCcsXG4gIC8qKlxuICAgKiDml6Xlv5forrDlvZXlkIzmraVcbiAgICovXG4gIFNZTkNfQ0FMTF9MT0cgPSAnc3luY0NhbGxMb2cnLFxuICAvKipcbiAgICog5pel5b+X6K6w5b2V5LiL5Y+RXG4gICAqL1xuICBQVUJfQ0FMTF9MT0cgPSAncHViQ2FsbExvZycsXG4gIC8qKlxuICAgKiDmibnph4/liKDpmaTpgJror53orrDlvZVcbiAgICovXG4gIERFTF9DQUxMX0xPRyA9ICdkZWxldGVDYWxsTG9nJyxcbiAgLyoqXG4gICAqIOafpeivouW9k+WJjeeUqOaIt+W3suacieeahCBjYWxsIOeKtuaAgVxuICAgKi9cbiAgUVJZX0NBTExfU1RBVEUgPSAncXVlcnlVc2VySGFzQ2FsbCcsXG4gIC8qKlxuICAgKiDmn6Xor6IgY2FsbFNlcnZlciDlvZPliY3ml7bpl7TmiLNcbiAgICovXG4gIFFSWV9TUlZfVElNRVNUQU1QID0gJ2dldENhbGxTcnZUaW1lU3RhbXAnLFxuICAvKipcbiAgICog6I635Y+W5b2T5YmN55So5oi36L+b6KGM55qEIGNhbGwg5YiX6KGoXG4gICAqL1xuICBHRVRfQ0FMTF9TVEFURV9MSVNUID0gJ2dldFVzZXJDYWxsU3RhdGVMaXN0JyxcbiAgLyoqXG4gICAqIOa4hemZpOW9k+WJjeeUqOaIt+mAmuivneiusOW9lVxuICAgKi9cbiAgQ0xFQVJfQ0FMTF9MT0cgPSAnY2xlYW5DYWxsTG9nJyxcbiAgLyoqXG4gICAqIOiOt+WPliBjYWxsIOS8muivneS/oeaBr1xuICAgKi9cbiAgR0VUX0NBTExfU0VTU0lPTiA9ICdnZXRDYWxsU2Vzc2lvbicsXG4gIC8qKlxuICAgKiDojrflj5YgY2FsbCDml7bpl7Tkv6Hmga9cbiAgICovXG4gIEdFVF9DQUxMX1RJTUVfSU5GTyA9ICdnZXRDYWxsVGltZUluZm8nLFxuICAvKipcbiAgICog57uT5p2f5b2T5YmN55So5oi35byC5bi455qEY2FsbFNlc3Npb24o5YyF5ZCr5ZCE5Liq6Zi25q61Ke+8jOS4u+imgeeUqOS6juW6lOeUqOW8guW4uOmAgOWHuuWGjeWQr+WKqOOAgeWQhOenjemAmuivneW8guW4uOW9k+S4reOAgumFjOaDheiwg+eUqFxuICAgKi9cbiAgRU5EX0FCTk9STUFMX0NBTEwgPSAnZW5kVXNlckFibm9ybWFsQ2FsbHMnLFxuICAvKipcbiAgICog55So5oi357O757uf54q25oCB5LiK5oqlXG4gICAqL1xuICBTWVNfU1RBVFVTX1VQID0gJ3N5c1N0YXR1c1VwJyxcbiAgLyoqXG4gICAqIOS4iuaKpemAmuivneiusOW9leW3suivu+eKtuaAgVxuICAgKi9cbiAgVVBfQ0FMTF9MT0dfUkVBREVEID0gJ3VwQ2FsbExvZ1JlYWRlZCcsXG4gIC8qKlxuICAgKiDkuIvlj5HpgJror53orrDlvZXlt7Lor7vnirbmgIFcbiAgICovXG4gIFBVQl9DQUxMX0xPR19SRUFERUQgPSAncHViQ2FsbExvZ1JlYWRlZCcsXG4gIC8qKlxuICAgKiDkuIvlj5HkuIvooYzkv6Hku6TmlbDmja7luo/lj7dJZCDvvIjlvLHnvZHooaXlgb/mlrnms5XvvIznp7vliqjnq6/lt7Llrp7njrDvvIxQQyDmnKrlrp7njrDvvIlcbiAgICovXG4gIFBVQl9OQUNLX1NFUV9JRCA9ICdwdWJOQUNLU2VxSWQnLFxuICAvKipcbiAgICog5p+l6K+i5b2T5YmN55So5oi35Y+C5LiO55qE5pyq57uT5p2f55qEY2FsbFNlc3Npb27nmoRDYWxsSWTliJfooajvvIxncm91cOS4k+eUqO+8jOWPr+WcqGdyb3VwY2FsbOe7k+adn+aXtu+8jOihpeWBv+WQhOerr+eahOW/q+aNt+WFpeWPo+aYr+WQpua2iOWkseeahOWIpOaWrVxuICAgKi9cbiAgR0VUX1VTRVJfQ0FMTF9TRVNTSU9OX0lEX0xJU1QgPSAnZ2V0VXNlckNhbGxTZXNzaW9uSWRMaXN0J1xufVxuIiwiZXhwb3J0IGNvbnN0IHRpbWVyU2V0VGltZW91dCA9IChmdW5jOiBGdW5jdGlvbiwgdGltZW91dDogbnVtYmVyKTogbnVtYmVyID0+IHNldFRpbWVvdXQoZnVuYywgdGltZW91dCkgYXMgbnVtYmVyO1xuXG5leHBvcnQgY29uc3QgdGltZXJJbnRlcnZhbCA9IChmdW46IEZ1bmN0aW9uLCBpdHY6IG51bWJlcik6IG51bWJlciA9PiBzZXRJbnRlcnZhbChmdW4sIGl0dikgYXMgbnVtYmVyO1xuXG5leHBvcnQgY29uc3Qgc2xlZXAgPSAobWlsbGlzZWNvbmQ6IG51bWJlcikgPT4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgc2V0VGltZW91dChyZXNvbHZlLCBtaWxsaXNlY29uZCk7XG59KTtcbiIsImltcG9ydCB7IEVycm9yQ29kZSB9IGZyb20gJ0Byb25nY2xvdWQvZW5naW5lJztcbmltcG9ydCB7IFJDUlRDQ29kZSB9IGZyb20gJ0Byb25nY2xvdWQvcGx1Z2luLXJ0Yyc7XG5pbXBvcnQgeyBDYWxsU2VydmVyRXJyb3JDb2RlIH0gZnJvbSAnLi4vZW51bXMvQ2FsbFNlcnZlckVycm9yQ29kZSc7XG5pbXBvcnQgeyBzbGVlcCB9IGZyb20gJy4vdGltZXJzJztcbmltcG9ydCB7IFJDQ2FsbFBsdXNDb2RlIH0gZnJvbSAnLi4vYXBpL2VudW1zL1JDQ2FsbFBsdXNDb2RlJztcblxuZXhwb3J0IHR5cGUgVFJldHJ5RXJyb3JDb2RlID0gQ2FsbFNlcnZlckVycm9yQ29kZSB8IFJDUlRDQ29kZSB8IG51bWJlciB8IEVycm9yQ29kZVxuZXhwb3J0IGludGVyZmFjZSByZXRyeU9wdGlvbnMge1xuICAvKipcbiAgICog6KaB6YeN6K+V55qE5byC5q2l5Ye95pWwXG4gICAqL1xuICBhc3luY0ZuOiBGdW5jdGlvbjtcbiAgLyoqXG4gICAqIOWHveaVsOeahOWPguaVsFxuICAgKi9cbiAgZm5BcmdzOiBhbnlbXTtcbiAgLyoqXG4gICAqIOW9k+WJjemHjeivleaXtumXtOaIs1xuICAgKi9cbiAgY3VycmVudFJldHJ5VGltZT86IG51bWJlcjtcbiAgLyoqXG4gICAqIOacgOWkp+mHjeivleaXtumVv1xuICAgKi9cbiAgbWF4RHVyYXRpb24/OiBudW1iZXI7XG4gIC8qKlxuICAgKiDmoq/luqbph43or5Xpl7TpmpRcbiAgICovXG4gIGludGVydmFscz86IG51bWJlcltdO1xuICAvKipcbiAgICog5qKv5bqm6YeN6K+V6Ze06ZqU5pWw57uE5LiL5qCHXG4gICAqL1xuICBpbmRleD86IG51bWJlcjtcbiAgLyoqXG4gICAqIOmHjeivleWksei0peeahOWbnuiwg1xuICAgKi9cbiAgb25FcnJvcj86IChjb2RlOiBUUmV0cnlFcnJvckNvZGUpID0+IHZvaWRcbn1cblxuY29uc3QgbmVlZFJldHJ5Q29kZTogVFJldHJ5RXJyb3JDb2RlW10gPSBbXG4gIC8qKlxuICAgKiBJTSDlupXlsYLov5Tlm57pnIDopoHph43or5XnmoTplJnor6/noIFcbiAgICovXG4gIEVycm9yQ29kZS5SQ19ORVRfQ0hBTk5FTF9JTlZBTElELFxuICBFcnJvckNvZGUuUkNfTkVUX1VOQVZBSUxBQkxFLFxuICBFcnJvckNvZGUuUkNfTVNHX1JFU1BfVElNRU9VVCxcbiAgLyoqXG4gICAqIFJUQyDov5Tlm57pnIDopoHph43or5XnmoTplJnor6/noIFcbiAgICovXG4gIFJDUlRDQ29kZS5TSUdOQUxfRElTQ09OTkVDVEVELFxuICBSQ1JUQ0NvZGUuUkVRVUVTVF9GQUlMRUQsXG5cbl07XG5cbi8qKlxuICogQHBhcmFtIHJldHJ5T3B0aW9ucy5hc3luY0ZuIOimgemHjeivleeahOW8guatpeWHveaVsFxuICogQHBhcmFtIHJldHJ5T3B0aW9ucy5mbkFyZ3Mg5Ye95pWw55qE5Y+C5pWwXG4gKiBAcGFyYW0gcmV0cnlPcHRpb25zLmN1cnJlbnRSZXRyeVRpbWUg5b2T5YmN6YeN6K+V5pe26Ze05oizXG4gKiBAcGFyYW0gcmV0cnlPcHRpb25zLm1heER1cmF0aW9uIOacgOWkp+mHjeivleaXtumVv1xuICogQHBhcmFtIHJldHJ5T3B0aW9ucy5pbnRlcnZhbHMg5qKv5bqm6YeN6K+V6Ze06ZqUXG4gKiBAcGFyYW0gcmV0cnlPcHRpb25zLmluZGV4IOair+W6pumHjeivlemXtOmalOaVsOe7hOS4i+agh1xuICovXG5leHBvcnQgY29uc3QgcmV0cnlBc3luY0ZuID0gYXN5bmMgPFIgZXh0ZW5kcyB7Y29kZTogVFJldHJ5RXJyb3JDb2RlfT4gKHtcbiAgYXN5bmNGbixcbiAgZm5BcmdzLFxuICBjdXJyZW50UmV0cnlUaW1lID0gRGF0ZS5ub3coKSxcbiAgbWF4RHVyYXRpb24gPSA2MCAqIDEwMDAsXG4gIGludGVydmFscyA9IFsyICogMTAwMCwgNCAqIDEwMDAsIDggKiAxMDAwLCAxNiAqIDEwMDAsIDMyICogMTAwMCwgNjQgKiAxMDAwXSxcbiAgaW5kZXggPSAwLFxuICBvbkVycm9yLFxufTogcmV0cnlPcHRpb25zKTogUHJvbWlzZTxSPiA9PiB7XG4gIGNvbnN0IHJlcyA9IGF3YWl0IGFzeW5jRm4oLi4uZm5BcmdzKTtcbiAgLy8gY29uc3QgaXR2ID0gaW50ZXJ2YWxzW2luZGV4XSB8fCBpbnRlcnZhbHNbaW50ZXJ2YWxzLmxlbmd0aCAtIDFdXG4gIC8vIGluZGV4KytcbiAgLy8gaXR2IOWGmeatuyAyMDAwIG1zICzlkI7nu63pnIDopoHlho3mlL7lvIDmoq/luqbph43or5VcbiAgY29uc3QgaXR2ID0gMiAqIDEwMDA7XG4gIGNvbnN0IGlzTmVlZFJlc29sdmVJbW1lZGlhdGVseSA9IChyZXMuY29kZSA9PT0gUkNDYWxsUGx1c0NvZGUuU1VDQ0VTU1xuICAgIHx8ICFuZWVkUmV0cnlDb2RlLmluY2x1ZGVzKHJlcy5jb2RlKSlcbiAgICB8fCAoKERhdGUubm93KCkgKyBpdHYgLSBjdXJyZW50UmV0cnlUaW1lKSA+IG1heER1cmF0aW9uKTtcblxuICBpZiAoIWlzTmVlZFJlc29sdmVJbW1lZGlhdGVseSkge1xuICAgIG9uRXJyb3IgJiYgb25FcnJvcihyZXMuY29kZSk7XG4gICAgYXdhaXQgc2xlZXAoaXR2KTtcbiAgICByZXR1cm4gcmV0cnlBc3luY0ZuKHtcbiAgICAgIGFzeW5jRm4sXG4gICAgICBmbkFyZ3MsXG4gICAgICBjdXJyZW50UmV0cnlUaW1lLFxuICAgICAgbWF4RHVyYXRpb24sXG4gICAgICBpbnRlcnZhbHMsXG4gICAgICBpbmRleCxcbiAgICAgIG9uRXJyb3IsXG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgcmV0cnlCeVRpbWVPcHRpb25zIHtcbiAgLyoqXG4gICAqIOimgemHjeivleeahOW8guatpeWHveaVsFxuICAgKi9cbiAgYXN5bmNGbjogRnVuY3Rpb247XG4gIC8qKlxuICAgKiDlh73mlbDnmoTlj4LmlbBcbiAgICovXG4gIGZuQXJnczogYW55W107XG4gIC8qKlxuICAgKiDlvZPliY3ph43or5Xml7bpl7TmiLNcbiAgICovXG4gIGN1cnJlbnRSZXRyeVRpbWU/OiBudW1iZXI7XG4gIC8qKlxuICAgKiDmnIDlpKfph43or5XmrKHmlbAsIOm7mOiupCAyIOasoVxuICAgKi9cbiAgbWF4UmV0cnlUaW1lPzogbnVtYmVyO1xuICAvKipcbiAgICog6YeN6K+V5aSx6LSl55qE5Zue6LCDXG4gICAqL1xuICBvbkVycm9yPzogKGNvZGU6IFRSZXRyeUVycm9yQ29kZSkgPT4gdm9pZFxufVxuXG5leHBvcnQgY29uc3QgcmV0cnlBc255Y0ZuQnlUaW1lID0gYXN5bmMgPFIgZXh0ZW5kcyB7Y29kZTogVFJldHJ5RXJyb3JDb2RlfT4gKHtcbiAgYXN5bmNGbixcbiAgZm5BcmdzLFxuICBjdXJyZW50UmV0cnlUaW1lID0gMCxcbiAgbWF4UmV0cnlUaW1lID0gMixcbiAgb25FcnJvcixcbn06IHJldHJ5QnlUaW1lT3B0aW9ucyk6IFByb21pc2U8Uj4gPT4ge1xuICBjb25zdCByZXMgPSBhd2FpdCBhc3luY0ZuKC4uLmZuQXJncyk7XG4gIGNvbnN0IGl0diA9IDIgKiAxMDAwO1xuICBjdXJyZW50UmV0cnlUaW1lKys7XG4gIGNvbnN0IGlzTmVlZFJlc29sdmVJbW1lZGlhdGVseSA9IChyZXMuY29kZSA9PT0gUkNDYWxsUGx1c0NvZGUuU1VDQ0VTU1xuICAgIHx8ICFuZWVkUmV0cnlDb2RlLmluY2x1ZGVzKHJlcy5jb2RlKSkgfHwgY3VycmVudFJldHJ5VGltZSA+IG1heFJldHJ5VGltZTtcblxuICBpZiAoIWlzTmVlZFJlc29sdmVJbW1lZGlhdGVseSkge1xuICAgIG9uRXJyb3IgJiYgb25FcnJvcihyZXMuY29kZSk7XG4gICAgYXdhaXQgc2xlZXAoaXR2KTtcbiAgICByZXR1cm4gcmV0cnlBc255Y0ZuQnlUaW1lKHtcbiAgICAgIGFzeW5jRm4sXG4gICAgICBmbkFyZ3MsXG4gICAgICBjdXJyZW50UmV0cnlUaW1lLFxuICAgICAgbWF4UmV0cnlUaW1lLFxuICAgICAgb25FcnJvcixcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gcmVzO1xufTtcbiIsImltcG9ydCB7IElQdWJJbnZpdGVDb24gfSBmcm9tICcuL0lTaWduYWxUcmFuc3BvcnRlcic7XG5cbmV4cG9ydCBlbnVtIENhbGxIb29rc1R5cGUge1xuICBvbkJlZm9yZVB1Ymxpc2ggPSAnb25CZWZvcmVQdWJsaXNoJyxcbiAgb25QdWJsaXNoUmVzID0gJ29uUHVibGlzaFJlcycsXG4gIG9uUHViSW52aXRlQ2FsbCA9ICdvblB1Ykludml0ZUNhbGwnLFxuICBvblB1Ykludml0ZUNhbGxQdWxsS3YgPSAnb25QdWJJbnZpdGVDYWxsUHVsbEt2JyxcbiAgb25QdWJJbnZpdGVDYWxsTWlzcyA9ICdvblB1Ykludml0ZUNhbGxNaXNzJ1xufVxuXG5leHBvcnQgZW51bSBQdWJJbnZpdGVDYWxsTWlzc1JlYXNvbiB7XG4gIE5PVF9DVVJSRU5UX0RFVklDRUlEID0gJ25vdCBjdXJyZW50IGRldmljZSBpZCcsXG4gIFNFQ1JFVF9DQUxMID0gJ3NlY3JldCBjYWxsJyxcbiAgTk9UX0lOVklURUUgPSAnbm90IGFuIGludml0ZWUnXG59XG5cbmV4cG9ydCBlbnVtIFB1Ykludml0ZUNhbGxNaXNzUmVmZXIge1xuICBQVUJfSU5WSVRFID0gJ3B1Ymludml0ZWNhbGwnLFxuICBQVUxMX0tWX0lOVklURSA9ICdwdWxsa3ZfaW52aXRlY2FsbCcsXG4gIFBVU0ggPSAnc3lzdGVtX3B1YnNoJ1xufVxuXG5leHBvcnQgdHlwZSBJUHViSW52aXRlQ2FsbEluZm8gPSBJUHViSW52aXRlQ29uICYgeyBleHRyYTogc3RyaW5nfVxuXG5leHBvcnQgdHlwZSBJUHViSW52aXRlQ2FsbE1pc3NJbmZvID0gSVB1Ykludml0ZUNvbiAmIHsgZXh0cmE6IHN0cmluZywgcmVhc29uOiBzdHJpbmcsIHJlZmVyOiBQdWJJbnZpdGVDYWxsTWlzc1JlZmVyfVxuIiwiaW1wb3J0IHtcbiAgQmFzaWNMb2dnZXIsIEVycm9yQ29kZSwgRXZlbnRFbWl0dGVyLCBnZXRVVUlEMjIsIElSdW50aW1lLCBpc051bGwsIGlzU3RyaW5nLCBsb2dnZXIsIFBsdWdpbkNvbnRleHQsIFJDQ29ubmVjdGlvblN0YXR1cyxcbn0gZnJvbSAnQHJvbmdjbG91ZC9lbmdpbmUnO1xuaW1wb3J0IHsgQ2FsbFNlcnZlckFjdGlvbiB9IGZyb20gJy4uL2VudW1zL0NhbGxTZXJ2ZXJBY3Rpb24nO1xuaW1wb3J0IHtcbiAgSUFjY2VwdENhbGxDb24sXG4gIElCYXNlU2luZ2FsQ29uLFxuICBJQ2xlYXJDYWxsTG9nUmVzLFxuICBJQ29ucGVuc2F0aW9uRGF0YSxcbiAgSURpYWxvZ0Rvd25DYWxsQ29uLFxuICBJRGlhbG9nVXBDYWxsQ29uLFxuICBJRXZlbnREb3duQ2FsbENvbixcbiAgSUV2ZW50VXBDYWxsQ29uLFxuICBJR2V0Q2FsbFNlc3Npb25TZXJ2ZXJSZXMsXG4gIElHZXRDYWxsVGltZUluZm9SZXMsXG4gIElHZXRVc2VyQ2FsbFN0YXRlTGlzdFJlcyxcbiAgSUhhbmd1cENhbGxDb24sXG4gIElJbnZpdGVDYWxsQ29uLFxuICBJSW52aXRlQ2FsbFJlcyxcbiAgSUpvaW5DYWxsQ29uLFxuICBJUHViQ2FsbExvZyxcbiAgSVB1Ykludml0ZUNvbixcbiAgSVFyeVVzZXJIYXNDYWxsUmVzLFxuICBJUmluZ2luZ0NhbGxDb24sXG4gIElTaWduYWxUcmFuc3BvcnRlckxpc3RlbmVyLFxuICBJU3RhcnRDYWxsQ29uLFxuICBJU3RhcnRDYWxsUmVzLFxuICBJU3RhcnRHcm91cENvbixcbiAgSVN0YXJ0U2luZ2xlQ29uLFxuICBJU3RhdHVzRG93bkNvbnQsXG4gIElTdGF0dXNVcENvbixcbiAgSVN5bmNDYWxsTG9nQ29uLFxuICBJU3luY0NhbGxMb2dSZXNMaXN0LFxuICBJU3lzU3RhdHVzVXBPcHRzLFxufSBmcm9tICcuLi9pbnRlcmZhY2VzL0lTaWduYWxUcmFuc3BvcnRlcic7XG5pbXBvcnQgeyBEaWFsb2dUeXBlIH0gZnJvbSAnLi4vZW51bXMvRGlhbG9nVHlwZSc7XG5pbXBvcnQgeyBJUkNDYWxsSW5pdE9wdGlvbnMgfSBmcm9tICcuLi9pbnRlcmZhY2VzL0lJbmRleCc7XG5pbXBvcnQgeyBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZSB9IGZyb20gJy4uL2VudW1zL1JDQ2FsbFNlc3Npb25Vc2VyU3RhdGUnO1xuaW1wb3J0IHsgVGltZUNvcnJlY3Rpb25lciB9IGZyb20gJy4vVGltZUNvcnJlY3Rpb25lcic7XG5pbXBvcnQgeyByZXRyeUFzeW5jRm4gfSBmcm9tICcuLi91dGlscy9yZXRyeSc7XG5pbXBvcnQgeyBSQ0NhbGxQbHVzVHlwZSB9IGZyb20gJy4uL2VudW1zL1JDQ2FsbFR5cGUnO1xuaW1wb3J0IHtcbiAgQ2FsbEhvb2tzVHlwZSwgUHViSW52aXRlQ2FsbE1pc3NSZWFzb24sIFB1Ykludml0ZUNhbGxNaXNzUmVmZXIsXG59IGZyb20gJy4uL2ludGVyZmFjZXMvSUNhbGxIb29rcyc7XG5pbXBvcnQgeyBSQ0NhbGxQbHVzQ29kZSB9IGZyb20gJy4uL2FwaS9lbnVtcy9SQ0NhbGxQbHVzQ29kZSc7XG5pbXBvcnQgeyBSQ0NhbGxQbHVzTG9nZ2VyVGFnIH0gZnJvbSAnLi4vYXBpL2VudW1zL1JDQ2FsbFBsdXNMb2dnZXJUYWcnO1xuXG5leHBvcnQgY2xhc3MgU2lnbmFsVHJhbnNwb3J0ZXIgZXh0ZW5kcyBFdmVudEVtaXR0ZXIge1xuICAvKipcbiAgICog55uR5ZCs5a+56LGhXG4gICAqL1xuICBfbGlzdGVuZXIhOiBJU2lnbmFsVHJhbnNwb3J0ZXJMaXN0ZW5lclxuXG4gIC8qKlxuICAgKiDpnIDopoHph43or5XnmoQgYWN0aW9uXG4gICAqL1xuICBfbmVlZFJldHJ5QWN0aW9uczogQ2FsbFNlcnZlckFjdGlvbltdID0gW1xuICAgIENhbGxTZXJ2ZXJBY3Rpb24uU1RBUlRfU0lOR0xFX0NBTEwsXG4gICAgQ2FsbFNlcnZlckFjdGlvbi5TVEFSVF9HUk9VUF9DQUxMLFxuICAgIENhbGxTZXJ2ZXJBY3Rpb24uQUNDRVBUX0NBTEwsXG4gICAgQ2FsbFNlcnZlckFjdGlvbi5KT0lOX0NBTEwsXG4gICAgQ2FsbFNlcnZlckFjdGlvbi5FVkVOVF9VUF9DQUxMLFxuICBdXG5cbiAgX3Nlc3Npb25JZDogc3RyaW5nID0gJydcblxuICAvKipcbiAgICogY29uc3RydWN0b3JcbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NvbnRleHQ6IFBsdWdpbkNvbnRleHQsXG4gICAgcHJpdmF0ZSByZWFkb25seSBfcnVudGltZTogSVJ1bnRpbWUsXG4gICAgcHJpdmF0ZSByZWFkb25seSBfaW5pdE9wdHM6IElSQ0NhbGxJbml0T3B0aW9ucyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF90aW1lQ29ycmVjdGlvbmVyOiBUaW1lQ29ycmVjdGlvbmVyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2xvZ2dlcjogQmFzaWNMb2dnZXIsXG4gICkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5fY29udGV4dC5vbkNhbGxJbmZvID0gdGhpcy5fb25SZWN2Q2FsbFNpZ25hbC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX2NvbnRleHQub25jb25uZWN0aW9uc3RhdGVjaGFuZ2UgPSB0aGlzLl9vbklNQ29ubmVjdGlvblN0YXRlQ2hhbmdlLmJpbmQodGhpcyk7XG4gICAgdGhpcy5fc2Vzc2lvbklkID0gZ2V0VVVJRDIyKCk7XG4gIH1cblxuICBnZXRTZXNzaW9uSWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Nlc3Npb25JZDtcbiAgfVxuXG4gIHB1YmxpYyByZWdpc3Rlckxpc3RlbmVyKGxpc3RlbmVyOiBJU2lnbmFsVHJhbnNwb3J0ZXJMaXN0ZW5lcikge1xuICAgIHRoaXMuX2xpc3RlbmVyID0gbGlzdGVuZXI7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc3RhcnRDYWxsKG1zZzogSVN0YXJ0Q2FsbENvbiwgdHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7Y29kZTogbnVtYmVyLCBkYXRhPzogSVN0YXJ0Q2FsbFJlc30+IHtcbiAgICBjb25zdCB7XG4gICAgICBjbGllbnRDYWxsSWQsIGNhbGxUeXBlLCB0b1VzZXJzLCBtZWRpYVR5cGUsIHNlY3JldENoYXQsIHRhcmdldFR5cGUsIHRhcmdldElkLCBuaWNrTmFtZSwgb2xkUm9vbUlkLFxuICAgIH0gPSBtc2c7XG4gICAgaWYgKGNhbGxUeXBlID09PSBSQ0NhbGxQbHVzVHlwZS5TSU5HTEUpIHtcbiAgICAgIHJldHVybiB0aGlzLnN0YXJ0U2luZ2xlQ2FsbCh7XG4gICAgICAgIGNsaWVudENhbGxJZCxcbiAgICAgICAgdG9Vc2VySWQ6IHRvVXNlcnNbMF0udXNlcklkLFxuICAgICAgICBtZWRpYVR5cGUsXG4gICAgICAgIHNlY3JldENoYXQsXG4gICAgICAgIHRhcmdldFR5cGUsXG4gICAgICAgIHRhcmdldElkLFxuICAgICAgICBvbGRSb29tSWQsXG4gICAgICAgIHRvT3JnSWQ6IHRvVXNlcnNbMF0ub3JnSWQgfHwgJycsXG4gICAgICB9LCB0cmFjZUlkKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc3RhcnRHcm91cENhbGwoe1xuICAgICAgY2xpZW50Q2FsbElkLFxuICAgICAgdG9Vc2VycyxcbiAgICAgIG1lZGlhVHlwZSxcbiAgICAgIHRhcmdldFR5cGUsXG4gICAgICB0YXJnZXRJZCxcbiAgICAgIG5pY2tOYW1lLFxuICAgICAgb2xkUm9vbUlkLFxuICAgIH0sIHRyYWNlSWQpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHN0YXJ0U2luZ2xlQ2FsbChtc2c6IElTdGFydFNpbmdsZUNvbiwgdHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7Y29kZTogbnVtYmVyLCBkYXRhPzogSVN0YXJ0Q2FsbFJlc30+IHtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfU0lHTkFMX1RSQU5TUE9SVEVSX1NJTkdMRV9DQUxMX1QsIGBwYXJhbXM6ICR7SlNPTi5zdHJpbmdpZnkobXNnKX1gLCB0cmFjZUlkKTtcbiAgICByZXR1cm4gdGhpcy5fc2VuZENhbGxTaWduYWw8SVN0YXJ0U2luZ2xlQ29uLCBJU3RhcnRDYWxsUmVzPih0aGlzLl9jb250ZXh0LmdldEN1cnJlbnRJZCgpLCBDYWxsU2VydmVyQWN0aW9uLlNUQVJUX1NJTkdMRV9DQUxMLCBtc2cpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHN0YXJ0R3JvdXBDYWxsKG1zZzogSVN0YXJ0R3JvdXBDb24sIHRyYWNlSWQ6IHN0cmluZyk6IFByb21pc2U8e2NvZGU6IG51bWJlciwgZGF0YT86IElTdGFydENhbGxSZXN9PiB7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1NJR05BTF9UUkFOU1BPUlRFUl9HUk9VUF9DQUxMX1QsIGBwYXJhbXM6ICR7SlNPTi5zdHJpbmdpZnkobXNnKX1gLCB0cmFjZUlkKTtcbiAgICByZXR1cm4gdGhpcy5fc2VuZENhbGxTaWduYWw8SVN0YXJ0R3JvdXBDb24sIElTdGFydENhbGxSZXM+KHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudElkKCksIENhbGxTZXJ2ZXJBY3Rpb24uU1RBUlRfR1JPVVBfQ0FMTCwgbXNnKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBpbnZpdGVDYWxsKG1zZzogSUludml0ZUNhbGxDb24sIHRyYWNlSWQ6IHN0cmluZyk6IFByb21pc2U8e2NvZGU6IG51bWJlciwgZGF0YT86IElJbnZpdGVDYWxsUmVzfT4ge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9TSUdOQUxfVFJBTlNQT1JURVJfSU5WSVRFX1QsIGBwYXJhbXM6ICR7SlNPTi5zdHJpbmdpZnkobXNnKX1gLCB0cmFjZUlkKTtcbiAgICByZXR1cm4gdGhpcy5fc2VuZENhbGxTaWduYWw8SUludml0ZUNhbGxDb24sIElJbnZpdGVDYWxsUmVzPihtc2cuY2FsbElkLCBDYWxsU2VydmVyQWN0aW9uLklOVklURV9DQUxMLCBtc2cpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHJpbmdpbmdDYWxsKG1zZzogSVJpbmdpbmdDYWxsQ29uLCB0cmFjZUlkOiBzdHJpbmcpOiBQcm9taXNlPHtjb2RlOiBudW1iZXJ9PiB7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1NJR05BTF9UUkFOU1BPUlRFUl9SSU5HX1QsIGBwYXJhbXM6ICR7SlNPTi5zdHJpbmdpZnkobXNnKX1gLCB0cmFjZUlkKTtcbiAgICByZXR1cm4gdGhpcy5fc2VuZENhbGxTaWduYWw8SVJpbmdpbmdDYWxsQ29uLCB1bmRlZmluZWQ+KG1zZy5jYWxsSWQsIENhbGxTZXJ2ZXJBY3Rpb24uUklOR0lOR19DQUxMLCBtc2cpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGFjY2VwdENhbGwobXNnOiBJQWNjZXB0Q2FsbENvbiwgdHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7Y29kZTogbnVtYmVyfT4ge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9TSUdOQUxfVFJBTlNQT1JURVJfQUNDRVBUX1QsIGBwYXJhbXM6ICR7SlNPTi5zdHJpbmdpZnkobXNnKX1gLCB0cmFjZUlkKTtcbiAgICByZXR1cm4gdGhpcy5fc2VuZENhbGxTaWduYWw8SUFjY2VwdENhbGxDb24sIHVuZGVmaW5lZD4obXNnLmNhbGxJZCwgQ2FsbFNlcnZlckFjdGlvbi5BQ0NFUFRfQ0FMTCwgbXNnKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBqb2luQ2FsbChtc2c6IElKb2luQ2FsbENvbiwgdHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7Y29kZTogbnVtYmVyfT4ge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9TSUdOQUxfVFJBTlNQT1JURVJfSk9JTl9DQUxMX1QsIGBwYXJhbXM6ICR7SlNPTi5zdHJpbmdpZnkobXNnKX1gLCB0cmFjZUlkKTtcbiAgICByZXR1cm4gdGhpcy5fc2VuZENhbGxTaWduYWw8SUpvaW5DYWxsQ29uLCB1bmRlZmluZWQ+KG1zZy5jYWxsSWQsIENhbGxTZXJ2ZXJBY3Rpb24uSk9JTl9DQUxMLCBtc2cpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGhhbmd1cENhbGwobXNnOiBJSGFuZ3VwQ2FsbENvbiwgdHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7Y29kZTogbnVtYmVyfT4ge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9TSUdOQUxfVFJBTlNQT1JURVJfSEFOR1VQX1QsIGBwYXJhbXM6ICR7SlNPTi5zdHJpbmdpZnkobXNnKX1gLCB0cmFjZUlkKTtcbiAgICBjb25zdCB7IGNvZGUgfSA9IGF3YWl0IHRoaXMuX3NlbmRDYWxsU2lnbmFsPElIYW5ndXBDYWxsQ29uLCB1bmRlZmluZWQ+KG1zZy5jYWxsSWQsIENhbGxTZXJ2ZXJBY3Rpb24uSEFOR1VQX0NBTEwsIG1zZyk7XG4gICAgaWYgKGNvZGUgPT09IFJDQ2FsbFBsdXNDb2RlLk5PVF9JTl9DQUxMKSB7XG4gICAgICAvLyDlrZjlnKjljZXlkbwgQSDmjILmlq3lkI7nm7TmjqXouKLlh7ogQu+8jENhbGxTZXJ2ZXIg5bey56e76ZmkIGNhbGwsIEIg5ZCO5YiwIENhbGxTZXJ2ZXIg55qEIGhhbmd1cCDkvJrovazkuLogQ2FsbFNlcnZlckVycm9yQ29kZS5DQUxMX05PVF9FWElTVO+8jOaVheW/veeVpVxuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyB9O1xuICAgIH1cbiAgICByZXR1cm4geyBjb2RlIH07XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc3RhdHVzVXBDYWxsKG1zZzogSVN0YXR1c1VwQ29uLCB0cmFjZUlkOiBzdHJpbmcpOiBQcm9taXNlPHtjb2RlOiBudW1iZXJ9PiB7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1NJR05BTF9UUkFOU1BPUlRFUl9DQUxMX1NUQVRVU19VUF9ULCBgY2FsbCBzdGF0dXMgdXAgcGFyYW1zOiAke0pTT04uc3RyaW5naWZ5KG1zZyl9YCwgdHJhY2VJZCk7XG4gICAgcmV0dXJuIHRoaXMuX3NlbmRDYWxsU2lnbmFsPElTdGF0dXNVcENvbiwgdW5kZWZpbmVkPihtc2cuY2FsbElkLCBDYWxsU2VydmVyQWN0aW9uLlNUQVRVU19VUF9DQUxMLCBtc2cpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGV2ZW50VXBDYWxsKG1zZzogSUV2ZW50VXBDYWxsQ29uLCB0cmFjZUlkOiBzdHJpbmcpOiBQcm9taXNlPHtjb2RlOiBudW1iZXJ9PiB7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1NJR05BTF9UUkFOU1BPUlRFUl9DQUxMX0VWRU5UX1VQX1QsIGBwYXJhbXM6ICR7SlNPTi5zdHJpbmdpZnkobXNnKX1gLCB0cmFjZUlkKTtcbiAgICByZXR1cm4gdGhpcy5fc2VuZENhbGxTaWduYWw8SUV2ZW50VXBDYWxsQ29uLCB1bmRlZmluZWQ+KG1zZy5jYWxsSWQsIENhbGxTZXJ2ZXJBY3Rpb24uRVZFTlRfVVBfQ0FMTCwgbXNnKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkaWFsb2dVcENhbGwobXNnOiBJRGlhbG9nVXBDYWxsQ29uLCB0cmFjZUlkOiBzdHJpbmcpOiBQcm9taXNlPHtjb2RlOiBudW1iZXJ9PiB7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1NJR05BTF9UUkFOU1BPUlRFUl9DQUxMX0RJQUxPR19VUF9ULCBgcGFyYW1zOiAke0pTT04uc3RyaW5naWZ5KG1zZyl9YCwgdHJhY2VJZCk7XG4gICAgcmV0dXJuIHRoaXMuX3NlbmRDYWxsU2lnbmFsPElEaWFsb2dVcENhbGxDb24sIHVuZGVmaW5lZD4obXNnLmNhbGxJZCwgQ2FsbFNlcnZlckFjdGlvbi5ESUFMT0dfVVBfQ0FMTCwgbXNnKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkZWxldGVDYWxsUmVjb3JkKHVzZXJJZDogc3RyaW5nLCBjYWxsSWRzOiBzdHJpbmdbXSwgdHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7Y29kZTogbnVtYmVyIH0+IHtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfU0lHTkFMX1RSQU5TUE9SVEVSX0RFTEVURV9DQUxMX1JFQ09SRF9ULCBgY2FsbElkczogJHtKU09OLnN0cmluZ2lmeShjYWxsSWRzKX1gLCB0cmFjZUlkKTtcbiAgICByZXR1cm4gdGhpcy5fc2VuZENhbGxTaWduYWw8e2NhbGxJZHM6IHN0cmluZ1tdfSwgdW5kZWZpbmVkPih1c2VySWQsIENhbGxTZXJ2ZXJBY3Rpb24uREVMX0NBTExfTE9HLCB7XG4gICAgICBjYWxsSWRzLFxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHN5bmNDYWxsTG9nKG1zZzogSVN5bmNDYWxsTG9nQ29uLCB0cmFjZUlkOiBzdHJpbmcpOiBQcm9taXNlPHtjb2RlOiBudW1iZXIsIGRhdGE/OiBJU3luY0NhbGxMb2dSZXNMaXN0fT4ge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9TSUdOQUxfVFJBTlNQT1JURVJfR0VUX0NBTExfUkVDT1JEX1QsIGBwYXJhbXM6ICR7SlNPTi5zdHJpbmdpZnkobXNnKX1gLCB0cmFjZUlkKTtcbiAgICByZXR1cm4gdGhpcy5fc2VuZENhbGxTaWduYWw8SVN5bmNDYWxsTG9nQ29uLCBJU3luY0NhbGxMb2dSZXNMaXN0Pihtc2cudXNlcklkLCBDYWxsU2VydmVyQWN0aW9uLlNZTkNfQ0FMTF9MT0csIG1zZyk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgcXVlcnlVc2VySGFzQ2FsbCgpOiBQcm9taXNlPHtjb2RlOiBudW1iZXIsIGRhdGE/OiBJUXJ5VXNlckhhc0NhbGxSZXN9PiB7XG4gICAgY29uc3QgdXNlcklkID0gdGhpcy5fY29udGV4dC5nZXRDdXJyZW50SWQoKTtcbiAgICByZXR1cm4gdGhpcy5fc2VuZENhbGxTaWduYWw8bnVsbCwgSVFyeVVzZXJIYXNDYWxsUmVzPih1c2VySWQsIENhbGxTZXJ2ZXJBY3Rpb24uUVJZX0NBTExfU1RBVEUsIG51bGwpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGdldENhbGxTZXJ2ZXJUaW1lc3RhbXAodHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7Y29kZTogbnVtYmVyLCBkYXRhPzogeyBzeW5jVGltZTogbnVtYmVyfX0+IHtcbiAgICBjb25zdCB1c2VySWQgPSB0aGlzLl9jb250ZXh0LmdldEN1cnJlbnRJZCgpO1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9TSUdOQUxfVFJBTlNQT1JURVJfR0VUX0NBTExfU0VSVkVSX1RJTUVfVCwgYHVzZXJJZDogJHt1c2VySWR9YCwgdHJhY2VJZCk7XG4gICAgcmV0dXJuIHRoaXMuX3NlbmRDYWxsU2lnbmFsPG51bGwsIHsgc3luY1RpbWU6IG51bWJlcn0+KHVzZXJJZCwgQ2FsbFNlcnZlckFjdGlvbi5RUllfU1JWX1RJTUVTVEFNUCwgbnVsbCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZ2V0Q2FsbFRpbWVJbmZvKGNhbGxJZDogc3RyaW5nLCB0cmFjZUlkOiBzdHJpbmcpOiBQcm9taXNlPHtjb2RlOiBudW1iZXIsIGRhdGE/OiBJR2V0Q2FsbFRpbWVJbmZvUmVzfT4ge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9TSUdOQUxfVFJBTlNQT1JURVJfR0VUX0NBTExfVElNRV9JTkZPX1QsIGBjYWxsSWQ6ICR7Y2FsbElkfWAsIHRyYWNlSWQpO1xuICAgIHJldHVybiB0aGlzLl9zZW5kQ2FsbFNpZ25hbDx7IGNhbGxJZDogc3RyaW5nfSwgSUdldENhbGxUaW1lSW5mb1Jlcz4oY2FsbElkLCBDYWxsU2VydmVyQWN0aW9uLkdFVF9DQUxMX1RJTUVfSU5GTywgeyBjYWxsSWQgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZ2V0VXNlckNhbGxTdGF0ZUxpc3QodHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7Y29kZTogbnVtYmVyLCBkYXRhPzogSUdldFVzZXJDYWxsU3RhdGVMaXN0UmVzfT4ge1xuICAgIGNvbnN0IHVzZXJJZCA9IHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudElkKCk7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1NJR05BTF9UUkFOU1BPUlRFUl9HRVRfQVZBSUxBQkxFX0NBTExfTElTVF9ULCBgdXNlcklkOiAke3VzZXJJZH1gLCB0cmFjZUlkKTtcbiAgICByZXR1cm4gdGhpcy5fc2VuZENhbGxTaWduYWw8bnVsbCwgSUdldFVzZXJDYWxsU3RhdGVMaXN0UmVzPih1c2VySWQsIENhbGxTZXJ2ZXJBY3Rpb24uR0VUX0NBTExfU1RBVEVfTElTVCwgbnVsbCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgY2xlYXJDYWxsUmVjb3JkKHRyYWNlSWQ6IHN0cmluZyk6UHJvbWlzZTx7Y29kZTogbnVtYmVyLCBkYXRhPzogSUNsZWFyQ2FsbExvZ1Jlc30+IHtcbiAgICBjb25zdCB1c2VySWQgPSB0aGlzLl9jb250ZXh0LmdldEN1cnJlbnRJZCgpO1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9TSUdOQUxfVFJBTlNQT1JURVJfQ0xFQVJfQ0FMTF9SRUNPUkRfVCwgYHVzZXJJZDogJHt1c2VySWR9YCwgdHJhY2VJZCk7XG4gICAgcmV0dXJuIHRoaXMuX3NlbmRDYWxsU2lnbmFsPG51bGwsIElDbGVhckNhbGxMb2dSZXM+KHVzZXJJZCwgQ2FsbFNlcnZlckFjdGlvbi5DTEVBUl9DQUxMX0xPRywgbnVsbCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZ2V0Q2FsbFNlc3Npb24ob3B0czogSUJhc2VTaW5nYWxDb24sIHRyYWNlSWQ6IHN0cmluZyk6IFByb21pc2U8e2NvZGU6IG51bWJlciwgZGF0YT86IElHZXRDYWxsU2Vzc2lvblNlcnZlclJlc30+IHtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfU0lHTkFMX1RSQU5TUE9SVEVSX0dFVF9DQUxMX0lORk9fQllfQ0FMTElEX1QsIGBjYWxsSWQ6ICR7b3B0cy5jYWxsSWR9YCwgdHJhY2VJZCk7XG4gICAgcmV0dXJuIHRoaXMuX3NlbmRDYWxsU2lnbmFsPElCYXNlU2luZ2FsQ29uLCBJR2V0Q2FsbFNlc3Npb25TZXJ2ZXJSZXM+KG9wdHMuY2FsbElkLCBDYWxsU2VydmVyQWN0aW9uLkdFVF9DQUxMX1NFU1NJT04sIG9wdHMpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHN5c1N0YXR1c1VwKG9wdHM6IElTeXNTdGF0dXNVcE9wdHMsIHRyYWNlSWQ6IHN0cmluZyk6IFByb21pc2U8e2NvZGU6IG51bWJlcn0+IHtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfU0lHTkFMX1RSQU5TUE9SVEVSX1VTRVJfU1lTVEVNX1NUQVRFX1VQX1QsIGBvcHRzOiAke0pTT04uc3RyaW5naWZ5KG9wdHMpfWAsIHRyYWNlSWQpO1xuICAgIHJldHVybiB0aGlzLl9zZW5kQ2FsbFNpZ25hbDxJU3lzU3RhdHVzVXBPcHRzLCB1bmRlZmluZWQ+KG9wdHMuY2FsbElkLCBDYWxsU2VydmVyQWN0aW9uLlNZU19TVEFUVVNfVVAsIG9wdHMpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHVwQ2FsbExvZ1JlYWRlZChvcHRzOiBJQmFzZVNpbmdhbENvbik6IFByb21pc2U8e2NvZGU6IG51bWJlcn0+IHtcbiAgICBjb25zdCB1c2VySWQgPSB0aGlzLl9jb250ZXh0LmdldEN1cnJlbnRJZCgpO1xuICAgIHJldHVybiB0aGlzLl9zZW5kQ2FsbFNpZ25hbDxJQmFzZVNpbmdhbENvbiwgdW5kZWZpbmVkPih1c2VySWQsIENhbGxTZXJ2ZXJBY3Rpb24uVVBfQ0FMTF9MT0dfUkVBREVELCBvcHRzKTtcbiAgfVxuXG4gIC8qKiA9PT09PT3np4HmnInmlrnms5U9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cbiAgcHJpdmF0ZSBfb25JTUNvbm5lY3Rpb25TdGF0ZUNoYW5nZShzdGF0ZTogUkNDb25uZWN0aW9uU3RhdHVzKSB7XG4gICAgY29uc3QgdHJhY2VJZCA9IHRoaXMuX2xvZ2dlci5jcmVhdGVUcmFjZUlkKCk7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1NJR05BTF9UUkFOU1BPUlRFUl9JTV9TVEFURV9DSEFOR0VfTywgYHN0YXRlOiAke3N0YXRlfWAsIHRyYWNlSWQpO1xuXG4gICAgdGhpcy5fbGlzdGVuZXIub25JTVN0YXRlQ2hhbmdlKHN0YXRlKTtcbiAgICAvKipcbiAgICAgKiDov57mjqXmiJDlip/lkI7lkK/liqjml7bpl7TmoKHmraPlmahcbiAgICAgKi9cbiAgICBpZiAoc3RhdGUgPT09IFJDQ29ubmVjdGlvblN0YXR1cy5DT05ORUNURUQpIHtcbiAgICAgIHRoaXMuX3RpbWVDb3JyZWN0aW9uZXIuc3RhcnQodHJhY2VJZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3RpbWVDb3JyZWN0aW9uZXIuc3RvcCh0cmFjZUlkKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogY2FsbCDkv6Hku6Tlj5HpgIFcbiAgICogQHBhcmFtIHRhcmdldElkIOiOt+WPliBjYWxsIGxvZyAoc3luY0NhbGxMb2cpIOaXtuS8oCB1c2VySWQsIOWFtuS7liBhY3Rpb24g5LygIGNhbGxJZFxuICAgKiBAcGFyYW0ga2V5IGNhbGwgc2VydmVyIOWumuS5iSBhY3Rpb25cbiAgICogQHBhcmFtIG9wdGlvbnMgYWN0aW9uIOaQuuW4puWPguaVsO+8jOaXoOWPguaVsOS8oOepuuWtl+espuS4slxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBfc2VuZENhbGxTaWduYWwgPFQsIFI+KHRhcmdldElkOiBzdHJpbmcsIGtleTogQ2FsbFNlcnZlckFjdGlvbiwgb3B0aW9uczogVCk6IFByb21pc2U8e2NvZGU6IG51bWJlciwgZGF0YT86IFJ9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBvcHRpb25zID8gSlNPTi5zdHJpbmdpZnkoeyAuLi5vcHRpb25zLCAuLi57IHNlc3Npb25JZDogdGhpcy5fc2Vzc2lvbklkIH0gfSkgOiAnJztcblxuICAgIGxldCByZXN1bHQ6IHtkYXRhPzogeyBrZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZ30gfCB1bmRlZmluZWQsIGNvZGU6IEVycm9yQ29kZX07XG4gICAgaWYgKHRoaXMuX25lZWRSZXRyeUFjdGlvbnMuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgcmVzdWx0ID0gYXdhaXQgcmV0cnlBc3luY0ZuIDx7ZGF0YT86IHsga2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmd9IHwgdW5kZWZpbmVkLCBjb2RlOiBFcnJvckNvZGV9Pih7XG4gICAgICAgIGFzeW5jRm46IHRoaXMuX2NvbnRleHQuc2V0Q2FsbEluZm8uYmluZCh0aGlzLl9jb250ZXh0KSxcbiAgICAgICAgZm5BcmdzOiBbdGFyZ2V0SWQsIGtleSwgdmFsdWVdLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdCA9IGF3YWl0IHRoaXMuX2NvbnRleHQuc2V0Q2FsbEluZm8odGFyZ2V0SWQsIGtleSwgdmFsdWUpO1xuICAgIH1cbiAgICBjb25zdCB7IGNvZGUsIGRhdGEgfSA9IHJlc3VsdDtcbiAgICBpZiAoY29kZSAhPT0gRXJyb3JDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICB9XG4gICAgY29uc3QgeyBrZXk6IHNlcnZlcktleSwgdmFsdWU6IHNlcnZlclZhbCB9ID0gZGF0YSE7XG4gICAgY29uc3QgcGFyc2VkRGF0YSA9IEpTT04ucGFyc2Uoc2VydmVyVmFsKS5kYXRhIGFzIFI7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MsXG4gICAgICBkYXRhOiBwYXJzZWREYXRhLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogY2FsbCDkv6Hku6TmjqXmlLZcbiAgICovXG4gIHByaXZhdGUgX29uUmVjdkNhbGxTaWduYWwoZGF0YTogc3RyaW5nKSB7XG4gICAgY29uc3QgdHJhY2VJZCA9IHRoaXMuX2xvZ2dlci5jcmVhdGVUcmFjZUlkKCk7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1NJR05BTF9UUkFOU1BPUlRFUl9SRUNFSVZFX0NBTExfU0lHTkFMX0RBVEFfTywgYGRhdGE6ICR7ZGF0YX1gLCB0cmFjZUlkKTtcblxuICAgIGNvbnN0IGRhdGFMaXN0ID0gSlNPTi5wYXJzZShkYXRhKS5saXN0IGFzIHtba2V5OiBzdHJpbmddOiBzdHJpbmcgfVtdO1xuICAgIGRhdGFMaXN0LmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICAgIGNvbnN0IHsga2V5IH0gPSBpdGVtO1xuICAgICAgY29uc3QgaW5mbyA9IEpTT04ucGFyc2UoaXRlbS52YWx1ZSk7XG4gICAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgICBjYXNlIENhbGxTZXJ2ZXJBY3Rpb24uUFVCX0lOVklURV9DQUxMOlxuICAgICAgICAgIHRoaXMuX29uUHViSW52aXRlQ2FsbChpbmZvIGFzIElQdWJJbnZpdGVDb24sIHRydWUsIHRyYWNlSWQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIENhbGxTZXJ2ZXJBY3Rpb24uU1RBVFVTX0RPV05fQ0FMTDpcbiAgICAgICAgICB0aGlzLl9vblN0YXR1c0Rvd25DYWxsKGluZm8gYXMgSVN0YXR1c0Rvd25Db250LCB0cmFjZUlkKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBDYWxsU2VydmVyQWN0aW9uLkVWRU5UX0RPV05fQ0FMTDpcbiAgICAgICAgICB0aGlzLl9vbkV2ZW50RG93bkNhbGwoaW5mbyBhcyBJRXZlbnREb3duQ2FsbENvbiwgdHJhY2VJZCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgQ2FsbFNlcnZlckFjdGlvbi5ESUFMT0dfRE9XTl9DQUxMOlxuICAgICAgICAgIHRoaXMuX29uRGlhbG9nRG93bkNhbGwoaW5mbyBhcyBJRGlhbG9nRG93bkNhbGxDb24sIHRyYWNlSWQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIENhbGxTZXJ2ZXJBY3Rpb24uUFVCX0NBTExfTE9HOlxuICAgICAgICAgIHRoaXMuX29uUHViQ2FsbExvZyhpbmZvIGFzIElQdWJDYWxsTG9nLCB0cmFjZUlkKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBDYWxsU2VydmVyQWN0aW9uLlBVQl9DQUxMX0xPR19SRUFERUQ6XG4gICAgICAgICAgLy8gcGFzcyDmmoLmnKrnlKjliLBcbiAgICAgICAgICAvLyB0aGlzLl9vblB1YkNhbGxMb2dSZWFkZWQoaW5mbyBhcyBJUHViQ2FsbExvZ1JlYWRlZCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgQ2FsbFNlcnZlckFjdGlvbi5QVUJfTkFDS19TRVFfSUQ6XG4gICAgICAgICAgLy8gVE9ETyBjYWxsIOW8see9keihpeWBv+aWueahiOa2ieWPiuaWueazle+8jFBDIOacquWBmu+8jOatpOWkhOmYsuatoui1sOWIsCBkZWZhdWx0XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhpcy5fb25Db25wZW5zYXRpb25EYXRhKGluZm8gYXMgSUNvbnBlbnNhdGlvbkRhdGEsIHRyYWNlSWQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIOagueaNriBkZXZpY2VJZCDliKTmlq3mlbDmja7mmK/lkKblupTor6XkuIvlj5FcbiAgICogZGV2aWNlSWQg5Li656m65a2X56ym5Liy5oiWIG51bGwg55u05o6l5LiL5Y+RXG4gICAqIGRldmljZUlkIOacieWFt+S9k+eahOWAvO+8jOagueaNriBkZXZpY2VJZCDliKTmlq3mmK/lkKbmmK/lt7Hnq6/nmoQgZGV2aWNlSWRcbiAgICovXG4gIHByaXZhdGUgX2lzVmFsaWREYXRhKGRldmljZUlkOiBzdHJpbmcgfCBudWxsKTogYm9vbGVhbiB7XG4gICAgaWYgKGlzTnVsbChkZXZpY2VJZCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAoaXNTdHJpbmcoZGV2aWNlSWQpICYmIChkZXZpY2VJZD8ubGVuZ3RoID09PSAwIHx8IGRldmljZUlkID09PSB0aGlzLl9zZXNzaW9uSWQpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIOaUtuWIsOmCgOivt1xuICAgKiBAcGFyYW0gaXNEaXJlY3RseSDmmK/lkKbkuLrnm7Tlj5Hkv6Hku6RcbiAgICovXG4gIHByaXZhdGUgX29uUHViSW52aXRlQ2FsbChkYXRhOiBJUHViSW52aXRlQ29uLCBpc0RpcmVjdGx5ID0gdHJ1ZSwgdHJhY2VJZDogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGN1cnJlbnRVSWQgPSB0aGlzLl9jb250ZXh0LmdldEN1cnJlbnRJZCgpO1xuICAgICAgY29uc3QgY3VycmVudFVzZXIgPSBkYXRhLmNhbGxTZXNzaW9uVXNlcnMuZmluZCgoaXRlbSkgPT4gaXRlbS51c2VySWQgPT09IGN1cnJlbnRVSWQpO1xuICAgICAgY29uc3Qgc3RhdGUgPSB0aGlzLl9jb250ZXh0LmdldENvbm5lY3Rpb25TdGF0dXMoKTtcbiAgICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9TSUdOQUxfVFJBTlNQT1JURVJfUkVDRUlWRV9JTlZJVEVfTywgYGN1cnJlbnRVc2VyOiAke0pTT04uc3RyaW5naWZ5KGN1cnJlbnRVc2VyKX0sIGN1cnJlbnRVc2VySWQ6ICR7Y3VycmVudFVJZH0sIHN0YXRlOiAke3N0YXRlfWAsIHRyYWNlSWQpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9TSUdOQUxfVFJBTlNQT1JURVJfUkVDRUlWRV9JTlZJVEVfTywgYGVycm9yOiAkeyhlcnIgYXMgRXJyb3IpLm1lc3NhZ2V9YCwgdHJhY2VJZCk7XG4gICAgfVxuICAgIGlmICghdGhpcy5faXNWYWxpZERhdGEoZGF0YS50b0RldmljZUlkIHx8ICcnKSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLndhcm4oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1NJR05BTF9UUkFOU1BPUlRFUl9SRUNFSVZFX0lOVklURV9PLCBgbm90IGN1cnJlbnQgZGV2aWNlSWQgLT4gZGV2aWNlSW5mbzogJHtKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIHRvRGV2aWNlSWQ6IGRhdGEudG9EZXZpY2VJZCxcbiAgICAgICAgY2xpZW50RGV2aWNlSWQ6IHRoaXMuX3Nlc3Npb25JZCxcbiAgICAgIH0pfWAsIHRyYWNlSWQpO1xuICAgICAgLy8gQSDlkowgQiDnvqTpgJror53kuK3vvIxBIOWGjemCgOivtyBD77yMQiDlkowgQicg6YO95Lya5Lya5pS25YiwIHB1Ykludml0ZUNhbGwsIEInIOaUtuWIsOeahCBwdWJJbnZpdGVDYWxsIOeahCB0b0RldmljZUlkIOS4jeS4uuiHquW3se+8jOaXoOmcgOWkhOeQhlxuXG4gICAgICAvLyBob29rcyDlm57osIPlpITnkIZcbiAgICAgIGNvbnN0IGluZm8gPSB7XG4gICAgICAgIGV4dHJhOiBKU09OLnN0cmluZ2lmeShkYXRhKSxcbiAgICAgICAgcmVhc29uOiBQdWJJbnZpdGVDYWxsTWlzc1JlYXNvbi5OT1RfQ1VSUkVOVF9ERVZJQ0VJRCxcbiAgICAgICAgcmVmZXI6IGlzRGlyZWN0bHkgPyBQdWJJbnZpdGVDYWxsTWlzc1JlZmVyLlBVQl9JTlZJVEUgOiBQdWJJbnZpdGVDYWxsTWlzc1JlZmVyLlBVTExfS1ZfSU5WSVRFLFxuICAgICAgfTtcbiAgICAgIGlmIChpc0RpcmVjdGx5KSB7XG4gICAgICAgIHRoaXMuZW1pdChDYWxsSG9va3NUeXBlLm9uUHViSW52aXRlQ2FsbE1pc3MsIE9iamVjdC5hc3NpZ24oZGF0YSwgaW5mbykpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5lbWl0KENhbGxIb29rc1R5cGUub25QdWJJbnZpdGVDYWxsTWlzcywgT2JqZWN0LmFzc2lnbihkYXRhLCBpbmZvKSk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fbGlzdGVuZXIub25JbnZpdGUoZGF0YSwgaXNEaXJlY3RseSwgdHJhY2VJZCk7XG4gICAgaWYgKGlzRGlyZWN0bHkpIHtcbiAgICAgIHRoaXMuZW1pdChDYWxsSG9va3NUeXBlLm9uUHViSW52aXRlQ2FsbCwgT2JqZWN0LmFzc2lnbihkYXRhLCB7IGV4dHJhOiBKU09OLnN0cmluZ2lmeShkYXRhKSB9KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZW1pdChDYWxsSG9va3NUeXBlLm9uUHViSW52aXRlQ2FsbFB1bGxLdiwgT2JqZWN0LmFzc2lnbihkYXRhLCB7IGV4dHJhOiBKU09OLnN0cmluZ2lmeShkYXRhKSB9KSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOaUtuWIsOeKtuaAgeWPmOabtO+8muWTjemTg+OAgeW/meeijOOAgemAmuivneetieW+heOAgeWvueaWueacquaOpeWQrOOAgeW3seaWueacquaOpeWQrFxuICAgKi9cbiAgcHJpdmF0ZSBfb25TdGF0dXNEb3duQ2FsbChkYXRhOiBJU3RhdHVzRG93bkNvbnQsIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIC8vIOaVsOaNruS4rei/h+a7pOaOieacquWPmOabtOeahCB1c2VyU2Vzc2lvblxuICAgIGRhdGEuY2FsbFNlc3Npb25Vc2VycyA9IGRhdGEuY2FsbFNlc3Npb25Vc2Vycy5maWx0ZXIoKGl0ZW0pID0+IEJvb2xlYW4oaXRlbS5jaGFuZ2VkKSk7XG5cbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfU0lHTkFMX1RSQU5TUE9SVEVSX1JFQ0VJVkVfQ0FMTF9TVEFUVVNfTywgJycsIHRyYWNlSWQpO1xuXG4gICAgaWYgKCF0aGlzLl9pc1ZhbGlkRGF0YShkYXRhLnRvRGV2aWNlSWQgfHwgJycpKSB7XG4gICAgICB0aGlzLl9sb2dnZXIud2FybihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfU0lHTkFMX1RSQU5TUE9SVEVSX1JFQ0VJVkVfQ0FMTF9TVEFUVVNfTywgYG5vdCBjdXJyZW50IGRldmljZUlkIC0+IGRldmljZUluZm86ICR7SlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICB0b0RldmljZUlkOiBkYXRhLnRvRGV2aWNlSWQsXG4gICAgICAgIGNsaWVudERldmljZUlkOiB0aGlzLl9zZXNzaW9uSWQsXG4gICAgICB9KX1gLCB0cmFjZUlkKTtcbiAgICAgIC8vIOS4jeaYr+e7meW9k+WJjeiuvuWkh+S4i+WPkeeahOeKtuaAgeWkhOeQhlxuICAgICAgdGhpcy5fbGlzdGVuZXIub25PdGhlckNsaWVudFN0YXR1c0Rvd24oZGF0YSwgdHJhY2VJZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX2xpc3RlbmVyLm9uU3RhdHVzRG93bihkYXRhLCB0cmFjZUlkLCB0aGlzLl9zZXNzaW9uSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIOaUtuWIsOmAmuivneS6i+S7tuWPmOabtO+8muaJk+W8gHzlhbPpl60g5pGE5YOP5aS0XG4gICAqL1xuICBwcml2YXRlIF9vbkV2ZW50RG93bkNhbGwoZGF0YTogSUV2ZW50RG93bkNhbGxDb24sIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIHRoaXMuX2xpc3RlbmVyLm9uRXZlbnREb3duKGRhdGEsIHRyYWNlSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIOaUtuWIsOmAmuivneiwg+aVtOS6i+S7tuWPiue7k+aenFxuICAgKiDkuovku7bvvJrlqpLkvZPnsbvlnovliIfmjaJcbiAgICog5Yqo5L2c77ya6K+35rGC44CB5o6l5Y+X44CB5ouS57ud44CB5Y+W5raIXG4gICAqL1xuICBwcml2YXRlIF9vbkRpYWxvZ0Rvd25DYWxsKGRhdGE6IElEaWFsb2dEb3duQ2FsbENvbiwgdHJhY2VJZDogc3RyaW5nKSB7XG4gICAgY29uc3QgeyBkaWFsb2dUeXBlLCBhY3Rpb24sIGV4dHJhS2V5VmFsIH0gPSBkYXRhO1xuICAgIHN3aXRjaCAoZGlhbG9nVHlwZSkge1xuICAgICAgY2FzZSBEaWFsb2dUeXBlLlNXSVRDSF9NRURJQV9UWVBFOlxuICAgICAgICB0aGlzLl9saXN0ZW5lci5vblN3aXRjaE1lZGlhVHlwZShkYXRhLCB0cmFjZUlkKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog6YCa6K+d57uT5p2f5ZCO77yM5pel5b+X5LiL5Y+RXG4gICAqL1xuICBwcml2YXRlIF9vblB1YkNhbGxMb2coZGF0YTogSVB1YkNhbGxMb2csIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMX0VOR0lORV9SRUNFSVZFX0NBTExfUkVDT1JEX08sIGBjYWxsIHJlY29yZDogJHtKU09OLnN0cmluZ2lmeShkYXRhKX1gLCB0cmFjZUlkKTtcblxuICAgIHRoaXMuX2xpc3RlbmVyLm9uUmVjdkNhbGxFbmRMb2coZGF0YSwgdHJhY2VJZCk7XG4gIH1cblxuICAvKipcbiAgICog6KGl5YG/5pWw5o2u5aSE55CGXG4gICAqL1xuICBwcml2YXRlIF9vbkNvbnBlbnNhdGlvbkRhdGEoZGF0YTogSUNvbnBlbnNhdGlvbkRhdGEsIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMX0VOR0lORV9SRUNFSVZFX0NPTVBMRU1FTlRBUllfREFUQV9PLCAnJywgdHJhY2VJZCk7XG4gICAgY29uc3Qge1xuICAgICAgY2FsbElkLCBjYWxsVHlwZSwgbWVkaWFUeXBlLCBzZWNyZXRDaGF0LCBkdXJhdGlvbiwgY2FsbFN0YXR1cywgY2FsbGluZ1VzZXJJZCwgY2FsbFNlc3Npb25Vc2VycywgdG9EZXZpY2VJZCwgY2FsbERpYWxvZ0VudGl0eXMsXG4gICAgfSA9IGRhdGE7XG5cbiAgICBjb25zdCBpc1B1Ykludml0ZUNhbGxEYXRhID0gY2FsbFNlc3Npb25Vc2Vycy5zb21lKChpdGVtKSA9PiBpdGVtLnNlc3Npb25TdGF0dXMgPT09IFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLklOVklURUQgJiYgaXRlbS51c2VySWQgPT09IHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudElkKCkpO1xuXG4gICAgaWYgKGlzUHViSW52aXRlQ2FsbERhdGEpIHtcbiAgICAgIHRoaXMuX29uUHViSW52aXRlQ2FsbCh7XG4gICAgICAgIGNhbGxJZCxcbiAgICAgICAgdG9EZXZpY2VJZCxcbiAgICAgICAgY2FsbFR5cGUsXG4gICAgICAgIG1lZGlhVHlwZSxcbiAgICAgICAgaW52aXRlVXNlcklkOiBjYWxsaW5nVXNlcklkLFxuICAgICAgICBjYWxsaW5nVXNlcklkLFxuICAgICAgICBjYWxsU2Vzc2lvblVzZXJzLFxuICAgICAgICBzZWNyZXRDaGF0LFxuICAgICAgfSwgdHJ1ZSwgdHJhY2VJZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX29uU3RhdHVzRG93bkNhbGwoe1xuICAgICAgICBjYWxsSWQsXG4gICAgICAgIHRvRGV2aWNlSWQsXG4gICAgICAgIGNhbGxTdGF0dXMsXG4gICAgICAgIGR1cmF0aW9uLFxuICAgICAgICBjYWxsU2Vzc2lvblVzZXJzLFxuICAgICAgfSwgdHJhY2VJZCk7XG4gICAgfVxuXG4gICAgaWYgKGNhbGxEaWFsb2dFbnRpdHlzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNhbGxEaWFsb2dFbnRpdHlzLmZvckVhY2goKGRhdGEpID0+IHRoaXMuX29uRGlhbG9nRG93bkNhbGwoZGF0YSwgdHJhY2VJZCksIHRoaXMpO1xuICAgIH1cbiAgfVxufVxuIiwiY29uc3Qgc3RyaW5nMTB0bzY0ID0gKG51bWJlcjogbnVtYmVyKSA9PiB7XG4gIGNvbnN0IGNoYXJzID0gJzAxMjM0NTY3ODlhYmNkZWZnaGlna2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUdLTE1OT1BRUlNUVVZXWFlaKy8nLnNwbGl0KCcnKTtcbiAgY29uc3QgcmFkaXggPSBjaGFycy5sZW5ndGggKyAxO1xuICBsZXQgcXV0aWVudCA9ICtudW1iZXI7XG4gIGNvbnN0IGFyciA9IFtdO1xuICBkbyB7XG4gICAgY29uc3QgbW9kID0gcXV0aWVudCAlIHJhZGl4O1xuICAgIHF1dGllbnQgPSAocXV0aWVudCAtIG1vZCkgLyByYWRpeDtcbiAgICBhcnIudW5zaGlmdChjaGFyc1ttb2RdKTtcbiAgfSB3aGlsZSAocXV0aWVudCk7XG4gIHJldHVybiBhcnIuam9pbignJyk7XG59O1xuXG5jb25zdCBnZXRVVUlEID0gKCkgPT4gJ3h4eHh4eHh4LXh4eHgtNHh4eC15eHh4LXh4eHh4eHh4eHh4eCcucmVwbGFjZSgvW3h5XS9nLCAoYykgPT4ge1xuICBjb25zdCByID0gTWF0aC5yYW5kb20oKSAqIDE2IHwgMDtcbiAgY29uc3QgdiA9IGMgPT09ICd4JyA/IHIgOiAociAmIDB4MyB8IDB4OCk7XG4gIHJldHVybiB2LnRvU3RyaW5nKDE2KTtcbn0pO1xuXG4vKiDojrflj5YgMjIg5L2N55qEIFVVSUQgKi9cbmV4cG9ydCBjb25zdCBnZXRVVUlEMjIgPSAoKSA9PiB7XG4gIGxldCB1dWlkOiBzdHJpbmcgfCBudW1iZXIgPSBnZXRVVUlEKCk7XG4gIHV1aWQgPSBgJHt1dWlkLnJlcGxhY2UoLy0vZywgJycpfTBgO1xuICB1dWlkID0gcGFyc2VJbnQodXVpZCwgMTYpO1xuICB1dWlkID0gc3RyaW5nMTB0bzY0KHV1aWQpO1xuICBpZiAodXVpZC5sZW5ndGggPiAyMikge1xuICAgIHV1aWQgPSB1dWlkLnNsaWNlKDAsIDIyKTtcbiAgfVxuICByZXR1cm4gdXVpZDtcbn07XG4iLCJpbXBvcnQgeyBCYXNpY0xvZ2dlciB9IGZyb20gJ0Byb25nY2xvdWQvZW5naW5lJztcblxuY29uc3QgQ0FMTF9EQl9OQU1FID0gJ1JDX0NBTExQTFVTJztcblxuY29uc3QgREJfVkVSU0lPTiA9IDE7XG5cbmludGVyZmFjZSBJT2JqU3RvcmVQYXJhbXMge1xuICAvKipcbiAgICog5Li76ZSuXG4gICAqL1xuICBrZXlQYXRoPzogc3RyaW5nO1xuICAvKipcbiAgICog5aaC5p6c5rKh5pyJ5ZCI6YCC55qE5Li76ZSu77yM5Y+v5Lul6K6+572u5Li6IHRydWUg6Ieq5Yqo55Sf5oiQXG4gICAqL1xuICBhdXRvSW5jcmVtZW50PzogYm9vbGVhblxufVxuXG5pbnRlcmZhY2UgSUluZGV4REJPcHRzIHtcbiAgb25TdWNjZXNzOiAoKSA9PiB2b2lkO1xuICBvbkVycm9yPzogKCkgPT4gdm9pZDtcbn1cblxubGV0IGxvZ2dlcjogQmFzaWNMb2dnZXI7XG5cbmV4cG9ydCBjbGFzcyBSQ0NhbGxJbmRleERCIHtcbiAgLyoqXG4gICAqIGNhbGwgaW5kZXhEQiDlupNcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIF9kYjogSURCRGF0YWJhc2UgfCBudWxsID0gbnVsbFxuXG4gIC8qKlxuICAgKiBSQ0NhbGxJbmRleERCIOWunuS+i1xuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgX2luc3RhbmNlOiBSQ0NhbGxJbmRleERCIHwgbnVsbCA9IG51bGxcblxuICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgc3RhdGljIGluaXQoX2xvZ2dlcjogQmFzaWNMb2dnZXIsIG9wdHM6IElJbmRleERCT3B0cykge1xuICAgIGxvZ2dlciA9IF9sb2dnZXI7XG4gICAgaWYgKCF0aGlzLmlzU3VwcG9ydCgpKSB7XG4gICAgICBsb2dnZXIuaW5mbygnW1JDQ2FsbEluZGV4REJdJywgJ0luZGV4REIgaXMgbm90IHN1cHBvcnQgaW4gdGhlIGN1cnJlbnQgZW52aXJvbm1lbnQnKTtcbiAgICB9XG5cbiAgICBjb25zdCByZXEgPSB3aW5kb3cuaW5kZXhlZERCLm9wZW4oQ0FMTF9EQl9OQU1FLCBEQl9WRVJTSU9OKTtcblxuICAgIHJlcS5vbmVycm9yID0gKGV2OiBhbnkpID0+IHtcbiAgICAgIGxvZ2dlci53YXJuKCdbUkNDYWxsSW5kZXhEQl0nLCBgb3BlbiBpbmRleERCIHJlcSBmYWlsZWQgLT4gJHtldi50YXJnZXQuZXJyb3J9YCk7XG4gICAgfTtcblxuICAgIHJlcS5vbnN1Y2Nlc3MgPSAoZXY6IGFueSkgPT4ge1xuICAgICAgdGhpcy5fZGIgPSBldi50YXJnZXQucmVzdWx0O1xuICAgICAgaWYgKHRoaXMuX2RiKSB7XG4gICAgICAgIHRoaXMuX2RiLm9uY2xvc2UgPSAoZXY6IGFueSkgPT4ge1xuICAgICAgICAgIGxvZ2dlci53YXJuKCdbUkNDYWxsSW5kZXhEQl0nLCBgVGhlIGRiICR7dGhpcy5fZGIhLm5hbWV9IGhhcyB1bmV4cGVjdGVkbHkgY2xvc2VkLiAke2V2fWApO1xuICAgICAgICAgIHRoaXMudW5Jbml0KCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuX2RiLm9uZXJyb3IgPSAoZXY6IGFueSkgPT4ge1xuICAgICAgICAgIGxvZ2dlci53YXJuKCdbUkNDYWxsSW5kZXhEQl0nLCBgVGhlIGRiICR7dGhpcy5fZGIhLm5hbWV9IGhhcyBvcGVuaW5nIGVycm9yLiAke2V2fWApO1xuICAgICAgICAgIHRoaXMudW5Jbml0KCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuX2RiLm9uYWJvcnQgPSAoZXY6IGFueSkgPT4ge1xuICAgICAgICAgIGxvZ2dlci53YXJuKCdbUkNDYWxsSW5kZXhEQl0nLCBgVGhlIGRiICR7dGhpcy5fZGIhLm5hbWV9IGhhcyBvcGVuaW5nIGFib3J0ZWQuICR7ZXZ9YCk7XG4gICAgICAgICAgdGhpcy51bkluaXQoKTtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIFJDQ2FsbEluZGV4REIuX2luc3RhbmNlID0gbmV3IFJDQ2FsbEluZGV4REIoKTtcbiAgICAgIG9wdHMub25TdWNjZXNzKCk7XG4gICAgfTtcblxuICAgIHJlcS5vbnVwZ3JhZGVuZWVkZWQgPSAoZXY6IGFueSkgPT4ge1xuICAgICAgdGhpcy5fZGIgPSBldi50YXJnZXQucmVzdWx0O1xuXG4gICAgICBSQ0NhbGxJbmRleERCLmNyZWF0ZU9ialN0b3JlKCdDYWxsQldfQWJub3JtYWxDYWxsJywgeyBrZXlQYXRoOiAndXNlcklkJyB9KTtcbiAgICB9O1xuICB9XG5cbiAgc3RhdGljIHVuSW5pdCgpIHtcbiAgICB0aGlzLl9kYiA9IG51bGw7XG4gICAgdGhpcy5faW5zdGFuY2UgPSBudWxsO1xuICB9XG5cbiAgc3RhdGljIGdldEluc3RhbmNlKCk6IFJDQ2FsbEluZGV4REIgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5faW5zdGFuY2U7XG4gIH1cblxuICBzdGF0aWMgaXNTdXBwb3J0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnIHx8ICF3aW5kb3cgfHwgIXdpbmRvdy5pbmRleGVkREIpO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZU9ialN0b3JlKG9iak5hbWU6IHN0cmluZywgb3B0czogSU9ialN0b3JlUGFyYW1zKSB7XG4gICAgbGV0IG9ialN0b3JlOiBJREJPYmplY3RTdG9yZTtcbiAgICBpZiAoIVJDQ2FsbEluZGV4REIuX2RiPy5vYmplY3RTdG9yZU5hbWVzLmNvbnRhaW5zKG9iak5hbWUpKSB7XG4gICAgICBvYmpTdG9yZSA9IFJDQ2FsbEluZGV4REIuX2RiIS5jcmVhdGVPYmplY3RTdG9yZShvYmpOYW1lLCBvcHRzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9nZ2VyLmRlYnVnKCdbUkNDYWxsSW5kZXhEQl0nLCBgY3JlYXRlT2JqU3RvcmUgJHtvYmpOYW1lfSBhbHJlYWR5IGV4aXN0c2ApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gb2JqTmFtZSDooajmmI5cbiAgICogQHBhcmFtIHZhbCDopoHmt7vliqDnmoTmlbDmja5cbiAgICovXG4gIHB1YmxpYyBhZGRWYWx1ZSA8VD4ob2JqTmFtZTogc3RyaW5nLCB2YWw6IFQpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgaWYgKCFSQ0NhbGxJbmRleERCLl9kYikge1xuICAgICAgICByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzdG9yZSA9IFJDQ2FsbEluZGV4REIuX2RiLnRyYW5zYWN0aW9uKFtvYmpOYW1lXSwgJ3JlYWR3cml0ZScpLm9iamVjdFN0b3JlKG9iak5hbWUpO1xuICAgICAgY29uc3QgcmVxID0gc3RvcmUuYWRkKHZhbCk7XG5cbiAgICAgIHJlcS5vbnN1Y2Nlc3MgPSAoKSA9PiB7XG4gICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICB9O1xuXG4gICAgICByZXEub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdbUkNDYWxsSW5kZXhEQl0nLCAnYWRkVmFsdWUgZmFpbGVkJyk7XG4gICAgICAgIHJlc29sdmUoZmFsc2UpO1xuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDmoLnmja7kuLvplK7or7vlj5bmlbDmja5cbiAgICogQHBhcmFtIGtleSDkuLvplK5cbiAgICovXG4gIHB1YmxpYyByZWFkQnlLZXkgPFQ+KG9iak5hbWU6IHN0cmluZywga2V5OiBzdHJpbmcpOiBQcm9taXNlPFQgfCBudWxsPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGlmICghUkNDYWxsSW5kZXhEQi5fZGIpIHtcbiAgICAgICAgcmVzb2x2ZShudWxsKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzdG9yZSA9IFJDQ2FsbEluZGV4REIuX2RiLnRyYW5zYWN0aW9uKFtvYmpOYW1lXSkub2JqZWN0U3RvcmUob2JqTmFtZSk7XG5cbiAgICAgIGNvbnN0IHJlcSA9IHN0b3JlLmdldChrZXkpO1xuXG4gICAgICByZXEub25zdWNjZXNzID0gKCkgPT4ge1xuICAgICAgICByZXNvbHZlKHJlcS5yZXN1bHQpO1xuICAgICAgfTtcblxuICAgICAgcmVxLm9uZXJyb3IgPSAoZXYpID0+IHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1tSQ0NhbGxJbmRleERCXScsIGByZWFkQnlLZXkgb25lcnJvciAtPiAke2V2fWApO1xuICAgICAgICByZXNvbHZlKG51bGwpO1xuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDmoLnmja7kuLvplK7mm7TmlrDmlbDmja5cbiAgICovXG4gIHB1YmxpYyB1cGRhdGVCeUtleSA8VD4ob2JqTmFtZTogc3RyaW5nLCBrZXk6IHN0cmluZywgdmFsOiBUKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGlmICghUkNDYWxsSW5kZXhEQi5fZGIpIHtcbiAgICAgICAgcmVzb2x2ZShmYWxzZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3RvcmUgPSBSQ0NhbGxJbmRleERCLl9kYi50cmFuc2FjdGlvbihbb2JqTmFtZV0sICdyZWFkd3JpdGUnKS5vYmplY3RTdG9yZShvYmpOYW1lKTtcblxuICAgICAgY29uc3QgcmVxID0gc3RvcmUucHV0KHZhbCk7XG5cbiAgICAgIHJlcS5vbnN1Y2Nlc3MgPSAoKSA9PiB7XG4gICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICB9O1xuXG4gICAgICByZXEub25lcnJvciA9IChldikgPT4ge1xuICAgICAgICByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1tSQ0NhbGxJbmRleERCXScsIGB1cGRhdGVCeUtleSBvbmVycm9yIC0+ICR7ZXZ9YCk7XG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIHJlbW92ZUJ5S2V5KG9iak5hbWU6IHN0cmluZywga2V5OiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgaWYgKCFSQ0NhbGxJbmRleERCLl9kYikge1xuICAgICAgICByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzdG9yZSA9IFJDQ2FsbEluZGV4REIuX2RiLnRyYW5zYWN0aW9uKFtvYmpOYW1lXSwgJ3JlYWR3cml0ZScpLm9iamVjdFN0b3JlKG9iak5hbWUpO1xuXG4gICAgICBjb25zdCByZXEgPSBzdG9yZS5kZWxldGUoa2V5KTtcblxuICAgICAgcmVxLm9uc3VjY2VzcyA9ICgpID0+IHtcbiAgICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICAgIH07XG5cbiAgICAgIHJlcS5vbmVycm9yID0gKGV2KSA9PiB7XG4gICAgICAgIHJlc29sdmUoZmFsc2UpO1xuICAgICAgICBsb2dnZXIud2FybignW1JDQ2FsbEluZGV4REJdJywgYHJlbW92ZUJ5S2V5IG9uZXJyb3IgLT4gJHtldn1gKTtcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cbn1cbiIsImltcG9ydCB7IEJhc2ljTG9nZ2VyLCBJUnVudGltZSwgSVN0b3JhZ2UgfSBmcm9tICdAcm9uZ2Nsb3VkL2VuZ2luZSc7XG5pbXBvcnQgeyBSQ0NhbGxJbmRleERCIH0gZnJvbSAnLi4vdXRpbHMvaW5kZXhEQic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSU9ialN0b3JlIHtbdXNlcklkOiBzdHJpbmddOiBzdHJpbmdbXX1cblxuaW50ZXJmYWNlIElTdG9yZVZhbCB7dXNlcklkOiBzdHJpbmcsIGNhbGxJZHM6IHN0cmluZ1tdfVxuXG4vKipcbiAqIOW8guW4uOe7k+adnyBjYWxsIOWkhOeQhuWtmOWCqOexu1xuICog5Zyo5ZG85Ye65oiW5ZG85YWl6Zi25q6155qEIGNhbGwg6L+b6KGM5pys5Zyw5a2Y5YKo77yM5q2j5bi457uT5p2f5ZCO5riF6ZmkXG4gKiDlvILluLjnu5PmnZ/lkI7vvIzmnKzlnLDlj5bmnKrmuIXpmaTnmoQgY2FsbElkLCDpgJrov4fmnI3liqHmjqXlj6PmuIXpmaTlvILluLjnu5PmnZ/nmoQgY2FsbCAs6Ziy5q2i5peg5rOV5ZG85Ye65oiW5ZG85YWlXG4gKi9cbmV4cG9ydCBjbGFzcyBBYm5vcm1hbENhbGwge1xuICBwcml2YXRlIF9sb2NhbFN0b3JlITogSVN0b3JhZ2VcblxuICBwcml2YXRlIF9pbmRleERCU3RvcmUhOiBSQ0NhbGxJbmRleERCXG5cbiAgcHJpdmF0ZSBfc3RvcmVLZXk6IHN0cmluZyA9ICdDYWxsQldfQWJub3JtYWxDYWxsJ1xuXG4gIHByaXZhdGUgX2lzU3VwcG9ydEluZGV4REI6IGJvb2xlYW5cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9ydW50aW1lOiBJUnVudGltZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9sb2dnZXI6IEJhc2ljTG9nZ2VyLFxuICApIHtcbiAgICB0aGlzLl9pc1N1cHBvcnRJbmRleERCID0gUkNDYWxsSW5kZXhEQi5pc1N1cHBvcnQoKTtcbiAgICBpZiAodGhpcy5faXNTdXBwb3J0SW5kZXhEQikge1xuICAgICAgUkNDYWxsSW5kZXhEQi5pbml0KHRoaXMuX2xvZ2dlciwge1xuICAgICAgICBvblN1Y2Nlc3M6ICgpID0+IHtcbiAgICAgICAgICB0aGlzLl9pbmRleERCU3RvcmUgPSBSQ0NhbGxJbmRleERCLmdldEluc3RhbmNlKCkhO1xuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX2xvY2FsU3RvcmUgPSBfcnVudGltZS5sb2NhbFN0b3JhZ2U7XG4gIH1cblxuICAvKipcbiAgICog5re75Yqg5byC5bi4IGNhbGxJZFxuICAgKi9cbiAgcHVibGljIGFkZEFibm9ybWFsbENhbGxJZCh1c2VySWQ6IHN0cmluZywgY2FsbElkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBhZGRGdW5jID0gdGhpcy5faXNTdXBwb3J0SW5kZXhEQiA/IHRoaXMuX2FkZEJ5SW5kZXhEQiA6IHRoaXMuX2FkZEJ5TG9jYWxTdG9yZTtcbiAgICBhZGRGdW5jLmNhbGwodGhpcywgdXNlcklkLCBjYWxsSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIOWIoOmZpOW8guW4uCBjYWxsSWRcbiAgICovXG4gIHB1YmxpYyByZW1vdmVBYm5vcm1hbENhbGxJZHModXNlcklkOiBzdHJpbmcsIGNhbGxJZHM6IHN0cmluZ1tdKSB7XG4gICAgY29uc3QgcmVtb3ZlRnVuYyA9IHRoaXMuX2lzU3VwcG9ydEluZGV4REIgPyB0aGlzLl9yZW1vdmVCeUluZGV4REIgOiB0aGlzLl9yZW1vdmVCeUxvY2FsU3RvcmU7XG4gICAgcmVtb3ZlRnVuYy5jYWxsKHRoaXMsIHVzZXJJZCwgY2FsbElkcyk7XG4gIH1cblxuICAvKipcbiAgICog6I635Y+W5byC5bi457uT5p2f55qEIGNhbGxJZCDliJfooahcbiAgICovXG4gIHB1YmxpYyBnZXRBYm5vcm1hbENhbGxJZHModXNlcklkOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZ1tdIHwgbnVsbD4ge1xuICAgIGNvbnN0IGdldEZ1bmMgPSB0aGlzLl9pc1N1cHBvcnRJbmRleERCID8gdGhpcy5fZ2V0QnlJbmRleERCIDogdGhpcy5fZ2V0QnlMb2NhbFN0b3JlO1xuICAgIHJldHVybiBnZXRGdW5jLmNhbGwodGhpcywgdXNlcklkKTtcbiAgfVxuXG4gIHByaXZhdGUgX2FkZEJ5TG9jYWxTdG9yZSh1c2VySWQ6IHN0cmluZywgY2FsbElkOiBzdHJpbmcpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgb2JqU3RvcmU6IElPYmpTdG9yZSA9IDxJT2JqU3RvcmU+SlNPTi5wYXJzZSh0aGlzLl9sb2NhbFN0b3JlLmdldEl0ZW0odGhpcy5fc3RvcmVLZXkpIHx8ICd7fScpO1xuICAgICAgbGV0IHVzZXJBYm5vcm1hbENhbGxJZHMgPSBvYmpTdG9yZVt1c2VySWRdO1xuICAgICAgaWYgKHVzZXJBYm5vcm1hbENhbGxJZHMpIHtcbiAgICAgICAgdXNlckFibm9ybWFsQ2FsbElkcy5wdXNoKGNhbGxJZCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1c2VyQWJub3JtYWxDYWxsSWRzID0gW2NhbGxJZF07XG4gICAgICB9XG4gICAgICBvYmpTdG9yZVt1c2VySWRdID0gdXNlckFibm9ybWFsQ2FsbElkcztcbiAgICAgIHRoaXMuX2xvY2FsU3RvcmUuc2V0SXRlbSh0aGlzLl9zdG9yZUtleSwgSlNPTi5zdHJpbmdpZnkob2JqU3RvcmUpKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci53YXJuKCdbQWJub3JtYWxDYWxsXScsIGBfYWRkQnlMb2NhbFN0b3JlIGVycjogJHsoZXJyIGFzIEVycm9yKS5tZXNzYWdlfWApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX3JlbW92ZUJ5TG9jYWxTdG9yZSh1c2VySWQ6IHN0cmluZywgY2FsbElkczogc3RyaW5nW10pIHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgb2JqU3RvcmU6IElPYmpTdG9yZSA9IDxJT2JqU3RvcmU+SlNPTi5wYXJzZSh0aGlzLl9sb2NhbFN0b3JlLmdldEl0ZW0odGhpcy5fc3RvcmVLZXkpIHx8ICd7fScpO1xuICAgICAgbGV0IHVzZXJBYm5vcm1hbENhbGxJZHMgPSBvYmpTdG9yZVt1c2VySWRdO1xuICAgICAgaWYgKHVzZXJBYm5vcm1hbENhbGxJZHMpIHtcbiAgICAgICAgdXNlckFibm9ybWFsQ2FsbElkcyA9IHVzZXJBYm5vcm1hbENhbGxJZHMuZmlsdGVyKChpZCkgPT4gIWNhbGxJZHMuaW5jbHVkZXMoaWQpKTtcbiAgICAgICAgaWYgKHVzZXJBYm5vcm1hbENhbGxJZHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIG9ialN0b3JlW3VzZXJJZF0gPSB1c2VyQWJub3JtYWxDYWxsSWRzO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSBvYmpTdG9yZVt1c2VySWRdO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fbG9jYWxTdG9yZS5zZXRJdGVtKHRoaXMuX3N0b3JlS2V5LCBKU09OLnN0cmluZ2lmeShvYmpTdG9yZSkpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5fbG9nZ2VyLndhcm4oJ1tBYm5vcm1hbENhbGxdJywgYF9yZW1vdmVCeUxvY2FsU3RvcmUgZXJyOiAkeyhlcnIgYXMgRXJyb3IpLm1lc3NhZ2V9YCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0QnlMb2NhbFN0b3JlKHVzZXJJZDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmdbXSB8IG51bGw+IHtcbiAgICBsZXQgY2FsbElkcyA9IG51bGw7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG9ialN0b3JlOiBJT2JqU3RvcmUgPSA8SU9ialN0b3JlPkpTT04ucGFyc2UodGhpcy5fbG9jYWxTdG9yZS5nZXRJdGVtKHRoaXMuX3N0b3JlS2V5KSB8fCAne30nKTtcbiAgICAgIGNvbnN0IHVzZXJBYm5vcm1hbENhbGxJZHMgPSBvYmpTdG9yZVt1c2VySWRdO1xuICAgICAgaWYgKHVzZXJBYm5vcm1hbENhbGxJZHMpIHtcbiAgICAgICAgY2FsbElkcyA9IHVzZXJBYm5vcm1hbENhbGxJZHM7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLl9sb2dnZXIud2FybignW0Fibm9ybWFsQ2FsbF0nLCBgX2dldEJ5TG9jYWxTdG9yZSBlcnI6ICR7KGVyciBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShjYWxsSWRzKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgX2FkZEJ5SW5kZXhEQih1c2VySWQ6IHN0cmluZywgY2FsbElkOiBzdHJpbmcpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHRoaXMuX2luZGV4REJTdG9yZS5yZWFkQnlLZXk8SVN0b3JlVmFsPih0aGlzLl9zdG9yZUtleSwgdXNlcklkKTtcbiAgICAgIGlmIChkYXRhKSB7XG4gICAgICAgIGRhdGEuY2FsbElkcy5wdXNoKGNhbGxJZCk7XG4gICAgICAgIHRoaXMuX2luZGV4REJTdG9yZS51cGRhdGVCeUtleSh0aGlzLl9zdG9yZUtleSwgdXNlcklkLCB7XG4gICAgICAgICAgdXNlcklkLFxuICAgICAgICAgIGNhbGxJZHM6IGRhdGEuY2FsbElkcyxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9pbmRleERCU3RvcmUuYWRkVmFsdWUodGhpcy5fc3RvcmVLZXksIHtcbiAgICAgICAgICB1c2VySWQsXG4gICAgICAgICAgY2FsbElkczogW2NhbGxJZF0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5fbG9nZ2VyLndhcm4oJ1tBYm5vcm1hbENhbGxdJywgYF9hZGRCeUluZGV4REIgZXJyOiAkeyhlcnIgYXMgRXJyb3IpLm1lc3NhZ2V9YCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBfcmVtb3ZlQnlJbmRleERCKHVzZXJJZDogc3RyaW5nLCBjYWxsSWRzOiBzdHJpbmdbXSkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgdGhpcy5faW5kZXhEQlN0b3JlLnJlYWRCeUtleTxJU3RvcmVWYWw+KHRoaXMuX3N0b3JlS2V5LCB1c2VySWQpO1xuICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgZGF0YS5jYWxsSWRzID0gZGF0YS5jYWxsSWRzLmZpbHRlcigoaWQpID0+ICFjYWxsSWRzLmluY2x1ZGVzKGlkKSk7XG4gICAgICAgIGlmIChkYXRhLmNhbGxJZHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHRoaXMuX2luZGV4REJTdG9yZS51cGRhdGVCeUtleSh0aGlzLl9zdG9yZUtleSwgdXNlcklkLCB7XG4gICAgICAgICAgICB1c2VySWQsXG4gICAgICAgICAgICBjYWxsSWRzOiBkYXRhLmNhbGxJZHMsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5faW5kZXhEQlN0b3JlLnJlbW92ZUJ5S2V5KHRoaXMuX3N0b3JlS2V5LCB1c2VySWQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLl9sb2dnZXIud2FybignW0Fibm9ybWFsQ2FsbF0nLCBgX3JlbW92ZUJ5SW5kZXhEQiBlcnI6ICR7KGVyciBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIF9nZXRCeUluZGV4REIodXNlcklkOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZ1tdIHwgbnVsbD4ge1xuICAgIGxldCBkYXRhID0gbnVsbDtcbiAgICB0cnkge1xuICAgICAgZGF0YSA9IGF3YWl0IHRoaXMuX2luZGV4REJTdG9yZS5yZWFkQnlLZXk8SVN0b3JlVmFsPih0aGlzLl9zdG9yZUtleSwgdXNlcklkKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci53YXJuKCdbQWJub3JtYWxDYWxsXScsIGBfZ2V0QnlJbmRleERCIGVycjogJHsoZXJyIGFzIEVycm9yKS5tZXNzYWdlfWApO1xuICAgIH1cbiAgICBpZiAoZGF0YSkge1xuICAgICAgcmV0dXJuIGRhdGEuY2FsbElkcztcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cbiIsIi8qKlxuICog5LqL5Lu257G75Z6LXG4gKi9cbmV4cG9ydCBlbnVtIENhbGxTZXJ2ZXJFdmVudFR5cGUge1xuICAvKipcbiAgICog5o+Q56S656qX5Y+jXG4gICAqL1xuICBQUk9NUFQgPSAwLFxuICAvKipcbiAgICogQ2FsbFNlcnZlciDkuIvlj5HpgJror53ml7bplb/lj5jmm7TnsbvlnotcbiAgICovXG4gIENBTExfRFVSQVRJT04gPSAxMCxcbiAgLyoqXG4gICAqIOaUtuWIsOi/nOerr+esrOS4gOW4p+aXtumXtFxuICAgKi9cbiAgRklSU1RfRlJBTUUgPSAyMCxcbn1cbiIsImV4cG9ydCBlbnVtIFJDQ2FsbFBsdXNJbm5lckNvZGUge1xuICBTVUNDRVNTID0gMCxcbiAgLyoqXG4gICAqIOaXoOaViOeahOWTjeW6lOaXtumXtO+8iOaOpeWPo+WTjeW6lOaXtumXtOi/h+mVv++8iVxuICAgKi9cbiAgSU5WQUxJRF9SRVNQT05TRV9USU1FID0gODAxNzAsXG4gIC8qKlxuICAgKiDpnZ7mnIDkvJjlk43lupTml7bpl7RcbiAgICovXG4gIE5PTk9QVElNQUxfUkVTX1RJTUUgPSA4MDE3MSxcbn1cbiIsImltcG9ydCB7IEJhc2ljTG9nZ2VyIH0gZnJvbSAnQHJvbmdjbG91ZC9lbmdpbmUnO1xuaW1wb3J0IHsgUkNDYWxsRW5naW5lIH0gZnJvbSAnLi4vUkNDYWxsRW5naW5lJztcbmltcG9ydCB7IFJDQ2FsbFBsdXNDb2RlIH0gZnJvbSAnLi4vYXBpL2VudW1zL1JDQ2FsbFBsdXNDb2RlJztcbmltcG9ydCB7IHRpbWVyU2V0VGltZW91dCB9IGZyb20gJy4uL3V0aWxzL3RpbWVycyc7XG5pbXBvcnQgeyBSQ0NhbGxQbHVzTG9nZ2VyVGFnIH0gZnJvbSAnLi4vYXBpL2VudW1zL1JDQ2FsbFBsdXNMb2dnZXJUYWcnO1xuaW1wb3J0IHsgUkNDYWxsUGx1c0lubmVyQ29kZSB9IGZyb20gJy4uL2VudW1zL1JDQ2FsbFBsdXNJbm5lckNvZGUnO1xuXG4vKipcbiAqIOagoeaXtuaooeWdl1xuICovXG5leHBvcnQgY2xhc3MgVGltZUNvcnJlY3Rpb25lciB7XG4gIC8qKlxuICAgKiDmjqXlj6Plk43lupTml7bpl7RcbiAgICovXG4gIHByaXZhdGUgX1JUVDogbnVtYmVyID0gMFxuXG4gIC8qKlxuICAgKiDlj6/nlKjnmoTmjqXlj6Plk43lupTml7bpl7TkuIvpmZDvvIjljZXkvY06IG1z77yJXG4gICAqL1xuICBwcml2YXRlIF92YWxpZE1pblJUVDogbnVtYmVyID0gMjAwXG5cbiAgLyoqXG4gICAqIOWPr+eUqOeahOaOpeWPo+WTjeW6lOaXtumXtOS4iumZkO+8iOWNleS9jTogbXPvvIlcbiAgICovXG4gIHByaXZhdGUgX3ZhbGlkTWF4UlRUOiBudW1iZXIgPSAxMDAwXG5cbiAgLyoqXG4gICAqIOS4jiBjYWxsU2VydmVyIOeahOaXtumXtOWBj+W3ruaXtumXtO+8iOWNleS9jTogbXPvvIlcbiAgICovXG4gIHByaXZhdGUgX2RlbHRhVGltZTogbnVtYmVyID0gMFxuXG4gIC8qKlxuICAgKiB0aW1lcklkXG4gICAqL1xuICBwcml2YXRlIF90aW1lcklkOiBudW1iZXIgfCBudWxsID0gbnVsbFxuXG4gIC8qKlxuICAgKiDova7orq3ml7bpl7Tpl7TpmpTvvIjljZXkvY06IG1z77yJXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IF9pbnRlcnZhbDogbnVtYmVyID0gMiAqIDEwMDBcblxuICAvKipcbiAgICog5pyA5aSn6YeN6K+V5qyh5pWwXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IF9tYXhSZXRyeVRpbWVzOiBudW1iZXIgPSA4XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBfY2FsbEVuZ2luZTogUkNDYWxsRW5naW5lLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2xvZ2dlcjogQmFzaWNMb2dnZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBfc2luZ2xlQ2FsbER1cmF0aW9uRXY6IChjYWxsSWQ6IHN0cmluZywgY2xpZW50U3RhcnRUaW1lOiBudW1iZXIsIGNsaWVudEZpcnN0RnJhbWVUaW1lOiBudW1iZXIsIHRyYWNlSWQ6IHN0cmluZykgPT4gdm9pZCxcbiAgKSB7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiDku47mnI3liqHnq6/ojrflj5bpgJror53ml7bplb/jgIHpgJror53lvIDlp4vml7bpl7RcbiAgICovXG4gIHB1YmxpYyBhc3luYyBnZXRDYWxsQ2xpZW50VGltZUJ5U2VydmVyKGNhbGxJZDogc3RyaW5nLCB0cmFjZUlkOiBzdHJpbmcpOiBQcm9taXNlPHsgY29kZTogbnVtYmVyLCBkdXJhdGlvbj86IG51bWJlciwgY2xpZW50U3RhcnRUaW1lPzogbnVtYmVyIH0+IHtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfVElNRV9DT1JSRUNUX0dFVF9DQUxMX0NMSUVOVF9USU1FX0JZX1NFUlZFUl9ULCBgY2FsbElkOiAke2NhbGxJZH1gLCB0cmFjZUlkKTtcbiAgICBpZiAoIXRoaXMuX1JUVCB8fCB0aGlzLl9SVFQgPiB0aGlzLl92YWxpZE1pblJUVCkge1xuICAgICAgYXdhaXQgdGhpcy5fZ2V0RGVsdGFUaW1lKHRyYWNlSWQpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9SVFQgPiB0aGlzLl92YWxpZE1heFJUVCkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9USU1FX0NPUlJFQ1RfR0VUX0NBTExfQ0xJRU5UX1RJTUVfQllfU0VSVkVSX1IsIGBjb2RlOiAke1JDQ2FsbFBsdXNJbm5lckNvZGUuSU5WQUxJRF9SRVNQT05TRV9USU1FfWAsIHRyYWNlSWQpO1xuICAgICAgLy8gcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0lubmVyQ29kZS5JTlZBTElEX1JFU1BPTlNFX1RJTUUgfTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGNvZGUsIGRhdGEgfSA9IGF3YWl0IHRoaXMuX2NhbGxFbmdpbmUuZ2V0Q2FsbFRpbWVJbmZvKGNhbGxJZCwgdHJhY2VJZCk7XG4gICAgaWYgKGNvZGUgIT09IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfVElNRV9DT1JSRUNUX0dFVF9DQUxMX0NMSUVOVF9USU1FX0JZX1NFUlZFUl9SLCBgY29kZTogJHtjb2RlfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZSB9O1xuICAgIH1cblxuICAgIGNvbnN0IHsgc3RhcnRUaW1lOiBzZXJ2ZXJTdGFydFRpbWUgfSA9IGRhdGEhO1xuICAgIGNvbnN0IGNsaWVudFN0YXJ0VGltZSA9IE1hdGguZmxvb3Ioc2VydmVyU3RhcnRUaW1lIC0gdGhpcy5fZGVsdGFUaW1lKTtcbiAgICBjb25zdCBjdXJyZW50VGltZSA9IERhdGUubm93KCk7XG4gICAgbGV0IGR1cmF0aW9uID0gKGN1cnJlbnRUaW1lICsgdGhpcy5fZGVsdGFUaW1lIC0gc2VydmVyU3RhcnRUaW1lKSAvIDEwMDA7XG5cbiAgICBpZiAoZHVyYXRpb24gPCAwKSB7XG4gICAgICB0aGlzLl9sb2dnZXIud2FybihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfVElNRV9DT1JSRUNUX0dFVF9DQUxMX0NMSUVOVF9USU1FX0JZX1NFUlZFUl9QLCBgaW52YWxpZCBkdXJhdGlvbjogJHtkdXJhdGlvbn1gLCB0cmFjZUlkKTtcbiAgICAgIGR1cmF0aW9uID0gMDtcbiAgICB9XG5cbiAgICAvLyDlkJHkuIvlj5bmlbRcbiAgICBkdXJhdGlvbiA9IE1hdGguZmxvb3IoZHVyYXRpb24pO1xuXG4gICAgaWYgKHRoaXMuX1JUVCA+IHRoaXMuX3ZhbGlkTWluUlRUICYmIHRoaXMuX1JUVCA8PSB0aGlzLl92YWxpZE1heFJUVCkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9USU1FX0NPUlJFQ1RfR0VUX0NBTExfQ0xJRU5UX1RJTUVfQllfU0VSVkVSX1IsIGBjb2RlOiAke1JDQ2FsbFBsdXNJbm5lckNvZGUuTk9OT1BUSU1BTF9SRVNfVElNRX1gLCB0cmFjZUlkKTtcbiAgICAgIC8vIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNJbm5lckNvZGUuTk9OT1BUSU1BTF9SRVNfVElNRSwgZHVyYXRpb24sIGNsaWVudFN0YXJ0VGltZSB9O1xuICAgIH1cblxuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9USU1FX0NPUlJFQ1RfR0VUX0NBTExfQ0xJRU5UX1RJTUVfQllfU0VSVkVSX1IsIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIHJ0dDogdGhpcy5fUlRULFxuICAgICAgZGVsdGFUOiB0aGlzLl9kZWx0YVRpbWUsXG4gICAgICBzZXJ2ZXJTdGFydFRpbWUsXG4gICAgICBjbGllbnRTdGFydFRpbWUsXG4gICAgICBkdXJhdGlvbixcbiAgICB9KSwgdHJhY2VJZCk7XG4gICAgcmV0dXJuIHsgY29kZSwgZHVyYXRpb24sIGNsaWVudFN0YXJ0VGltZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOebtOaOpeiuoeeul+WuouaIt+err+W8gOWni+aXtumXtFxuICAgKi9cbiAgcHVibGljIGNhbGNDbGllbnRTdGFydFRpbWUoY2FsbElkOiBzdHJpbmcsIHN0YXJ0VGltZTogbnVtYmVyLCB0cmFjZUlkOiBzdHJpbmcpOiB7IGNvZGU6IFJDQ2FsbFBsdXNJbm5lckNvZGUsIGNsaWVudFN0YXJ0VGltZT86IG51bWJlciB9IHtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfVElNRV9DT1JSRUNUX0NBTENfQ0xJRU5UX1NUQVJUX1RJTUVfVCwgYGNhbGxJZDogJHtjYWxsSWR9LCBzdGFydFRpbWU6ICR7c3RhcnRUaW1lfWAsIHRyYWNlSWQpO1xuICAgIGlmICh0aGlzLl9SVFQgPiB0aGlzLl92YWxpZE1heFJUVCkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9USU1FX0NPUlJFQ1RfQ0FMQ19DTElFTlRfU1RBUlRfVElNRV9SLCBgY29kZTogJHtSQ0NhbGxQbHVzSW5uZXJDb2RlLklOVkFMSURfUkVTUE9OU0VfVElNRX1gLCB0cmFjZUlkKTtcbiAgICAgIC8vIOWGjeasoemHjeaWsOiOt+WPliBSVFQg5bm26YeN5paw6K6h566X5byA5aeL5pe26Ze0XG4gICAgICB0aGlzLl9sb29wQ29ycmVjdENsaWVudFRpbWUoY2FsbElkLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNJbm5lckNvZGUuSU5WQUxJRF9SRVNQT05TRV9USU1FIH07XG4gICAgfVxuXG4gICAgY29uc3QgY2xpZW50U3RhcnRUaW1lID0gTWF0aC5mbG9vcihzdGFydFRpbWUgLSB0aGlzLl9kZWx0YVRpbWUpO1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9USU1FX0NPUlJFQ1RfQ0FMQ19DTElFTlRfU1RBUlRfVElNRV9SLCBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBydHQ6IHRoaXMuX1JUVCxcbiAgICAgIGRlbHRhVDogdGhpcy5fZGVsdGFUaW1lLFxuICAgICAgc3RhcnRUOiBzdGFydFRpbWUsXG4gICAgICBjbGllbnRTdGFydFRpbWUsXG4gICAgfSksIHRyYWNlSWQpO1xuXG4gICAgaWYgKHRoaXMuX1JUVCA+IHRoaXMuX3ZhbGlkTWluUlRUKSB7XG4gICAgICAvLyDph43nva4gY2FsbCDkuK3ph43or5XmrKHmlbBcbiAgICAgIHRoaXMuX3JldHJ5VGltZXNJbkNhbGwgPSAwO1xuICAgICAgLy8g5YaN5qyh6YeN5paw6I635Y+WIFJUVCDlubbph43mlrDorqHnrpflvIDlp4vml7bpl7RcbiAgICAgIHRoaXMuX2xvb3BDb3JyZWN0Q2xpZW50VGltZShjYWxsSWQsIHRyYWNlSWQpO1xuICAgIH1cblxuICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNJbm5lckNvZGUuU1VDQ0VTUywgY2xpZW50U3RhcnRUaW1lIH07XG4gIH1cblxuICBwcml2YXRlIF9zdGFydFRpbWVzID0gMDtcblxuICAvKipcbiAgICog5byA5aeL5a6a5pe26YCS5b2S6I635Y+W5LiOIENhbGxTZXJ2ZXIg55qE5pe26Ze05YGP5beu5YC8XG4gICAqL1xuICBwdWJsaWMgc3RhcnQodHJhY2VJZDogc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMuX3RpbWVySWQgfHwgdGhpcy5fc3RhcnRUaW1lcyA+PSB0aGlzLl9tYXhSZXRyeVRpbWVzKSB7XG4gICAgICAvLyDpmLLmraLph43lpI3lkK/liqhcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfVElNRV9DT1JSRUNUX1NUQVJUX08sIGB0aW1lcklkOiAke3RoaXMuX3RpbWVySWR9YCk7XG5cbiAgICB0aGlzLl9zdGFydFRpbWVzKys7XG5cbiAgICAvLyDojrflj5ZcbiAgICB0aGlzLl9nZXREZWx0YVRpbWUodHJhY2VJZCk7XG5cbiAgICB0aGlzLl90aW1lcklkID0gdGltZXJTZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuX3RpbWVySWQgPSBudWxsO1xuICAgICAgdGhpcy5zdGFydCh0cmFjZUlkKTtcbiAgICB9LCB0aGlzLl9pbnRlcnZhbCk7XG4gIH1cblxuICAvKipcbiAgICog5YGc5q2i5a6a5pe26L2u6K6tXG4gICAqL1xuICBwdWJsaWMgc3RvcCh0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfVElNRV9DT1JSRUNUX1NUT1BfTywgYHRpbWVySWQ6ICR7dGhpcy5fdGltZXJJZH1gLCB0cmFjZUlkKTtcbiAgICB0aGlzLl90aW1lcklkICYmIGNsZWFyVGltZW91dCh0aGlzLl90aW1lcklkKTtcbiAgICB0aGlzLl90aW1lcklkID0gbnVsbDtcbiAgICAvLyDph43nva7mrKHmlbBcbiAgICB0aGlzLl9zdGFydFRpbWVzID0gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiDph43mlrDlrprml7bova7orq1cbiAgICovXG4gIHB1YmxpYyByZXN0YXJ0KHRyYWNlSWQ6IHN0cmluZykge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9USU1FX0NPUlJFQ1RfUkVTVEFSVF9PLCBgbGVnYWwgcnR0IHRpbWUsIFJUVDogJHt0aGlzLl9SVFR9LCB2YWxpZE1pblJUVDogJHt0aGlzLl92YWxpZE1pblJUVH1gLCB0cmFjZUlkKTtcbiAgICBpZiAodGhpcy5fUlRUIDwgdGhpcy5fdmFsaWRNaW5SVFQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8g5riF6Zmk5b2T5YmN5q2j5Zyo6L+b6KGM55qEXG4gICAgdGhpcy5zdG9wKHRyYWNlSWQpO1xuICAgIC8vIOmHjeaWsOWQr+WKqFxuICAgIHRoaXMuc3RhcnQodHJhY2VJZCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0TG9jYWxEZWxheVRpbWUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fZGVsdGFUaW1lO1xuICB9XG5cbiAgcHVibGljIGdldFJUVCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9SVFQ7XG4gIH1cblxuICAvKipcbiAgICog6I635Y+W5LiOIENhbGxTZXJ2ZXIg55qE5pe26Ze05YGP5beu5YC877yM6Z2e6YCa6K+d5Lit55qE6K6h566XXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIF9nZXREZWx0YVRpbWUodHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7IGNvZGU6IG51bWJlciwgZGVsYXlUaW1lPzogbnVtYmVyIH0+IHtcbiAgICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gICAgY29uc3QgeyBjb2RlLCBkYXRhOiBzeW5jVGltZSB9ID0gYXdhaXQgdGhpcy5fY2FsbEVuZ2luZS5nZXRDYWxsU2VydmVyVGltZXN0YW1wKHRyYWNlSWQpO1xuXG4gICAgY29uc3QgZW5kVGltZSA9IERhdGUubm93KCk7XG4gICAgaWYgKGNvZGUgIT09IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50UlRUID0gZW5kVGltZSAtIHN0YXJ0VGltZTtcblxuICAgIC8vIOWwj+S6jiAxMDAwbXMg5Li65Y+v55SoIHJ0dFxuICAgIGlmICgoY3VycmVudFJUVCA8IHRoaXMuX1JUVCB8fCB0aGlzLl9SVFQgPT09IDApICYmIGN1cnJlbnRSVFQgPD0gdGhpcy5fdmFsaWRNYXhSVFQpIHtcbiAgICAgIHRoaXMuX1JUVCA9IGN1cnJlbnRSVFQ7XG4gICAgfVxuXG4gICAgLy8g5Y+q5pyJ5bCP5LqOIDIwMG1zIOWBnOatouiOt+WPllxuICAgIGlmIChjdXJyZW50UlRUIDwgdGhpcy5fdmFsaWRNaW5SVFQpIHtcbiAgICAgIC8vIOWwj+S6juacgOWwj+WPr+eUqCBydHTvvIzlgZzmraLova7orq3orqHnrpdcbiAgICAgIHRoaXMuc3RvcCh0cmFjZUlkKTtcbiAgICB9XG5cbiAgICB0aGlzLl9kZWx0YVRpbWUgPSAoc3luY1RpbWUhIC0gc3RhcnRUaW1lKSAtIHRoaXMuX1JUVCAvIDI7XG5cbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfVElNRV9DT1JSRUNUX1NFVF9ERUxUQV9USU1FX08sIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIHJ0dDogdGhpcy5fUlRULFxuICAgICAgZGVsdGFUOiB0aGlzLl9kZWx0YVRpbWUsXG4gICAgfSksIHRyYWNlSWQpO1xuXG4gICAgcmV0dXJuIHsgY29kZSwgZGVsYXlUaW1lOiB0aGlzLl9kZWx0YVRpbWUgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDpgJror53kuK3ojrflj5blvIDlp4vml7bpl7RcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgX2dldERlbHRhVGltZUluQ2FsbChjYWxsSWQ6IHN0cmluZywgdHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7IGNvZGU6IFJDQ2FsbFBsdXNJbm5lckNvZGUsIGNsaWVudFN0YXJ0VGltZT86IG51bWJlciwgY2xpZW50Rmlyc3RGcmFtZVRpbWU/OiBudW1iZXIgfT4ge1xuICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgY29uc3QgeyBjb2RlLCBkYXRhIH0gPSBhd2FpdCB0aGlzLl9jYWxsRW5naW5lLmdldENhbGxUaW1lSW5mbyhjYWxsSWQsIHRyYWNlSWQpO1xuICAgIGNvbnN0IGVuZFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gICAgaWYgKGNvZGUgIT09IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50UlRUID0gZW5kVGltZSAtIHN0YXJ0VGltZTtcblxuICAgIC8vIOWwj+S6jiAxMDAwbXMg5Li65Y+v55SoIHJ0dFxuICAgIGlmIChjdXJyZW50UlRUIDwgdGhpcy5fUlRUKSB7XG4gICAgICB0aGlzLl9SVFQgPSBjdXJyZW50UlRUO1xuICAgIH1cblxuICAgIHRoaXMuX2RlbHRhVGltZSA9IChkYXRhIS5zeW5jVGltZSAtIHN0YXJ0VGltZSkgLSB0aGlzLl9SVFQgLyAyO1xuXG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1RJTUVfQ09SUkVDVF9TRVRfREVMVEFfVElNRV9PLCBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBjYWxsSWQsXG4gICAgICBydHQ6IHRoaXMuX1JUVCxcbiAgICAgIGRlbHRhVDogdGhpcy5fZGVsdGFUaW1lLFxuICAgIH0pLCB0cmFjZUlkKTtcblxuICAgIGNvbnN0IGNsaWVudFN0YXJ0VGltZSA9IE1hdGguZmxvb3IoZGF0YSEuc3RhcnRUaW1lIC0gdGhpcy5fZGVsdGFUaW1lKTtcbiAgICBjb25zdCBjbGllbnRGaXJzdEZyYW1lVGltZSA9IE1hdGguZmxvb3IoZGF0YSEuZmlyc3RGcmFtZXRpbWUgLSB0aGlzLl9kZWx0YVRpbWUpO1xuXG4gICAgLy8g5Y+q5pyJ5bCP5LqOIDIwMG1zIOWBnOatouiOt+WPllxuICAgIGlmIChjdXJyZW50UlRUIDwgdGhpcy5fdmFsaWRNaW5SVFQpIHtcbiAgICAgIC8vIOacgOS8mOe7k+aenO+8jOWBnOatoui9ruiureiuoeeul1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0lubmVyQ29kZS5TVUNDRVNTLCBjbGllbnRTdGFydFRpbWUsIGNsaWVudEZpcnN0RnJhbWVUaW1lIH07XG4gICAgfVxuICAgIC8vIOmdnuacgOS8mOe7k+aenFxuICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNJbm5lckNvZGUuSU5WQUxJRF9SRVNQT05TRV9USU1FLCBjbGllbnRTdGFydFRpbWUsIGNsaWVudEZpcnN0RnJhbWVUaW1lIH07XG4gIH1cblxuICBwcml2YXRlIF9yZXRyeVRpbWVzSW5DYWxsOiBudW1iZXIgPSAwXG5cbiAgcHJpdmF0ZSByZWFkb25seSBfbWF4UmV0cnlUaW1lc0luQ2FsbDogbnVtYmVyID0gM1xuXG4gIC8qKlxuICAgKiDlpJrmrKHmoKHmraPmipvnu5nkuJrliqHlsYLnmoTpgJror53lvIDlp4vml7bpl7TjgIHpppbluKfml7bpl7RcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgX2xvb3BDb3JyZWN0Q2xpZW50VGltZShjYWxsSWQ6IHN0cmluZywgdHJhY2VJZDogc3RyaW5nKSB7XG4gICAgLy8g5YWI5YGc5q2i5pyq57uT5p2f55qE6K6h566XXG4gICAgdGhpcy5zdG9wKHRyYWNlSWQpO1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9USU1FX0NPUlJFQ1RfTE9PUF9DT1JSRUNUX0NMSU5FVF9USU1FX1QsIGBjYWxsSWQ6ICR7Y2FsbElkfWAsIHRyYWNlSWQpO1xuICAgIGNvbnN0IHsgY29kZSwgY2xpZW50U3RhcnRUaW1lLCBjbGllbnRGaXJzdEZyYW1lVGltZSB9ID0gYXdhaXQgdGhpcy5fZ2V0RGVsdGFUaW1lSW5DYWxsKGNhbGxJZCwgdHJhY2VJZCk7XG5cbiAgICBpZiAoY29kZSA9PT0gUkNDYWxsUGx1c0lubmVyQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfVElNRV9DT1JSRUNUX0xPT1BfQ09SUkVDVF9DTElORVRfVElNRV9SLCBgY29kZTogJHtSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTfWAsIHRyYWNlSWQpO1xuICAgICAgLy8g57uT5p6c5pyA5LyY77yM5oqb57uZ5bqU55So5bGC5byA5aeL5pe26Ze0XG4gICAgICB0aGlzLl9zaW5nbGVDYWxsRHVyYXRpb25FdihjYWxsSWQsIGNsaWVudFN0YXJ0VGltZSEsIGNsaWVudEZpcnN0RnJhbWVUaW1lISwgdHJhY2VJZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLl9yZXRyeVRpbWVzSW5DYWxsID4gdGhpcy5fbWF4UmV0cnlUaW1lc0luQ2FsbCAmJiBjb2RlID09PSBSQ0NhbGxQbHVzSW5uZXJDb2RlLklOVkFMSURfUkVTUE9OU0VfVElNRSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1RJTUVfQ09SUkVDVF9MT09QX0NPUlJFQ1RfQ0xJTkVUX1RJTUVfUiwgYGNvZGU6ICR7UkNDYWxsUGx1c0lubmVyQ29kZS5JTlZBTElEX1JFU1BPTlNFX1RJTUV9YCwgdHJhY2VJZCk7XG4gICAgICAvLyDpnZ7mnIDkvJjnu5PmnpzvvIzmipvnu5nlupTnlKjlsYLlvIDlp4vml7bpl7TvvIzmoLnmja7ph43or5XmrKHmlbDov5vooYzph43or5U7IOmHjeivlSAzIOasoeWQjuWGjeaKm+WHuuS4u+imgeaYr+S4uuS6huiOt+WPluacgOWwjyBSVFRcbiAgICAgIHRoaXMuX3NpbmdsZUNhbGxEdXJhdGlvbkV2KGNhbGxJZCwgY2xpZW50U3RhcnRUaW1lISwgY2xpZW50Rmlyc3RGcmFtZVRpbWUhLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuX3JldHJ5VGltZXNJbkNhbGwgPiB0aGlzLl9tYXhSZXRyeVRpbWVzSW5DYWxsKSB7XG4gICAgICAvLyDml6DmnIDkvJjnu5PmnpzvvIzlupTnlKjlsYLmoLnmja7oh6rlt7HnmoTml7bpl7TotbDooagsIOebuOW9k+S6jiBSVFQg5oyJIDAg5aSE55CGXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fcmV0cnlUaW1lc0luQ2FsbCsrO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5fbG9vcENvcnJlY3RDbGllbnRUaW1lKGNhbGxJZCwgdHJhY2VJZCk7XG4gICAgfSwgdGhpcy5faW50ZXJ2YWwpO1xuICB9XG59XG4iLCJleHBvcnQgZW51bSBGb3J3YXJkVHlwZSB7XG4gIC8qKlxuICAgKiDpgJrov4fkuIvkuIDmrKHkurrlkZjnirbmgIEgdXNlclN0YXRlIOeahOS4i+WPkeWQjOatpeW4puS4i+WOu1xuICAgKi9cbiAgU09PTl9BRkVURVIgPSAwLFxuICAvKipcbiAgICog56uL5Y2z6L2s5Y+RXG4gICAqL1xuICBDVVJSRU5UID0gMSxcbn1cbiIsImltcG9ydCB7IFJDQ2FsbFBsdXNNZWRpYVR5cGUsIFJDQ2FsbFBsdXNUeXBlIH0gZnJvbSAnLi4vYXBpL2ludGVyZmFjZSc7XG5cbmV4cG9ydCBlbnVtIFJDQ2FsbFBsdXNJbnZpdGVTb3VyY2Uge1xuICBQVUJfSU5WSVRFX0NBTEwgPSAwLFxuICBQVUxMX0tWX0lOVklURV9DQUxMID0gMSxcbiAgU1lTVEVNX1BVU0ggPSAyLFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIElTdGF0aXN0aWNzRGF0YSB7XG4gIC8qKlxuICAgKiDkuIrmiqXml7bpl7RcbiAgICovXG4gIHRpbWU6IG51bWJlcixcbiAgLyoqXG4gICAqIOi/kOiQpeWVhu+8jOS+i+WmgiDkuK3lm73ogZTpgJpcbiAgICovXG4gIGNyOiBzdHJpbmcsXG4gIC8qKlxuICAgKiDnvZHnu5znsbvlnovvvIzkvovlpoIgNEdcbiAgICovXG4gIG5ldDogc3RyaW5nLFxuICAvKipcbiAgICogdXNlcklkXG4gICAqL1xuICB1aWQ6IHN0cmluZyxcbiAgLyoqXG4gICAqIOmUmeivr+eggVxuICAgKi9cbiAgY29kOiBudW1iZXIsXG4gIC8qKlxuICAgKiDosIPnlKjmiafooYzml7bplb9cbiAgICovXG4gIGR1cjogbnVtYmVyXG4gIC8qKlxuICAgKiDlqpLkvZPnsbvlnotcbiAgICovXG4gIG10cDogUkNDYWxsUGx1c01lZGlhVHlwZVxuICAvKipcbiAgICog6YCa6K+d57G75Z6L77yM56eB6IGK5oiW576k6IGKXG4gICAqL1xuICBjdHA6IFJDQ2FsbFBsdXNUeXBlXG4gIC8qKlxuICAgKiBjYWxsSWRcbiAgICovXG4gIGNpZDogc3RyaW5nXG4gIC8qKlxuICAgKiBjbGllbnQgY2FsbElkXG4gICAqL1xuICBjY2lkOiBzdHJpbmcsXG4gIC8qKlxuICAgKiDpgoDor7fmjqXmlLbmnaXmupBcbiAgICovXG4gIHJmOiBSQ0NhbGxQbHVzSW52aXRlU291cmNlXG59XG4iLCJleHBvcnQgZW51bSBSQ0NhbGxEaXJlY3Rpb24ge1xuICAvKipcbiAgICog5ZG85Ye6XG4gICAqL1xuICBPVVQgPSAtMSxcbiAgLyoqXG4gICAqIOe+pOWRvFxuICAgKi9cbiAgR1JPVVAgPSAwLFxuICAvKipcbiAgICog5ZG85YWlXG4gICAqL1xuICBJTiA9IDFcbn1cbiIsImltcG9ydCB7XG4gIEJhc2ljTG9nZ2VyLCBFdmVudEVtaXR0ZXIsIElSdW50aW1lLCBQbHVnaW5Db250ZXh0LCBSQ0Nvbm5lY3Rpb25TdGF0dXMsXG59IGZyb20gJ0Byb25nY2xvdWQvZW5naW5lJztcbmltcG9ydCB7IERpYWxvZ0FjdGlvbiB9IGZyb20gJy4vZW51bXMvRGlhbG9nQWN0aW9uJztcbmltcG9ydCB7IERpYWxvZ1R5cGUgfSBmcm9tICcuL2VudW1zL0RpYWxvZ1R5cGUnO1xuaW1wb3J0IHsgUkNDYWxsUGx1c01lZGlhVHlwZSB9IGZyb20gJy4vZW51bXMvUkNDYWxsUGx1c01lZGlhVHlwZSc7XG5pbXBvcnQgeyBSQ0NhbGxQbHVzQ2FsbFN0YXRlIH0gZnJvbSAnLi9lbnVtcy9SQ0NhbGxTZXNzaW9uU3RhdGUnO1xuaW1wb3J0IHsgUkNDYWxsUGx1c1R5cGUgfSBmcm9tICcuL2VudW1zL1JDQ2FsbFR5cGUnO1xuaW1wb3J0IHsgU2VjcmV0Q2FsbFR5cGUgfSBmcm9tICcuL2VudW1zL1NlY3JldENhbGxUeXBlJztcbmltcG9ydCB7IElSQ0NhbGxJbml0T3B0aW9ucyB9IGZyb20gJy4vaW50ZXJmYWNlcy9JSW5kZXgnO1xuaW1wb3J0IHtcbiAgSUFjY2VwdEluZm8sXG4gIElBY2NlcHRPcHRzLFxuICBJQ2FsbElkLFxuICBJUkNDYWxsUGx1c0NhbGxSZWNvcmQsXG4gIElSQ0NhbGxQbHVzR2V0Q2FsbFJlY29yZFJlcyxcbiAgSUNhbmNlbENoYW5nZU1lZGlhVHlwZU9wdHMsXG4gIElHZXRDYWxsTG9nTGlzdE9wdHMsXG4gIElHZXRDYWxsU2Vzc2lvblJlcyxcbiAgSUhhbmd1cEluZm8sXG4gIElJbnZpdGVPcHRzLFxuICBJSW52aXRlUmVzLFxuICBJSm9pbkNhbGxPcHRzLFxuICBJT3RoZXJNZW1JbmZvLFxuICBJUmVxQ2hhbmdlTWVkaWFUeXBlT3B0cyxcbiAgSVJlcUNoYW5nZU1lZGlhVHlwZVJlcyxcbiAgSVJlc0NoYW5nZU1lZGlhVHlwZU9wdHMsXG4gIElTZXNzaW9uVXNlcixcbiAgSVN0YXJ0Q2FsbE9wdHMsXG4gIElTdGFydENhbGxSZXN1bHQsXG4gIElIYW5ndXBGb3JCdXN5T3B0cyxcbiAgSUNoYW5nZU1lZGlhVHlwZUluZm8sXG59IGZyb20gJy4vaW50ZXJmYWNlcy9JUkNDYWxsQ2xpZW50JztcbmltcG9ydCB7XG4gIElDYWxsU2Vzc2lvblVzZXIsXG4gIElEaWFsb2dEb3duQ2FsbENvbixcbiAgSUV2ZW50RG93bkNhbGxDb24sXG4gIElHZXRDYWxsVGltZUluZm9SZXMsXG4gIElHZXREZWxheVRpbWVJbmZvUmVzLFxuICBJUHViQ2FsbExvZyxcbiAgSVB1Ykludml0ZUNvbixcbiAgSVN0YXR1c0Rvd25Db250LFxuICBJU3lzU3RhdHVzVXBPcHRzLFxufSBmcm9tICcuL2ludGVyZmFjZXMvSVNpZ25hbFRyYW5zcG9ydGVyJztcbmltcG9ydCB7IENhbGxUaW1lckV2ZW50VHlwZSwgUkNDYWxsSW5uZXJTZXNzaW9uIH0gZnJvbSAnLi9tb2R1bGVzL1JDQ2FsbElubmVyU2Vzc2lvbic7XG5pbXBvcnQgeyBTaWduYWxUcmFuc3BvcnRlciB9IGZyb20gJy4vbW9kdWxlcy9TaWduYWxUcmFuc3BvcnRlcic7XG5pbXBvcnQgeyBwYXJzZVN0YXR1c0RhdGEsIHRyYW4yQ2FsbExvZyB9IGZyb20gJy4vdXRpbHMvaGVscGVyJztcbmltcG9ydCB7IGdldFVVSUQyMiB9IGZyb20gJy4vdXRpbHMvcmFuZG9tJztcbmltcG9ydCB7IHRpbWVyU2V0VGltZW91dCB9IGZyb20gJy4vdXRpbHMvdGltZXJzJztcbmltcG9ydCB7IFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlIH0gZnJvbSAnLi9lbnVtcy9SQ0NhbGxTZXNzaW9uVXNlclN0YXRlJztcbmltcG9ydCB7IEFibm9ybWFsQ2FsbCB9IGZyb20gJy4vbW9kdWxlcy9BYm5vcm1hbENhbGwnO1xuaW1wb3J0IHsgQ2FsbFNlcnZlckV2ZW50VHlwZSB9IGZyb20gJy4vZW51bXMvQ2FsbFNlcnZlckV2ZW50VHlwZSc7XG5pbXBvcnQgeyBUaW1lQ29ycmVjdGlvbmVyIH0gZnJvbSAnLi9tb2R1bGVzL1RpbWVDb3JyZWN0aW9uZXInO1xuaW1wb3J0IHsgUkNDYWxsUGx1c1Nlc3Npb24gfSBmcm9tICcuL21vZHVsZXMvUkNDYWxsUGx1c1Nlc3Npb24nO1xuaW1wb3J0IHsgRm9yd2FyZFR5cGUgfSBmcm9tICcuL2VudW1zL0ZvcndhcmRUeXBlJztcbmltcG9ydCB7XG4gIENhbGxIb29rc1R5cGUsIFB1Ykludml0ZUNhbGxNaXNzUmVhc29uLCBQdWJJbnZpdGVDYWxsTWlzc1JlZmVyLFxufSBmcm9tICcuL2ludGVyZmFjZXMvSUNhbGxIb29rcyc7XG5pbXBvcnQgeyBSQ0NhbGxQbHVzQ29kZSwgUkNDYWxsUGx1c1JlYXNvbiB9IGZyb20gJy4vYXBpL2ludGVyZmFjZSc7XG5pbXBvcnQgeyBSQ0NhbGxQbHVzSW52aXRlU291cmNlIH0gZnJvbSAnLi9pbnRlcmZhY2VzL0lDYWxsUGx1c1N0YXRpc3RpY3MnO1xuaW1wb3J0IHsgUkNDYWxsUGx1c0xvZ2dlclRhZyB9IGZyb20gJy4vYXBpL2VudW1zL1JDQ2FsbFBsdXNMb2dnZXJUYWcnO1xuaW1wb3J0IHsgUkNDYWxsUGx1c01lZGlhVHlwZUNoYW5nZVJlc3VsdCB9IGZyb20gJy4vZW51bXMvUkNDYWxsUGx1c01lZGlhVHlwZUNoYW5nZVJlc3VsdCc7XG5pbXBvcnQgeyBSQ0NhbGxQbHVzUmVwb3J0TW9kdWxlIH0gZnJvbSAnLi9tb2R1bGVzL1JDQ2FsbFBsdXNSZXBvcnRNb2R1bGUnO1xuaW1wb3J0IHsgUkNDYWxsRGlyZWN0aW9uIH0gZnJvbSAnLi9lbnVtcy9SQ0NhbGxEaXJlY3Rpb24nO1xuaW1wb3J0IHsgUkNDYWxsUGx1c0lubmVyQ29kZSB9IGZyb20gJy4vZW51bXMvUkNDYWxsUGx1c0lubmVyQ29kZSc7XG5cbmNvbnN0IENBTExfVElNRV9PVVQgPSA2MCAqIDEwMDA7XG5cbmV4cG9ydCBjbGFzcyBSQ0NhbGxFbmdpbmUgZXh0ZW5kcyBFdmVudEVtaXR0ZXIge1xuICBzdGF0aWMgX19JTk5FUl9TRVNTSU9OX0NMT1NFX186IHN0cmluZyA9ICdpbm5lci1zZXNzaW9uLWNsb3NlJ1xuXG4gIHN0YXRpYyBfX0lOTkVSX1NFU1NJT05fQ09OTkVDVF9fOiBzdHJpbmcgPSAnaW5uZXItc2Vzc2lvbi1jb25uZWN0J1xuXG4gIHN0YXRpYyBfX0lOTkVSX0NIQU5HRV9NRURJQV9UWVBFX186IHN0cmluZyA9ICdpbm5lci1jaGFuZ2UtbWVkaWEtdHlwZSdcblxuICBzdGF0aWMgX19JTk5FUl9JTlZJVEVfXzogc3RyaW5nID0gJ2lubmVyLWludml0ZSdcblxuICAvKipcbiAgICog5Li7IHNlc3Npb25cbiAgICovXG4gIF9tYWluU2Vzc2lvbjogUkNDYWxsSW5uZXJTZXNzaW9uIHwgbnVsbCA9IG51bGxcblxuICAvKipcbiAgICog5Zyo6YCa6K+d5Lit5pS25Yiw55qEIOmCgOivtyBzZXNzaW9uXG4gICAqL1xuICBfaG9sZFNlc3Npb25zOiBSQ0NhbGxJbm5lclNlc3Npb25bXSA9IFtdXG5cbiAgLyoqXG4gICAqIOS/oeS7pOaooeWdl1xuICAgKi9cbiAgX3NpZ25hbE1vZHVsZTogU2lnbmFsVHJhbnNwb3J0ZXJcblxuICAvKipcbiAgICog5byC5bi457uT5p2fIGNhbGwg5aSE55CG5ZmoXG4gICAqL1xuICBfYWJub3JtYWxNb2R1bGU6IEFibm9ybWFsQ2FsbFxuXG4gIC8qKlxuICAgKiDorrDlvZXljZXlkbzkuK3vvIzmmK/lkKbkuIrmiqXov4fnrKzkuIDluKdcbiAgICog572uIHRydWUg5pe25py677ya5pS25Yiw6L+c56uv56ys5LiA5bin77yM5oiQ5Yqf5LiK5oqlIFNlcnZlclxuICAgKiDnva4gZmFsc2Ug5pe25py677ya6YCa6K+d57uT5p2fXG4gICAqL1xuICBwcml2YXRlIF9pc1VwRmlyc3RGcmFtZVRpbWU6IGJvb2xlYW4gPSBmYWxzZVxuXG4gIC8qKlxuICAgKiDpgJror53kuLogT05DQUxMIOaXtu+8jFNESyDpnIDnu5nkuJrliqHlsYLkuIrmiqXpgJror53lvIDlp4vorqHml7bkuovku7ZcbiAgICog5Lya5pS25Yiw5aSa5qyhIE9OQ0FMTO+8jOaJgOS7pemcgOimgeagh+ivhuaYr+WQpuW3suaKm+i/h+S6i+S7tlxuICAgKi9cbiAgcHJpdmF0ZSBfY2FsbFN0YXJ0TWFwOiB7XG4gICAgW2NhbGxJZDogc3RyaW5nXToge1xuICAgICAgaXNSZWNlaXZlQ2FsbFN0YXJ0VGltZTogYm9vbGVhbixcbiAgICB9XG4gIH0gPSB7fVxuXG4gIC8qKlxuICAgKiDmoKHml7blmahcbiAgICovXG4gIF90aW1lQ29ycmVjdGlvbmVyOiBUaW1lQ29ycmVjdGlvbmVyXG5cbiAgLyoqXG4gICAqIOaehOmAoOWZqFxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBfY29udGV4dDogUGx1Z2luQ29udGV4dCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9ydW50aW1lOiBJUnVudGltZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9pbml0T3B0czogSVJDQ2FsbEluaXRPcHRpb25zLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2xvZ2dlcjogQmFzaWNMb2dnZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBfcmVwb3J0QXBwRXZlbnRNb2R1bGU6IFJDQ2FsbFBsdXNSZXBvcnRNb2R1bGUsXG4gICkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5fdGltZUNvcnJlY3Rpb25lciA9IG5ldyBUaW1lQ29ycmVjdGlvbmVyKHRoaXMsIF9sb2dnZXIsIHRoaXMuX29uUmVjdlNpbkNhbGxEdXJhdGlvbi5iaW5kKHRoaXMpKTtcbiAgICB0aGlzLl9zaWduYWxNb2R1bGUgPSBuZXcgU2lnbmFsVHJhbnNwb3J0ZXIoX2NvbnRleHQsIF9ydW50aW1lLCBfaW5pdE9wdHMsIHRoaXMuX3RpbWVDb3JyZWN0aW9uZXIsIHRoaXMuX2xvZ2dlcik7XG4gICAgdGhpcy5fc2lnbmFsTW9kdWxlLnJlZ2lzdGVyTGlzdGVuZXIoe1xuICAgICAgb25JbnZpdGU6IHRoaXMuX29uSW52aXRlLmJpbmQodGhpcyksXG4gICAgICBvblN0YXR1c0Rvd246IHRoaXMuX29uU3RhdHVzRG93bi5iaW5kKHRoaXMpLFxuICAgICAgb25PdGhlckNsaWVudFN0YXR1c0Rvd246IHRoaXMuX29uT3RoZXJDbGllbnRTdGF0dXNEb3duLmJpbmQodGhpcyksXG4gICAgICBvbkV2ZW50RG93bjogdGhpcy5fb25FdmVudERvd24uYmluZCh0aGlzKSxcbiAgICAgIG9uU3dpdGNoTWVkaWFUeXBlOiB0aGlzLl9vblN3aXRjaE1lZGlhVHlwZS5iaW5kKHRoaXMpLFxuICAgICAgb25SZWN2Q2FsbEVuZExvZzogdGhpcy5fb25SZWN2Q2FsbEVuZExvZy5iaW5kKHRoaXMpLFxuICAgICAgb25JTVN0YXRlQ2hhbmdlOiB0aGlzLl9vbklNU3RhdGVDaGFuZ2UuYmluZCh0aGlzKSxcbiAgICB9KTtcbiAgICB0aGlzLl9hYm5vcm1hbE1vZHVsZSA9IG5ldyBBYm5vcm1hbENhbGwoX3J1bnRpbWUsIF9sb2dnZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIOWPkei1t+WRvOWPq1xuICAgKi9cbiAgcHVibGljIGFzeW5jIHN0YXJ0Q2FsbChvcHRzOiBJU3RhcnRDYWxsT3B0cywgdHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7Y29kZTogbnVtYmVyLCBkYXRhPzogSVN0YXJ0Q2FsbFJlc3VsdH0+IHtcbiAgICBjb25zdCBjdXJyZW50VXNlcklkID0gdGhpcy5fY29udGV4dC5nZXRDdXJyZW50SWQoKTtcbiAgICBjb25zdCB7XG4gICAgICBjYWxsVHlwZSwgbWVkaWFUeXBlLCB0b1VzZXJzLCB0YXJnZXRJZCwgdGFyZ2V0VHlwZSwgb2xkUm9vbUlkLFxuICAgIH0gPSBvcHRzO1xuICAgIGNvbnN0IHsgY29kZSwgZGF0YSB9ID0gYXdhaXQgdGhpcy5fc2lnbmFsTW9kdWxlLnN0YXJ0Q2FsbCh7XG4gICAgICBjbGllbnRDYWxsSWQ6IG9wdHMuY2FsbElkLFxuICAgICAgY2FsbFR5cGUsXG4gICAgICBtZWRpYVR5cGUsXG4gICAgICB0b1VzZXJzLFxuICAgICAgc2VjcmV0Q2hhdDogU2VjcmV0Q2FsbFR5cGUuTk9STUFMLFxuICAgICAgdGFyZ2V0VHlwZSxcbiAgICAgIHRhcmdldElkLFxuICAgICAgb2xkUm9vbUlkLFxuICAgIH0sIHRyYWNlSWQpO1xuXG4gICAgaWYgKGNvZGUgIT09IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGNhbGxJZCwgYnVzeWxpbmVVc2VycyB9ID0gZGF0YSE7XG5cbiAgICAvLyDmnKzlnLDlrZjlgqggY2FsbElkLCBjYWxsIOW8guW4uOmAgOWHuuaXtuS9v+eUqFxuICAgIHRoaXMuX2Fibm9ybWFsTW9kdWxlLmFkZEFibm9ybWFsbENhbGxJZChjdXJyZW50VXNlcklkLCBjYWxsSWQpO1xuXG4gICAgLy8g55Sf5oiQ5Li7IHNlc3Npb25cbiAgICB0aGlzLl9tYWluU2Vzc2lvbiA9IG5ldyBSQ0NhbGxJbm5lclNlc3Npb24oXG4gICAgICBjYWxsSWQsXG4gICAgICBSQ0NhbGxQbHVzQ2FsbFN0YXRlLklOVklURUQsXG4gICAgICBjYWxsVHlwZSxcbiAgICAgIG1lZGlhVHlwZSxcbiAgICAgIGN1cnJlbnRVc2VySWQsXG4gICAgICBjdXJyZW50VXNlcklkLFxuICAgICAgW10sXG4gICAgICB0aGlzLl9sb2dnZXIsXG4gICAgKTtcblxuICAgIC8vIOWNleWRvOWQr+WKqOWRvOWPq+i2heaXtuiuoeaXtuWZqCwg576k5ZG85peg6LaF5pe26YC76L6RXG4gICAgaWYgKGNhbGxUeXBlID09PSBSQ0NhbGxQbHVzVHlwZS5TSU5HTEUpIHtcbiAgICAgIGNvbnN0IGludml0ZXJUaW1lcklkID0gdGhpcy5fc3RhcnRUaW1lcihkYXRhIS5jYWxsSWQsIFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLk5PX0FOU1dFUiwgdHJhY2VJZCk7XG4gICAgICB0aGlzLl9tYWluU2Vzc2lvbi51cGRhdGVUaW1lcklkKENhbGxUaW1lckV2ZW50VHlwZS5JTlZJVEVSLCBpbnZpdGVyVGltZXJJZCk7XG4gICAgfVxuXG4gICAgLy8g6YCa55+l5bex5pa55Lq65ZGY54q25oCB5Y+Y5pu0XG4gICAgY29uc3Qgc2VsZlN0YXRlID0ge1xuICAgICAgdXNlcklkOiBjdXJyZW50VXNlcklkLFxuICAgICAgdXNlclN0YXRlOiBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZS5DQUxMSU5HLFxuICAgICAgc3lzdGVtU3RhdGU6IFJDQ2FsbFBsdXNSZWFzb24uQ0FMTElORyxcbiAgICAgIHRhcmdldFR5cGUsXG4gICAgICB0YXJnZXRJZCxcbiAgICAgIGNhbWVyYUVuYWJsZTogZmFsc2UsXG4gICAgICBtaWNyb3Bob25lRW5hYmxlOiBmYWxzZSxcbiAgICB9O1xuICAgIGxldCBpbnZpdGVlc1N0YXRlID0gdG9Vc2Vycy5tYXAoKHsgdXNlcklkLCB0YXJnZXRUeXBlLCB0YXJnZXRJZCB9KSA9PiAoe1xuICAgICAgdXNlcklkLFxuICAgICAgdXNlclN0YXRlOiBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZS5JTlZJVEVELFxuICAgICAgc3lzdGVtU3RhdGU6IFJDQ2FsbFBsdXNSZWFzb24uSU5WSVRFRCxcbiAgICAgIHRhcmdldFR5cGUsXG4gICAgICB0YXJnZXRJZCxcbiAgICAgIGNhbWVyYUVuYWJsZTogZmFsc2UsXG4gICAgICBtaWNyb3Bob25lRW5hYmxlOiBmYWxzZSxcbiAgICB9KSk7XG5cbiAgICBsZXQgYnVzeVVzZXJzU3RhdGU6IElTZXNzaW9uVXNlcltdID0gW107XG4gICAgaWYgKGJ1c3lsaW5lVXNlcnMpIHtcbiAgICAgIGJ1c3lVc2Vyc1N0YXRlID0gYnVzeWxpbmVVc2Vycy5tYXAoKGl0ZW0pID0+IHtcbiAgICAgICAgY29uc3QgeyB0YXJnZXRUeXBlLCB0YXJnZXRJZCB9ID0gaW52aXRlZXNTdGF0ZS5maW5kKCh1c2VyKSA9PiB1c2VyLnVzZXJJZCA9PT0gaXRlbS51c2VySWQpITtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB1c2VySWQ6IGl0ZW0udXNlcklkLFxuICAgICAgICAgIHVzZXJTdGF0ZTogaXRlbS5zZXNzaW9uU3RhdHVzLFxuICAgICAgICAgIHN5c3RlbVN0YXRlOiBSQ0NhbGxQbHVzUmVhc29uLkJVU1lMSU5FX1JJTkdJTkcsXG4gICAgICAgICAgdGFyZ2V0VHlwZSxcbiAgICAgICAgICB0YXJnZXRJZCxcbiAgICAgICAgICBjYW1lcmFFbmFibGU6IGZhbHNlLFxuICAgICAgICAgIG1pY3JvcGhvbmVFbmFibGU6IGZhbHNlLFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgICAvLyDooqvpgoDor7fogIXkuK3pnIDov4fmu6Tlh7rlv5nnooznlKjmiLdcbiAgICAgIGludml0ZWVzU3RhdGUgPSBpbnZpdGVlc1N0YXRlLmZpbHRlcigoeyB1c2VySWQgfSkgPT4gYnVzeVVzZXJzU3RhdGUhLmV2ZXJ5KCh7IHVzZXJJZDogYnVzeVVzZXJJZCB9KSA9PiBidXN5VXNlcklkICE9PSB1c2VySWQpKTtcbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMudXBkYXRlVXNlcnNTdGF0ZShjYWxsSWQsIFtzZWxmU3RhdGUsIC4uLmludml0ZWVzU3RhdGUsIC4uLmJ1c3lVc2Vyc1N0YXRlIV0sIHRyYWNlSWQpO1xuICAgIH0pO1xuICAgIHJldHVybiB7IGNvZGUsIGRhdGEgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDpgJror53kuK3pgoDor7dcbiAgICovXG4gIHB1YmxpYyBhc3luYyBpbnZpdGUob3B0czogSUludml0ZU9wdHMsIHRyYWNlSWQ6IHN0cmluZyk6IFByb21pc2U8e2NvZGU6IG51bWJlciwgZGF0YT86IElJbnZpdGVSZXN9PiB7XG4gICAgLy8g5LiN5a2Y5Zyo5q2j5Zyo6YCa6K+d5LitIHNlc3Npb24sIOS4jeWFgeiuuOmCgOivt1xuICAgIGlmICghdGhpcy5fbWFpblNlc3Npb24pIHtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLk5PVF9JTl9DQUxMIH07XG4gICAgfVxuXG4gICAgY29uc3QgeyB0b1VzZXJzIH0gPSBvcHRzO1xuXG4gICAgY29uc3QgY2FsbElkID0gdGhpcy5fbWFpblNlc3Npb24uZ2V0Q2FsbElkKCk7XG4gICAgY29uc3QgeyBjb2RlLCBkYXRhIH0gPSBhd2FpdCB0aGlzLl9zaWduYWxNb2R1bGUuaW52aXRlQ2FsbCh7XG4gICAgICBjYWxsSWQsXG4gICAgICB0b1VzZXJzLFxuICAgIH0sIHRyYWNlSWQpO1xuICAgIGlmIChjb2RlID09PSBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTKSB7XG4gICAgICBpZiAodGhpcy5fbWFpblNlc3Npb24uZ2V0Q2FsbFR5cGUoKSA9PT0gUkNDYWxsUGx1c1R5cGUuU0lOR0xFKSB7XG4gICAgICAgIC8vIOWNleWRvOS4remCgOivt+aIkOWKn++8jOWNs+abtOaWsCBjYWxsIHNlc3Npb24g6YCa6K+d57G75Z6L5Li6576k5ZG8XG4gICAgICAgIHRoaXMuX21haW5TZXNzaW9uLnVwZGF0ZUNhbGxUeXBlKFJDQ2FsbFBsdXNUeXBlLk1VTFRJKTtcbiAgICAgICAgLy8g6YCa55+lIGNhbGxUeXBlIOWPmOabtOS4uue+pOWRvFxuICAgICAgICB0aGlzLl9vbkNhbGxUeXBlQ2hhbmdlKHRoaXMuX21haW5TZXNzaW9uLmdldENhbGxJZCgpLCBSQ0NhbGxQbHVzVHlwZS5NVUxUSSwgdHJhY2VJZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIOmAmuefpeiiq+mCgOivt+S6uuWRmOeKtuaAgeWPmOabtFxuICAgICAgbGV0IGludml0ZWRVc2Vyc1N0YXRlID0gdG9Vc2Vycy5tYXAoKHsgdXNlcklkLCB0YXJnZXRUeXBlLCB0YXJnZXRJZCB9KSA9PiAoe1xuICAgICAgICB1c2VySWQsXG4gICAgICAgIHVzZXJTdGF0ZTogUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUuSU5WSVRFRCxcbiAgICAgICAgc3lzdGVtU3RhdGU6IFJDQ2FsbFBsdXNSZWFzb24uSU5WSVRFRCxcbiAgICAgICAgdGFyZ2V0VHlwZSxcbiAgICAgICAgdGFyZ2V0SWQsXG4gICAgICAgIGNhbWVyYUVuYWJsZTogZmFsc2UsXG4gICAgICAgIG1pY3JvcGhvbmVFbmFibGU6IGZhbHNlLFxuICAgICAgfSkpO1xuXG4gICAgICBsZXQgYnVzeWxpbmVVc2Vyc1N0YXRlOiBJU2Vzc2lvblVzZXJbXSA9IFtdO1xuICAgICAgaWYgKGRhdGEhLmJ1c3lsaW5lVXNlcnMpIHtcbiAgICAgICAgYnVzeWxpbmVVc2Vyc1N0YXRlID0gZGF0YSEuYnVzeWxpbmVVc2Vycz8ubWFwKChpdGVtKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyB0YXJnZXRUeXBlLCB0YXJnZXRJZCB9ID0gaW52aXRlZFVzZXJzU3RhdGUuZmluZCgodXNlcikgPT4gdXNlci51c2VySWQgPT09IGl0ZW0udXNlcklkKSE7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHVzZXJJZDogaXRlbS51c2VySWQsXG4gICAgICAgICAgICB1c2VyU3RhdGU6IGl0ZW0uc2Vzc2lvblN0YXR1cyxcbiAgICAgICAgICAgIHN5c3RlbVN0YXRlOiBSQ0NhbGxQbHVzUmVhc29uLkJVU1lMSU5FX1JJTkdJTkcsXG4gICAgICAgICAgICB0YXJnZXRUeXBlLFxuICAgICAgICAgICAgdGFyZ2V0SWQsXG4gICAgICAgICAgICBjYW1lcmFFbmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgbWljcm9waG9uZUVuYWJsZTogZmFsc2UsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICAgIGludml0ZWRVc2Vyc1N0YXRlID0gaW52aXRlZFVzZXJzU3RhdGUuZmlsdGVyKCh7IHVzZXJJZCB9KSA9PiBidXN5bGluZVVzZXJzU3RhdGUhLmV2ZXJ5KCh7IHVzZXJJZDogYnVzeVVzZXJJZCB9KSA9PiBidXN5VXNlcklkICE9PSB1c2VySWQpKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy51cGRhdGVVc2Vyc1N0YXRlKGNhbGxJZCwgWy4uLmludml0ZWRVc2Vyc1N0YXRlLCAuLi5idXN5bGluZVVzZXJzU3RhdGVdLCB0cmFjZUlkKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgY29kZSwgZGF0YSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIGJlZm9yZUhhbmd1cFxuICAgKi9cbiAgcHVibGljIGNsZWFyQWxsVGltZXIoY2FsbElkOiBzdHJpbmcsIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIC8vIOa4hemZpOaJgOaciei2heaXtuiuoeaXtuWZqFxuICAgIFt0aGlzLl9tYWluU2Vzc2lvbiwgLi4udGhpcy5faG9sZFNlc3Npb25zXS5mb3JFYWNoKChzZXNzaW9uKSA9PiB7XG4gICAgICBpZiAoc2Vzc2lvbiAmJiBzZXNzaW9uLmdldENhbGxJZCgpID09PSBjYWxsSWQpIHtcbiAgICAgICAgc2Vzc2lvbi5nZXRBbGxUaW1lcklkcygpLmZvckVhY2goKHRpbWVySWQpID0+IHRoaXMuX3N0b3BUaW1lci5iaW5kKHRoaXMpKHRpbWVySWQsIHRyYWNlSWQpKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDmjILmlq1cbiAgICog6YCa6K+d6K+35rGC5Y+W5raI44CB6YCa6K+d5ouS57udXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgaGFuZ3VwKG9wdHM6IElIYW5ndXBGb3JCdXN5T3B0cywgdHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7Y29kZTogbnVtYmVyfT4ge1xuICAgIHJldHVybiB0aGlzLl9zaWduYWxNb2R1bGUuaGFuZ3VwQ2FsbCh7XG4gICAgICBjYWxsSWQ6IG9wdHMuY2FsbElkLFxuICAgICAgc3lzU3RhdHVzOiBvcHRzLnN5c3RlbVN0YXRlLFxuICAgIH0sIHRyYWNlSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIOaOpeaUtumCgOivt1xuICAgKiDpgJror53kuK3lj4jmlLbliLDmlrDmnaXnlLXlkI7vvIzmjqXlkKzmlrDmnaXnlLXml7bvvIzlv4XpobvlhYjmjILmlq3kuYvliY3nmoTpgJror53vvIhtYWluU2Vzc2lvbu+8iVxuICAgKi9cbiAgcHVibGljIGFzeW5jIGFjY2VwdChvcHRzOiBJQWNjZXB0T3B0cywgdHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7Y29kZTogbnVtYmVyfT4ge1xuICAgIC8vIOS4jeWtmOWcqCBzZXNzaW9uIOS4jeWFgeiuuOaOpeWQrFxuICAgIGlmICghdGhpcy5fbWFpblNlc3Npb24pIHtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLk5PVF9JTl9DQUxMIH07XG4gICAgfVxuICAgIGNvbnN0IHsgY29kZSB9ID0gYXdhaXQgdGhpcy5fc2lnbmFsTW9kdWxlLmFjY2VwdENhbGwoeyBjYWxsSWQ6IG9wdHMuY2FsbElkIH0sIHRyYWNlSWQpO1xuXG4gICAgLy8g5riF6Zmk5o6l5ZCs6LaF5pe26K6h5pe25ZmoXG4gICAgdGhpcy5fc3RvcFRpbWVyKHRoaXMuX21haW5TZXNzaW9uIS5nZXRJbnZpdGVlVGltZXJJZCgpLCB0cmFjZUlkKTtcbiAgICBpZiAoY29kZSAhPT0gUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUykge1xuICAgICAgcmV0dXJuIHsgY29kZSB9O1xuICAgIH1cbiAgICB0aGlzLl9jbGVhck1vYmlsZU9uUGhvbmUob3B0cy5jYWxsSWQsIHRyYWNlSWQpO1xuICAgIHRoaXMuX21haW5TZXNzaW9uLnVwZGF0ZVNlc3Npb25TdGF0ZShSQ0NhbGxQbHVzQ2FsbFN0YXRlLkNPTk5FQ1RJTkcpO1xuXG4gICAgcmV0dXJuIHsgY29kZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOebtOaOpeWKoOWFpVxuICAgKi9cbiAgcHVibGljIGFzeW5jIGpvaW5DYWxsKG9wdHM6IElKb2luQ2FsbE9wdHMsIHRyYWNlSWQ6IHN0cmluZyk6IFByb21pc2U8e2NvZGU6IG51bWJlcn0+IHtcbiAgICBjb25zdCBjdXJyZW50VXNlcklkID0gdGhpcy5fY29udGV4dC5nZXRDdXJyZW50SWQoKTtcbiAgICAvLyDlhYjmlLbliLAgb25JbnZpdGXvvIzmsqHmnInmjqXpgJrov4cgam9pbkNhbGwg5riF6Zmk5o6l5ZCs6LaF5pe26K6h5pe25ZmoXG4gICAgdGhpcy5fbWFpblNlc3Npb24gJiYgdGhpcy5fc3RvcFRpbWVyKHRoaXMuX21haW5TZXNzaW9uIS5nZXRJbnZpdGVlVGltZXJJZCgpLCB0cmFjZUlkKTtcbiAgICBjb25zdCB7IGNvZGUgfSA9IGF3YWl0IHRoaXMuX3NpZ25hbE1vZHVsZS5qb2luQ2FsbCh7IGNhbGxJZDogb3B0cy5jYWxsSWQgfSwgdHJhY2VJZCk7XG4gICAgaWYgKGNvZGUgIT09IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICB9XG5cbiAgICAvLyDmnKzlnLDlrZjlgqggY2FsbElkLCBjYWxsIOW8guW4uOmAgOWHuuaXtuS9v+eUqFxuICAgIHRoaXMuX2Fibm9ybWFsTW9kdWxlLmFkZEFibm9ybWFsbENhbGxJZChjdXJyZW50VXNlcklkLCBvcHRzLmNhbGxJZCk7XG5cbiAgICBpZiAoIXRoaXMuX21haW5TZXNzaW9uKSB7XG4gICAgICAvLyDlpoLmnpzkuI3lrZjlnKggbWFpblNlc3Npb24g5LuOIHNlcnZlciDojrflj5blvZPliY3liqDlhaXnmoQgc2Vzc2lvblxuICAgICAgYXdhaXQgdGhpcy5fY3JlYXRlU2Vzc2lvbkJ5U2VydmVyKG9wdHMuY2FsbElkLCB0cnVlLCB0cmFjZUlkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fY2xlYXJNb2JpbGVPblBob25lKG9wdHMuY2FsbElkLCB0cmFjZUlkKTtcbiAgICB9XG5cbiAgICByZXR1cm4geyBjb2RlIH07XG4gIH1cblxuICAvKipcbiAgICog6YCa6K+d5aqS5L2T5Y+Y5pu06K+35rGCXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVxdWVzdENoYW5nZU1lZGlhVHlwZShvcHRzOiBJUmVxQ2hhbmdlTWVkaWFUeXBlT3B0cywgdHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7Y29kZTogbnVtYmVyLCBkYXRhPzogSVJlcUNoYW5nZU1lZGlhVHlwZVJlc30+IHtcbiAgICAvLyDkuI3lrZjlnKjmraPlnKjpgJror53kuK0gc2Vzc2lvbiwg5LiN5YWB6K646LCD55SoXG4gICAgaWYgKCF0aGlzLl9tYWluU2Vzc2lvbikge1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuTk9UX0lOX0NBTEwgfTtcbiAgICB9XG5cbiAgICBjb25zdCBleHRyYUtleVZhbCA9IHtcbiAgICAgIG1lZGlhVHlwZTogb3B0cy5tZWRpYVR5cGUsXG4gICAgfTtcbiAgICB0aGlzLl9tYWluU2Vzc2lvbi51cGRhdGVSZXFNZWRpYVR5cGUob3B0cy5tZWRpYVR5cGUpO1xuICAgIGNvbnN0IHRyYW5zYWN0aW9uSWQgPSBnZXRVVUlEMjIoKTtcbiAgICBjb25zdCB7IGNvZGUgfSA9IGF3YWl0IHRoaXMuX3NpZ25hbE1vZHVsZS5kaWFsb2dVcENhbGwoe1xuICAgICAgdHJhbnNhY3Rpb25JZCxcbiAgICAgIGNhbGxJZDogdGhpcy5fbWFpblNlc3Npb24uZ2V0Q2FsbElkKCksXG4gICAgICB0b1VzZXJJZHM6IG9wdHMudG9Vc2VySWRzLFxuICAgICAgZGlhbG9nVHlwZTogRGlhbG9nVHlwZS5TV0lUQ0hfTUVESUFfVFlQRSxcbiAgICAgIGFjdGlvbjogRGlhbG9nQWN0aW9uLlJFUVVFU1QsXG4gICAgICBleHRyYUtleVZhbCxcbiAgICB9LCB0cmFjZUlkKTtcbiAgICBpZiAoY29kZSAhPT0gUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUykge1xuICAgICAgcmV0dXJuIHsgY29kZSB9O1xuICAgIH1cblxuICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MsIGRhdGE6IHsgdHJhbnNhY3Rpb25JZCB9IH07XG4gIH1cblxuICAvKipcbiAgICog6YCa6K+d5aqS5L2T57G75Z6L5Y+Y5pu06K+35rGC5ZON5bqUXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVzcG9uc2VDaGFuZ2VNZWRpYVR5cGUob3B0czogSVJlc0NoYW5nZU1lZGlhVHlwZU9wdHMsIHRyYWNlSWQ6IHN0cmluZyk6IFByb21pc2U8e2NvZGU6IG51bWJlcn0+IHtcbiAgICAvLyDkuI3lrZjlnKjmraPlnKjpgJror53kuK0gc2Vzc2lvbiwg5LiN5YWB6K646LCD55SoXG4gICAgaWYgKCF0aGlzLl9tYWluU2Vzc2lvbikge1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuTk9UX0lOX0NBTEwgfTtcbiAgICB9XG5cbiAgICBjb25zdCByZXFNZWRpYVR5cGUgPSB0aGlzLl9tYWluU2Vzc2lvbi5nZXRSZXFNZWRpYVR5cGUoKTtcbiAgICBpZiAob3B0cy5hZ3JlZSkge1xuICAgICAgdGhpcy5fbWFpblNlc3Npb24udXBkYXRlTWVkaWFUeXBlKHJlcU1lZGlhVHlwZSEpO1xuICAgICAgdGhpcy5fbWFpblNlc3Npb24udXBkYXRlUmVxTWVkaWFUeXBlKG51bGwpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc2lnbmFsTW9kdWxlLmRpYWxvZ1VwQ2FsbCh7XG4gICAgICB0cmFuc2FjdGlvbklkOiBvcHRzLnRyYW5zYWN0aW9uSWQsXG4gICAgICBjYWxsSWQ6IHRoaXMuX21haW5TZXNzaW9uLmdldENhbGxJZCgpLFxuICAgICAgZGlhbG9nVHlwZTogRGlhbG9nVHlwZS5TV0lUQ0hfTUVESUFfVFlQRSxcbiAgICAgIGFjdGlvbjogb3B0cy5hZ3JlZSA/IERpYWxvZ0FjdGlvbi5BQ0NFUFQgOiBEaWFsb2dBY3Rpb24uUkVGVVNFLFxuICAgIH0sIHRyYWNlSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIOWPlua2iOmAmuivneWqkuS9k+exu+Wei+WIh+aNouivt+axglxuICAgKi9cbiAgcHVibGljIGFzeW5jIGNhbmNlbENoYW5nZU1lZGlhVHlwZShvcHRzOiBJQ2FuY2VsQ2hhbmdlTWVkaWFUeXBlT3B0cywgdHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7Y29kZTogbnVtYmVyfT4ge1xuICAgIC8vIOS4jeWtmOWcqOato+WcqOmAmuivneS4rSBzZXNzaW9uLCDkuI3lhYHorrjosIPnlKhcbiAgICBpZiAoIXRoaXMuX21haW5TZXNzaW9uKSB7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5OT1RfSU5fQ0FMTCB9O1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9zaWduYWxNb2R1bGUuZGlhbG9nVXBDYWxsKHtcbiAgICAgIHRyYW5zYWN0aW9uSWQ6IG9wdHMudHJhbnNhY3Rpb25JZCxcbiAgICAgIGNhbGxJZDogdGhpcy5fbWFpblNlc3Npb24uZ2V0Q2FsbElkKCksXG4gICAgICBkaWFsb2dUeXBlOiBEaWFsb2dUeXBlLlNXSVRDSF9NRURJQV9UWVBFLFxuICAgICAgYWN0aW9uOiBEaWFsb2dBY3Rpb24uQ0FOQ0VMLFxuICAgIH0sIHRyYWNlSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPliBjYWxsIGxvZyDliJfooahcbiAgICovXG4gIHB1YmxpYyBhc3luYyBnZXRDYWxsTG9nTGlzdChvcHRzOiBJR2V0Q2FsbExvZ0xpc3RPcHRzLCB0cmFjZUlkOiBzdHJpbmcpOiBQcm9taXNlPHtjb2RlOiBudW1iZXIsIGRhdGE/OiBJUkNDYWxsUGx1c0dldENhbGxSZWNvcmRSZXN9PiB7XG4gICAgY29uc3QgY3VycmVudFVzZXJJZCA9IHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudElkKCk7XG4gICAgY29uc3QgeyBjb2RlLCBkYXRhIH0gPSBhd2FpdCB0aGlzLl9zaWduYWxNb2R1bGUuc3luY0NhbGxMb2coe1xuICAgICAgdXNlcklkOiBjdXJyZW50VXNlcklkLFxuICAgICAgc3luY1RpbWU6IG9wdHMudGltZXN0YW1wLFxuICAgICAgY291bnQ6IG9wdHMuY291bnQsXG4gICAgfSwgdHJhY2VJZCk7XG4gICAgaWYgKGNvZGUgIT09IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICB9XG4gICAgY29uc3QgY2FsbExvZzogSVJDQ2FsbFBsdXNDYWxsUmVjb3JkW10gPSBkYXRhIS5jYWxsTG9nTGlzdC5tYXAoKGl0ZW0pID0+IHRyYW4yQ2FsbExvZyhpdGVtKSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyxcbiAgICAgIGRhdGE6IHtcbiAgICAgICAgaGFzTW9yZTogQm9vbGVhbihkYXRhPy5oYXNNb3JlKSxcbiAgICAgICAgbWF4VGltZTogZGF0YSEubWF4VGltZSxcbiAgICAgICAgbGlzdDogY2FsbExvZyxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDmibnph4/liKDpmaTpgJror53ml6Xlv5dcbiAgICovXG4gIHB1YmxpYyBhc3luYyBkZWxldGVDYWxsTG9nKGNhbGxJZHM6IHN0cmluZ1tdLCB0cmFjZUlkOiBzdHJpbmcpOiBQcm9taXNlPHtjb2RlOiBudW1iZXJ9PiB7XG4gICAgY29uc3QgY3VycmVudFVzZXJJZCA9IHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudElkKCk7XG4gICAgcmV0dXJuIHRoaXMuX3NpZ25hbE1vZHVsZS5kZWxldGVDYWxsUmVjb3JkKGN1cnJlbnRVc2VySWQsIGNhbGxJZHMsIHRyYWNlSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPliBjYWxsIHNlcnZlciDlvZPliY3ml7bpl7TmiLNcbiAgICovXG4gIHB1YmxpYyBhc3luYyBnZXRDYWxsU2VydmVyVGltZXN0YW1wKHRyYWNlSWQ6IHN0cmluZyk6IFByb21pc2U8e2NvZGU6IG51bWJlciwgZGF0YT86IG51bWJlcn0+IHtcbiAgICBjb25zdCB7IGNvZGUsIGRhdGEgfSA9IGF3YWl0IHRoaXMuX3NpZ25hbE1vZHVsZS5nZXRDYWxsU2VydmVyVGltZXN0YW1wKHRyYWNlSWQpO1xuICAgIGlmIChjb2RlICE9PSBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTKSB7XG4gICAgICByZXR1cm4geyBjb2RlIH07XG4gICAgfVxuICAgIHJldHVybiB7IGNvZGUsIGRhdGE6IGRhdGEhLnN5bmNUaW1lIH07XG4gIH1cblxuICAvKipcbiAgICog6I635Y+WIGNhbGwg5pe26Ze05L+h5oGvXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZ2V0Q2FsbFRpbWVJbmZvKGNhbGxJZDogc3RyaW5nLCB0cmFjZUlkOiBzdHJpbmcpOiBQcm9taXNlPHtjb2RlOiBudW1iZXIsIGRhdGE/OiBJR2V0Q2FsbFRpbWVJbmZvUmVzfT4ge1xuICAgIHJldHVybiB0aGlzLl9zaWduYWxNb2R1bGUuZ2V0Q2FsbFRpbWVJbmZvKGNhbGxJZCwgdHJhY2VJZCk7XG4gIH1cblxuICAvKipcbiAgICog6I635Y+W5pyq57uT5p2f55qE6YCa6K+d5YiX6KGoXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZ2V0T3BlbkNhbGxMaXN0KHRyYWNlSWQ6IHN0cmluZyk6IFByb21pc2U8e2NvZGU6IG51bWJlciwgZGF0YT86IElSQ0NhbGxQbHVzQ2FsbFJlY29yZFtdIH0+IHtcbiAgICBjb25zdCBjdXJyZW50VXNlcklkID0gdGhpcy5fY29udGV4dC5nZXRDdXJyZW50SWQoKTtcbiAgICBjb25zdCB7IGNvZGUsIGRhdGE6IHJlc0RhdGEgfSA9IGF3YWl0IHRoaXMuX3NpZ25hbE1vZHVsZS5nZXRVc2VyQ2FsbFN0YXRlTGlzdCh0cmFjZUlkKTtcbiAgICBpZiAoY29kZSAhPT0gUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUykge1xuICAgICAgcmV0dXJuIHsgY29kZSB9O1xuICAgIH1cblxuICAgIGNvbnN0IGxpc3QgPSByZXNEYXRhIS5jYWxsU3RhdGVMaXN0Lm1hcCgoaXRlbSkgPT4ge1xuICAgICAgY29uc3Qge1xuICAgICAgICBjYWxsSWQsIGNhbGxUeXBlLCBtZWRpYVR5cGUsIGNhbGxpbmdVc2VySWQsIGNhbGxVc2VySWRzLCBjYWxsU3RhdHVzLCBjcnRUaW1lLCB1c2VyU2Vzc2lvblN0YXR1cywgdGFyZ2V0VHlwZSwgdGFyZ2V0SWQsIHN0YXJ0VGltZSwgc3luY1RpbWUsXG4gICAgICB9ID0gaXRlbTtcbiAgICAgIGNvbnN0IGNhbGxEaXJlY3Rpb24gPSAoY2FsbGluZ1VzZXJJZCA9PT0gY3VycmVudFVzZXJJZCkgPyBSQ0NhbGxEaXJlY3Rpb24uT1VUIDogUkNDYWxsRGlyZWN0aW9uLklOO1xuICAgICAgY29uc3QgeyBjbGllbnRTdGFydFRpbWUgPSBzdGFydFRpbWUgfSA9IHRoaXMuX3RpbWVDb3JyZWN0aW9uZXIuY2FsY0NsaWVudFN0YXJ0VGltZShjYWxsSWQsIHN0YXJ0VGltZSwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjYWxsSWQsXG4gICAgICAgIGNhbGxUeXBlLFxuICAgICAgICBjYWxsRGlyZWN0aW9uLFxuICAgICAgICBtZWRpYVR5cGUsXG4gICAgICAgIGNhbGxlclVzZXJJZDogY2FsbGluZ1VzZXJJZCxcbiAgICAgICAgY2FsbFVzZXJJZHMsXG4gICAgICAgIHNlc3Npb25TdGF0ZTogY2FsbFN0YXR1cyxcbiAgICAgICAgdXNlclN0YXRlOiB1c2VyU2Vzc2lvblN0YXR1cyxcbiAgICAgICAgc3RhcnRUaW1lc3RhbXA6IHN0YXJ0VGltZSxcbiAgICAgICAgZW5kVGltZXN0YW1wOiAwLFxuICAgICAgICBkdXJhdGlvbjogTWF0aC5mbG9vcigoK25ldyBEYXRlKCkgLSBjbGllbnRTdGFydFRpbWUpIC8gMTAwMCksXG4gICAgICAgIHN5bmNUaW1lc3RhbXA6IHN5bmNUaW1lLFxuICAgICAgICBzeXN0ZW1TdGF0ZTogMCxcbiAgICAgICAgY3JlYXRlVGltZXN0YW1wOiBjcnRUaW1lLFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBjb2RlLFxuICAgICAgZGF0YTogbGlzdCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOa4hemZpOW9k+WJjeeUqOaIt+eahCBjYWxsIGxvZ1xuICAgKi9cbiAgcHVibGljIGFzeW5jIHJlbW92ZUFsbENhbGxMb2codHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7Y29kZTogbnVtYmVyIH0+IHtcbiAgICBjb25zdCB7IGNvZGUgfSA9IGF3YWl0IHRoaXMuX3NpZ25hbE1vZHVsZS5jbGVhckNhbGxSZWNvcmQodHJhY2VJZCk7XG4gICAgaWYgKGNvZGUgIT09IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICB9XG4gICAgcmV0dXJuIHsgY29kZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOmAmui/hyBjYWxsSWQg6I635Y+WIHNlc3Npb24g6K+m57uG5L+h5oGvXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZ2V0Q2FsbFNlc3Npb24ob3B0czogSUNhbGxJZCwgdHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7Y29kZTogbnVtYmVyLCBkYXRhPzogSUdldENhbGxTZXNzaW9uUmVzfT4ge1xuICAgIGNvbnN0IHsgY29kZSwgZGF0YSB9ID0gYXdhaXQgdGhpcy5fc2lnbmFsTW9kdWxlLmdldENhbGxTZXNzaW9uKG9wdHMsIHRyYWNlSWQpO1xuICAgIGlmIChjb2RlICE9PSBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTKSB7XG4gICAgICByZXR1cm4geyBjb2RlIH07XG4gICAgfVxuXG4gICAgY29uc3Qge1xuICAgICAgY2FsbElkLCBjYWxsaW5nVXNlcklkLCBjYWxsVHlwZSwgbWVkaWFUeXBlLCBjYWxsU3RhdHVzLCBjYWxsU2Vzc2lvblVzZXJzLCBzdGFydFRpbWUsIGR1cmF0aW9uLCBzeW5jVGltZSxcbiAgICB9ID0gZGF0YSE7XG4gICAgY29uc3Qgc2Vzc2lvblVzZXJzID0gY2FsbFNlc3Npb25Vc2Vycy5tYXAoKGl0ZW0pID0+IHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgdXNlcklkLCBzZXNzaW9uU3RhdHVzLCBzeXNTdGF0dXMsIHRhcmdldFR5cGUsIHRhcmdldElkLFxuICAgICAgfSA9IGl0ZW07XG4gICAgICByZXR1cm4ge1xuICAgICAgICB1c2VySWQsXG4gICAgICAgIHVzZXJTdGF0ZTogc2Vzc2lvblN0YXR1cyxcbiAgICAgICAgc3lzdGVtU3RhdGU6IHN5c1N0YXR1cyxcbiAgICAgICAgdGFyZ2V0VHlwZSxcbiAgICAgICAgdGFyZ2V0SWQsXG4gICAgICAgIGNhbWVyYUVuYWJsZTogZmFsc2UsXG4gICAgICAgIG1pY3JvcGhvbmVFbmFibGU6IGZhbHNlLFxuICAgICAgfTtcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgY29kZSxcbiAgICAgIGRhdGE6IHtcbiAgICAgICAgY2FsbElkLFxuICAgICAgICBzdGFydENhbGxlcklkOiBjYWxsaW5nVXNlcklkLFxuICAgICAgICBjYWxsVHlwZSxcbiAgICAgICAgbWVkaWFUeXBlLFxuICAgICAgICBzZXNzaW9uU3RhdGU6IGNhbGxTdGF0dXMsXG4gICAgICAgIGNhbGxTZXNzaW9uVXNlcnM6IHNlc3Npb25Vc2VycyxcbiAgICAgICAgc3RhcnRUaW1lLFxuICAgICAgICBkdXJhdGlvbixcbiAgICAgICAgc3luY1RpbWUsXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBwdWJsaWMgZ2V0SG9sZFNlc3Npb24oY2FsbElkOiBzdHJpbmcpOiBSQ0NhbGxQbHVzU2Vzc2lvbiB8IG51bGwge1xuICAgIGNvbnN0IGlubmVyU2Vzc2lvbiA9IHRoaXMuX2hvbGRTZXNzaW9ucy5maW5kKChzZXNzaW9uKSA9PiBzZXNzaW9uICYmIHNlc3Npb24uZ2V0Q2FsbElkKCkgPT09IGNhbGxJZCk7XG4gICAgcmV0dXJuIGlubmVyU2Vzc2lvbiA/IG5ldyBSQ0NhbGxQbHVzU2Vzc2lvbihpbm5lclNlc3Npb24sIHRoaXMsIHRoaXMuX2xvZ2dlcikgOiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPluW9k+WJjeS4uyBzZXNzaW9uXG4gICAqL1xuICBwdWJsaWMgZ2V0TG9jYWxNYWluU2Vzc2lvbigpOiBSQ0NhbGxQbHVzU2Vzc2lvbiB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9tYWluU2Vzc2lvbiA/IG5ldyBSQ0NhbGxQbHVzU2Vzc2lvbih0aGlzLl9tYWluU2Vzc2lvbiwgdGhpcywgdGhpcy5fbG9nZ2VyKSA6IG51bGw7XG4gIH1cblxuICAvKipcbiAgICog6K6+572u5Li7IHNlc3Npb24g54q25oCBXG4gICAqL1xuICBwdWJsaWMgdXBkYXRlTWFpblNlc3Npb25TdGF0ZShzdGF0ZTogUkNDYWxsUGx1c0NhbGxTdGF0ZSkge1xuICAgIHRoaXMuX21haW5TZXNzaW9uPy51cGRhdGVTZXNzaW9uU3RhdGUoc3RhdGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIOiusOW9leaYr+WQpuaYr+acrOerr+aMguaWrVxuICAgKi9cbiAgcHVibGljIHNldElzTG9jYWxDbGllbnRIYW5ndXAoaXNMb2NhbENsaWVudEhhbmd1cDogYm9vbGVhbikge1xuICAgIHRoaXMuX21haW5TZXNzaW9uPy5zZXRJc0xvY2FsQ2xpZW50SGFuZ3VwKGlzTG9jYWxDbGllbnRIYW5ndXApO1xuICB9XG5cbiAgLyoqXG4gICAqIOmAmuefpeS6uuWRmOeKtuaAgVxuICAgKiBDYWxsQ2xpZW50IOS5n+mcgOimgeabtOaWsOS6uuWRmOeKtuaAge+8jOWumuS5ieS4uuWFrOWFseWHveaVsFxuICAgKi9cbiAgcHVibGljIHVwZGF0ZVVzZXJzU3RhdGUoY2FsbElkOiBzdHJpbmcsIHVzZXJzOiBJU2Vzc2lvblVzZXJbXSwgdHJhY2VJZDogc3RyaW5nKSB7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExfRU5HSU5FX1VQREFURV9VU0VSU19TVEFURV9PLCBgdXBkYXRlVXNlcnNTdGF0ZSAtPiB1c2VyczogJHtKU09OLnN0cmluZ2lmeSh1c2Vycyl9YCwgdHJhY2VJZCk7XG5cbiAgICAvLyDmm7TmlrAgc2Vzc2lvbiDkurrlkZjliJfooahcbiAgICBjb25zdCBzZXNzaW9uID0gW3RoaXMuX21haW5TZXNzaW9uLCAuLi50aGlzLl9ob2xkU2Vzc2lvbnNdLmZpbmQoKGl0ZW0pID0+IGl0ZW0/LmdldENhbGxJZCgpID09PSBjYWxsSWQpO1xuXG4gICAgY29uc3QgY2hhbmdlZFVzZXJzID0gW107XG4gICAgaWYgKHNlc3Npb24pIHtcbiAgICAgIGNvbnN0IG5ld1VzZXJzID0gdXNlcnMubWFwKChpdGVtKSA9PiB7XG4gICAgICAgIGNvbnN0IG9sZFVzZXJTdGF0ZSA9IHNlc3Npb24uZ2V0VXNlckxpc3QoKS5maWx0ZXIoKHsgdXNlcklkIH0pID0+IHVzZXJJZCA9PT0gaXRlbS51c2VySWQpWzBdIHx8IHt9O1xuICAgICAgICBjb25zdCBpc0lkbGUgPSBpdGVtLnVzZXJTdGF0ZSA9PT0gUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUuSURMRTtcbiAgICAgICAgY29uc3QgeyBjYW1lcmFFbmFibGUgPSBmYWxzZSwgbWljcm9waG9uZUVuYWJsZSA9IGZhbHNlIH0gPSBpc0lkbGUgPyB7IGNhbWVyYUVuYWJsZTogZmFsc2UsIG1pY3JvcGhvbmVFbmFibGU6IGZhbHNlIH0gOiBvbGRVc2VyU3RhdGU7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4uaXRlbSxcbiAgICAgICAgICBjYW1lcmFFbmFibGUsXG4gICAgICAgICAgbWljcm9waG9uZUVuYWJsZSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuXG4gICAgICBjaGFuZ2VkVXNlcnMucHVzaCguLi5zZXNzaW9uLnVwZGF0ZVVzZXJMaXN0KG5ld1VzZXJzLCB0cmFjZUlkKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNoYW5nZWRVc2Vycy5wdXNoKC4uLnVzZXJzKTtcbiAgICB9XG4gICAgLy8g6YCa55+l5LqL5Lu2XG4gICAgY2hhbmdlZFVzZXJzLmxlbmd0aCA+IDAgJiYgdGhpcy5fb25Vc2VyU3RhdGVDaGFuZ2UoY2FsbElkLCBjaGFuZ2VkVXNlcnMsIHRyYWNlSWQpO1xuICB9XG5cbiAgcHVibGljIHNldFVzZXJEZXZpY2VFbmFibGUodXNlcklkOiBzdHJpbmcsIG1lZGlhVHlwZTogUkNDYWxsUGx1c01lZGlhVHlwZSwgZW5hYmxlOiBib29sZWFuLCB0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9tYWluU2Vzc2lvbj8uc2V0VXNlckRldmljZUVuYWJsZSh1c2VySWQsIG1lZGlhVHlwZSwgZW5hYmxlLCB0cmFjZUlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDojrflj5bpgJror53lvIDlp4vml7bpl7RcbiAgICovXG4gIHB1YmxpYyBhc3luYyBnZXRDYWxsU3RhcmluZ1RpbWUob3B0czogSUNhbGxJZCwgdHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7Y29kZTogbnVtYmVyLCBkdXJhdGlvbj86IG51bWJlciwgY2xpZW50U3RhcnRUaW1lPzogbnVtYmVyfT4ge1xuICAgIHJldHVybiB0aGlzLl90aW1lQ29ycmVjdGlvbmVyLmdldENhbGxDbGllbnRUaW1lQnlTZXJ2ZXIob3B0cy5jYWxsSWQsIHRyYWNlSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIOS6uuWRmOezu+e7n+eKtuaAgeS4iuaKpVxuICAgKi9cbiAgcHVibGljIGFzeW5jIHN5c3RlbVN0YXR1c1VwKG9wdHM6IElTeXNTdGF0dXNVcE9wdHMsIHRyYWNlSWQ6IHN0cmluZyk6IFByb21pc2U8e2NvZGU6IG51bWJlciB9PiB7XG4gICAgcmV0dXJuIHRoaXMuX3NpZ25hbE1vZHVsZS5zeXNTdGF0dXNVcChvcHRzLCB0cmFjZUlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDljZXlkbzkuK3mlLbliLDov5znq6/mtYHlkI7vvIznu5kgQ2FsbFNlcnZlciDkuIrmiqXvvIznlKjkuo7lpITnkIborqHml7bpgLvovpFcbiAgICovXG4gIHB1YmxpYyBhc3luYyB1cEZpcnN0RnJhbWVUaW1lKHRyYWNlSWQ6IHN0cmluZyk6IFByb21pc2U8e2NvZGU6IG51bWJlcn0+IHtcbiAgICBjb25zdCBub05lZWRVcENvbmRpdGlvbiA9ICF0aGlzLl9tYWluU2Vzc2lvblxuICAgICAgfHwgKHRoaXMuX21haW5TZXNzaW9uICYmIHRoaXMuX21haW5TZXNzaW9uLmdldENhbGxUeXBlKCkgIT09IFJDQ2FsbFBsdXNUeXBlLlNJTkdMRSlcbiAgICAgIHx8IHRoaXMuX2lzVXBGaXJzdEZyYW1lVGltZTtcbiAgICBpZiAobm9OZWVkVXBDb25kaXRpb24pIHtcbiAgICAgIC8vIOS4jeWtmCBtYWluU2Vzc2lvbiDmiJYg6YCa6L+H57G75Z6L5LiN5Li65Y2V5ZG85pe277yM5LiN5LiK5oql77yM55u05o6l6L+U5Zue5oiQ5YqfXG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTIH07XG4gICAgfVxuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgY29uc3QgZGVsYXlUaW1lID0gdGhpcy5fdGltZUNvcnJlY3Rpb25lci5nZXRMb2NhbERlbGF5VGltZSgpO1xuICAgIGNvbnN0IHN0cmVhbVJlYWR5VGltZSA9IE1hdGguZmxvb3Iobm93ICsgZGVsYXlUaW1lKTtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTF9FTkdJTkVfVVBfRklSU1RfRlJBTUVfVElNRV9ULCBgbm93OiAke25vd307IGRlbGF5OiAke2RlbGF5VGltZX07IHN0cmVhbVJlYWR5VGltZTogJHtzdHJlYW1SZWFkeVRpbWV9YCwgdHJhY2VJZCk7XG5cbiAgICB0aGlzLl9pc1VwRmlyc3RGcmFtZVRpbWUgPSB0cnVlO1xuXG4gICAgY29uc3QgY2FsbElkID0gdGhpcy5fbWFpblNlc3Npb24hLmdldENhbGxJZCgpO1xuICAgIGNvbnN0IHsgY29kZSB9ID0gYXdhaXQgdGhpcy5fc2lnbmFsTW9kdWxlLmV2ZW50VXBDYWxsKHtcbiAgICAgIGNhbGxJZCxcbiAgICAgIGV2ZW50VHlwZTogQ2FsbFNlcnZlckV2ZW50VHlwZS5GSVJTVF9GUkFNRSxcbiAgICAgIGV2ZW50QXJnczogeyBzdHJlYW1SZWFkeVRpbWUgfSxcbiAgICAgIGV2ZW50VGltZTogRGF0ZS5ub3coKSxcbiAgICB9LCB0cmFjZUlkKTtcblxuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMX0VOR0lORV9VUF9GSVJTVF9GUkFNRV9USU1FX1IsIGBjb2RlOiAke2NvZGV9YCwgdHJhY2VJZCk7XG5cbiAgICByZXR1cm4geyBjb2RlIH07XG4gIH1cblxuICAvKipcbiAgICog5LiK5bGC5qih5oufIHN0YXR1c0Rvd25DYWxsLCDnu5PmnZ8gc2Vzc2lvblxuICAgKiDpgJror53lu7rnq4vlkI7vvIzlj6rog73nu5PmnZ8gbWFpblNlc3Npb25cbiAgICovXG4gIHB1YmxpYyBlbmRDdXJyZW50U2Vzc2lvbihjdXJyZW50VXNlclN5c3RlbVN0YXRlOiBSQ0NhbGxQbHVzUmVhc29uLCBjYWxsSWQ6IHN0cmluZywgdHJhY2VJZDogc3RyaW5nKSB7XG4gICAgY29uc3QgY3VycmVudFVzZXJJZCA9IHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudElkKCk7XG4gICAgaWYgKHRoaXMuX21haW5TZXNzaW9uICYmIHRoaXMuX21haW5TZXNzaW9uLmdldENhbGxJZCgpID09PSBjYWxsSWQpIHtcbiAgICAgIGNvbnN0IHNlc3Npb25Vc2VyczogSUNhbGxTZXNzaW9uVXNlcltdID0gdGhpcy5fbWFpblNlc3Npb24uZ2V0VXNlckxpc3QoKS5tYXAoKGl0ZW0pID0+IHtcbiAgICAgICAgbGV0IHtcbiAgICAgICAgICB1c2VySWQsIHVzZXJTdGF0ZSwgc3lzdGVtU3RhdGUsIHRhcmdldFR5cGUsIHRhcmdldElkLFxuICAgICAgICB9ID0gaXRlbTtcbiAgICAgICAgaWYgKHVzZXJJZCA9PT0gY3VycmVudFVzZXJJZCkge1xuICAgICAgICAgIHN5c3RlbVN0YXRlID0gY3VycmVudFVzZXJTeXN0ZW1TdGF0ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHVzZXJJZCxcbiAgICAgICAgICBzZXNzaW9uU3RhdHVzOiBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZS5FTkRFRCxcbiAgICAgICAgICBzdGF0dXNUaW1lOiBEYXRlLm5vdygpLFxuICAgICAgICAgIGR1cmF0aW9uOiAwLFxuICAgICAgICAgIGNoYW5nZWQ6IDEsXG4gICAgICAgICAgaW52aXRlVXNlcklkOiB0aGlzLl9tYWluU2Vzc2lvbiEuZ2V0U3RhcnRDYWxsZXJJZCgpLFxuICAgICAgICAgIHN5c1N0YXR1czogc3lzdGVtU3RhdGUsXG4gICAgICAgICAgdGFyZ2V0VHlwZSxcbiAgICAgICAgICB0YXJnZXRJZCxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgICAgY29uc3QgZGF0YTogSVN0YXR1c0Rvd25Db250ID0ge1xuICAgICAgICBjYWxsSWQ6IHRoaXMuX21haW5TZXNzaW9uLmdldENhbGxJZCgpLFxuICAgICAgICB0b0RldmljZUlkOiB0aGlzLl9zaWduYWxNb2R1bGUuZ2V0U2Vzc2lvbklkKCksXG4gICAgICAgIGNhbGxTdGF0dXM6IFJDQ2FsbFBsdXNDYWxsU3RhdGUuRU5ERUQsXG4gICAgICAgIGR1cmF0aW9uOiAwLFxuICAgICAgICBjYWxsU2Vzc2lvblVzZXJzOiBzZXNzaW9uVXNlcnMsXG4gICAgICB9O1xuICAgICAgdGhpcy5fb25TdGF0dXNEb3duKGRhdGEsIHRyYWNlSWQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDkuIrlsYIgUlRDIOWKoOWFpeaIv+mXtOWQjumHjeaWsOW8gOWni+agoeaXtlxuICAgKi9cbiAgcHVibGljIHN0YXJ0VGltZUNvcnJlY3Rpb24odHJhY2VJZDogc3RyaW5nKSB7XG4gICAgdGhpcy5fdGltZUNvcnJlY3Rpb25lci5yZXN0YXJ0KHRyYWNlSWQpO1xuICB9XG5cbiAgcHVibGljIGdldERlbGF5VGltZUluZm8oKTogSUdldERlbGF5VGltZUluZm9SZXMge1xuICAgIHJldHVybiB7XG4gICAgICBkZWxheVRpbWU6IHRoaXMuX3RpbWVDb3JyZWN0aW9uZXIuZ2V0TG9jYWxEZWxheVRpbWUoKSxcbiAgICAgIHJ0dDogdGhpcy5fdGltZUNvcnJlY3Rpb25lci5nZXRSVFQoKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIGhvbGRTZXNzaW9uIOWNh+e6p+S4uiBtYWluU2Vzc2lvblxuICAgKi9cbiAgcHVibGljIHVwZ3JhZGVNYWluU2Vzc2lvbihob2xkQ2FsbElkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBpbmRleCA9IHRoaXMuX2hvbGRTZXNzaW9ucy5maW5kSW5kZXgoKHNlc3Npb24pID0+IHNlc3Npb24uZ2V0Q2FsbElkKCkgPT09IGhvbGRDYWxsSWQpO1xuICAgIHRoaXMuX21haW5TZXNzaW9uID0gdGhpcy5faG9sZFNlc3Npb25zLnNwbGljZShpbmRleCwgMSk/LlswXTtcbiAgfVxuXG4gIC8qKiA9PT09PT3np4HmnInmlrnms5U9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuICAvKipcbiAgICogSU0g54q25oCB5Y+Y5pu05aSE55CGXG4gICAqL1xuICBwcml2YXRlIF9vbklNU3RhdGVDaGFuZ2Uoc3RhdGU6IFJDQ29ubmVjdGlvblN0YXR1cykge1xuICAgIGNvbnN0IHRyYWNlSWQgPSB0aGlzLl9sb2dnZXIuY3JlYXRlVHJhY2VJZCgpO1xuICAgIGxldCB0aW1lcklkOiBudW1iZXIgPSAwO1xuICAgIGlmIChzdGF0ZSA9PT0gUkNDb25uZWN0aW9uU3RhdHVzLkRJU0NPTk5FQ1RFRCkge1xuICAgICAgaWYgKHRoaXMuX21haW5TZXNzaW9uICYmIHRoaXMuX21haW5TZXNzaW9uLmdldFNlc3Npb25TdGF0ZSgpICE9PSBSQ0NhbGxQbHVzQ2FsbFN0YXRlLk9OQ0FMTCkge1xuICAgICAgICAvLyDmlq3nvZHnrYnlvoUgNjBzIOWQjuinpuWPkSBvblNlc3Npb25DbG9zZVxuICAgICAgICB0aW1lcklkID0gdGltZXJTZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTF9FTkdJTkVfSU1fU1RBVEVfQ0hBTkdFX08sICdlbmRDdXJyZW50U2Vzc2lvbiwgSU0gZGlzY29ubmVjdGVkIGZvciBtb3JlIHRoYW4gNjBzJywgdHJhY2VJZCk7XG4gICAgICAgICAgdGhpcy5lbmRDdXJyZW50U2Vzc2lvbihSQ0NhbGxQbHVzUmVhc29uLkNPTk5FQ1RJT05fRVJSLCB0aGlzLl9tYWluU2Vzc2lvbj8uZ2V0Q2FsbElkKCkhLCB0cmFjZUlkKTtcbiAgICAgICAgfSwgQ0FMTF9USU1FX09VVCk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChzdGF0ZSA9PT0gUkNDb25uZWN0aW9uU3RhdHVzLkNPTk5FQ1RFRCkge1xuICAgICAgdGltZXJJZCAmJiBjbGVhclRpbWVvdXQodGltZXJJZCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOWkhOeQhuWPkei1t+mCgOivt+OAgeaUtuWIsOmCgOivt+WQjuiuoeaXtui2heaXtlxuICAgKiDmj5DliY3mqKHmi58gX29uU3RhdHVzRG93biwg5LiN5YaN5L6d6LWWIENhbGxTZXJ2ZXIg5LiL5Y+R55qEIF9vblN0YXR1c0Rvd25cbiAgICog5aSE55CG572R57uc5byC5bi45oOF5Ya15LiL5LiK5oqlIENhbGxTZXJ2ZXIg5aSx6LSl77yMQ2FsbFNlcnZlciDkuI3kvJrkuIvlj5EgX29uU3RhdHVzRG93biDmg4XlhrVcbiAgICovXG4gIHByaXZhdGUgX2hhbmRsZUNhbGxUaW1lb3V0KGNhbGxJZDogc3RyaW5nLCB1c2VyU3RhdGU6IFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLCB0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9sb2dnZXIud2FybihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTF9FTkdJTkVfQ0FMTF9USU1FT1VUX08sIGBjYWxsIHRpbWVvdXQgY2FsbElkOiAke2NhbGxJZH0sIHVzZXJTdGF0ZTogJHt1c2VyU3RhdGV9YCwgdHJhY2VJZCk7XG4gICAgY29uc3Qgc2Vzc2lvbiA9IFt0aGlzLl9tYWluU2Vzc2lvbiwgLi4udGhpcy5faG9sZFNlc3Npb25zXS5maW5kKChzZXNzaW9uKSA9PiBzZXNzaW9uICYmIHNlc3Npb24uZ2V0Q2FsbElkKCkgPT09IGNhbGxJZCk7XG4gICAgaWYgKCFzZXNzaW9uKSB7XG4gICAgICB0aGlzLl9sb2dnZXIud2FybihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTF9FTkdJTkVfQ0FMTF9USU1FT1VUX08sIGBoYW5kbGVDYWxsVGltZW91dCB3aXRob3V0IHNlc3Npb24sIGNhbGxJZDogJHtjYWxsSWR9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY3VycmVudFVzZXJJZCA9IHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudElkKCk7XG5cbiAgICB0aGlzLl9vblN0YXR1c0Rvd24oe1xuICAgICAgY2FsbElkLFxuICAgICAgdG9EZXZpY2VJZDogdGhpcy5fc2lnbmFsTW9kdWxlLmdldFNlc3Npb25JZCgpLFxuICAgICAgY2FsbFN0YXR1czogUkNDYWxsUGx1c0NhbGxTdGF0ZS5FTkRFRCxcbiAgICAgIGR1cmF0aW9uOiAwLFxuICAgICAgY2FsbFNlc3Npb25Vc2Vyczogc2Vzc2lvbi5nZXRVc2VyTGlzdCgpLm1hcCgodXNlcikgPT4ge1xuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgdXNlcklkLCB0YXJnZXRUeXBlLCB0YXJnZXRJZCwgc3RhdGVUaW1lLFxuICAgICAgICB9ID0gdXNlcjtcblxuICAgICAgICBsZXQgc3lzU3RhdHVzOiBSQ0NhbGxQbHVzUmVhc29uO1xuICAgICAgICBsZXQgc2Vzc2lvblN0YXR1czogUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGU7XG4gICAgICAgIGlmICh1c2VySWQgPT09IGN1cnJlbnRVc2VySWQpIHtcbiAgICAgICAgICBzeXNTdGF0dXMgPSB1c2VyU3RhdGUgPT09IFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLk1JU1NFRCA/IFJDQ2FsbFBsdXNSZWFzb24uTUlTU0VEIDogUkNDYWxsUGx1c1JlYXNvbi5OT19BTlNXRVI7XG4gICAgICAgICAgc2Vzc2lvblN0YXR1cyA9IHVzZXJTdGF0ZSA9PT0gUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUuTUlTU0VEID8gUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUuTUlTU0VEIDogUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUuTk9fQU5TV0VSO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN5c1N0YXR1cyA9IHVzZXJTdGF0ZSA9PT0gUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUuTUlTU0VEID8gUkNDYWxsUGx1c1JlYXNvbi5OT19BTlNXRVIgOiBSQ0NhbGxQbHVzUmVhc29uLk1JU1NFRDtcbiAgICAgICAgICBzZXNzaW9uU3RhdHVzID0gdXNlclN0YXRlID09PSBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZS5NSVNTRUQgPyBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZS5OT19BTlNXRVIgOiBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZS5NSVNTRUQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHVzZXJJZCxcbiAgICAgICAgICBzZXNzaW9uU3RhdHVzLFxuICAgICAgICAgIHN0YXR1c1RpbWU6IHN0YXRlVGltZSA/IHN0YXRlVGltZSArIDEgOiBEYXRlLm5vdygpLFxuICAgICAgICAgIGR1cmF0aW9uOiAwLFxuICAgICAgICAgIGNoYW5nZWQ6IDEsXG4gICAgICAgICAgaW52aXRlVXNlcklkOiBzZXNzaW9uLmdldENhbGxlcklkKCksXG4gICAgICAgICAgc3lzU3RhdHVzLFxuICAgICAgICAgIHRhcmdldFR5cGUsXG4gICAgICAgICAgdGFyZ2V0SWQsXG4gICAgICAgIH07XG4gICAgICB9KSxcbiAgICB9LCB0cmFjZUlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDlvIDlkK/otoXml7borqHml7blmahcbiAgICovXG4gIHByaXZhdGUgX3N0YXJ0VGltZXIoY2FsbElkOiBzdHJpbmcsIHVzZXJTdGF0ZTogUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUsIHRyYWNlSWQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgLy8g5ZCv5Yqo5ZG85Y+r6LaF5pe26K6h5pe25ZmoXG4gICAgY29uc3QgdGltZXJJZCA9IHRpbWVyU2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLl9oYW5kbGVDYWxsVGltZW91dChjYWxsSWQsIHVzZXJTdGF0ZSwgdHJhY2VJZCk7XG4gICAgICAvLyDkuIrmiqUgY2FsbCBzZXJ2ZXIg6LaF5pe2XG4gICAgICB0aGlzLl9zaWduYWxNb2R1bGUuc3RhdHVzVXBDYWxsKHsgY2FsbElkLCBzZXNzaW9uU3RhdHVzOiB1c2VyU3RhdGUgfSwgdHJhY2VJZCk7XG4gICAgfSwgQ0FMTF9USU1FX09VVCk7XG5cbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTF9FTkdJTkVfU1RBUlRfQ0FMTF9USU1FUl9PLCBgY2FsbElkOiAke2NhbGxJZH0sIHRpbWVySWQ6ICR7dGltZXJJZH1gLCB0cmFjZUlkKTtcbiAgICByZXR1cm4gdGltZXJJZDtcbiAgfVxuXG4gIC8qKlxuICAgKiDlgZzmraLotoXml7borqHml7blmahcbiAgICovXG4gIHByaXZhdGUgX3N0b3BUaW1lcih0aW1lcklkOiBudW1iZXIsIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIGNsZWFyVGltZW91dCh0aW1lcklkKTtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTF9FTkdJTkVfU1RPUF9DQUxMX1RJTUVSX08sIGB0aW1lcklkOiAke3RpbWVySWR9YCwgdHJhY2VJZCk7XG4gIH1cblxuICAvKipcbiAgICog5pS25YiwIOmAmuivnemCgOivt1xuICAgKi9cbiAgcHJpdmF0ZSBfb25JbnZpdGUoZGF0YTogSVB1Ykludml0ZUNvbiwgaXNEaXJlY3RseTogYm9vbGVhbiwgdHJhY2VJZDogc3RyaW5nKSB7XG4gICAgY29uc3QgY3VycmVudFVzZXJJZCA9IHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudElkKCk7XG4gICAgY29uc3Qge1xuICAgICAgY2FsbElkLCBpbnZpdGVVc2VySWQsIGNhbGxUeXBlLCBtZWRpYVR5cGUsIGNhbGxTZXNzaW9uVXNlcnMsIHNlY3JldENoYXQsIGNhbGxpbmdVc2VySWQsXG4gICAgfSA9IGRhdGE7XG5cbiAgICBpZiAoc2VjcmV0Q2hhdCA9PT0gU2VjcmV0Q2FsbFR5cGUuU0VDUkVUKSB7XG4gICAgICAvLyDlpoLmnpzmmK/lr4bogYrpgJror53kuI3lpITnkIZcbiAgICAgIHRoaXMuZW1pdChDYWxsSG9va3NUeXBlLm9uUHViSW52aXRlQ2FsbE1pc3MsIE9iamVjdC5hc3NpZ24oZGF0YSwge1xuICAgICAgICBleHRyYTogSlNPTi5zdHJpbmdpZnkoZGF0YSksXG4gICAgICAgIHJlYXNvbjogUHViSW52aXRlQ2FsbE1pc3NSZWFzb24uU0VDUkVUX0NBTEwsXG4gICAgICAgIHJlZmVyOiBpc0RpcmVjdGx5ID8gUHViSW52aXRlQ2FsbE1pc3NSZWZlci5QVUJfSU5WSVRFIDogUHViSW52aXRlQ2FsbE1pc3NSZWZlci5QVUxMX0tWX0lOVklURSxcbiAgICAgIH0pKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyDlpoLmnpzoh6rlt7HmmK/ooqvpgoDor7fnmoTnlKjmiLdcbiAgICBjb25zdCBpc0ludml0ZWUgPSBjYWxsU2Vzc2lvblVzZXJzLnNvbWUoKGl0ZW0pID0+IGl0ZW0udXNlcklkID09PSBjdXJyZW50VXNlcklkKTtcbiAgICBpZiAoaXNJbnZpdGVlKSB7XG4gICAgICAvLyDmnKzlnLDlrZjlgqggY2FsbElkLCBjYWxsIOW8guW4uOmAgOWHuuaXtuS9v+eUqFxuICAgICAgdGhpcy5fYWJub3JtYWxNb2R1bGUuYWRkQWJub3JtYWxsQ2FsbElkKGN1cnJlbnRVc2VySWQsIGNhbGxJZCk7XG5cbiAgICAgIC8vIOeUn+aIkCBjYWxsU2Vzc2lvblxuICAgICAgY29uc3QgaW5uZXJTZXNzaW9uID0gbmV3IFJDQ2FsbElubmVyU2Vzc2lvbihcbiAgICAgICAgY2FsbElkLFxuICAgICAgICBSQ0NhbGxQbHVzQ2FsbFN0YXRlLlJJTkdJTkcsXG4gICAgICAgIGNhbGxUeXBlLFxuICAgICAgICBtZWRpYVR5cGUsXG4gICAgICAgIGludml0ZVVzZXJJZCxcbiAgICAgICAgaW52aXRlVXNlcklkLFxuICAgICAgICBbXSxcbiAgICAgICAgdGhpcy5fbG9nZ2VyLFxuICAgICAgKTtcbiAgICAgIC8vIGNhbGwgc2VydmVyIOWTjemTg+S4iuaKpVxuICAgICAgdGhpcy5fc2lnbmFsTW9kdWxlLnJpbmdpbmdDYWxsKHsgY2FsbElkIH0sIHRyYWNlSWQpO1xuXG4gICAgICAvKipcbiAgICAgICAqIOWQr+WKqOaOpeWQrOi2heaXtuiuoeaXtuWZqFxuICAgICAgICovXG4gICAgICBjb25zdCBpbnZpdGVlVGltZXJJZCA9IHRoaXMuX3N0YXJ0VGltZXIoY2FsbElkLCBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZS5NSVNTRUQsIHRyYWNlSWQpO1xuICAgICAgaW5uZXJTZXNzaW9uLnVwZGF0ZVRpbWVySWQoQ2FsbFRpbWVyRXZlbnRUeXBlLklOVklURUUsIGludml0ZWVUaW1lcklkKTtcblxuICAgICAgaWYgKCF0aGlzLl9tYWluU2Vzc2lvbikge1xuICAgICAgICAvLyDnlJ/miJDkuLsgc2Vzc2lvblxuICAgICAgICB0aGlzLl9tYWluU2Vzc2lvbiA9IGlubmVyU2Vzc2lvbjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIOeUn+aIkOWJryBzZXNzaW9uc1xuICAgICAgICB0aGlzLl9ob2xkU2Vzc2lvbnMucHVzaChpbm5lclNlc3Npb24pO1xuICAgICAgICAvLyDmm7TmlrDkuLsgc2Vzc2lvbiDnirbmgIHkuLogSE9MRFxuICAgICAgICB0aGlzLl9tYWluU2Vzc2lvbi51cGRhdGVTZXNzaW9uU3RhdGUoUkNDYWxsUGx1c0NhbGxTdGF0ZS5CVVNZTElORV9XQUlUKTtcbiAgICAgIH1cblxuICAgICAgLy8g5oqb5Ye65bex5pa56KKr6YKA6K+3XG4gICAgICBjb25zdCBjYWxsUGx1c1Nlc3Npb24gPSBuZXcgUkNDYWxsUGx1c1Nlc3Npb24oaW5uZXJTZXNzaW9uLCB0aGlzLCB0aGlzLl9sb2dnZXIpO1xuICAgICAgdGhpcy5fcmVwb3J0QXBwRXZlbnRNb2R1bGUub25SZWNlaXZlZENhbGwoY2FsbFBsdXNTZXNzaW9uLCB0cmFjZUlkKTtcblxuICAgICAgY29uc3QgaW52aXRlU291cmNlID0gaXNEaXJlY3RseSA/IFJDQ2FsbFBsdXNJbnZpdGVTb3VyY2UuUFVCX0lOVklURV9DQUxMIDogUkNDYWxsUGx1c0ludml0ZVNvdXJjZS5QVUxMX0tWX0lOVklURV9DQUxMO1xuICAgICAgdGhpcy5lbWl0KFJDQ2FsbEVuZ2luZS5fX0lOTkVSX0lOVklURV9fLCBjYWxsUGx1c1Nlc3Npb24sIGludml0ZVNvdXJjZSk7XG5cbiAgICAgIGNvbnN0IG90aGVyc1N0YXRlOiBJU2Vzc2lvblVzZXJbXSA9IGNhbGxTZXNzaW9uVXNlcnMubWFwKCh7XG4gICAgICAgIHVzZXJJZCwgc2Vzc2lvblN0YXR1cywgc3lzU3RhdHVzLCB0YXJnZXRUeXBlLCB0YXJnZXRJZCwgc3RhdHVzVGltZSxcbiAgICAgIH0pID0+ICh7XG4gICAgICAgIHVzZXJJZCxcbiAgICAgICAgdXNlclN0YXRlOiBzZXNzaW9uU3RhdHVzLFxuICAgICAgICBzeXN0ZW1TdGF0ZTogc3lzU3RhdHVzLFxuICAgICAgICB0YXJnZXRUeXBlLFxuICAgICAgICB0YXJnZXRJZCxcbiAgICAgICAgc3RhdGVUaW1lOiBzdGF0dXNUaW1lLFxuICAgICAgICBjYW1lcmFFbmFibGU6IGZhbHNlLFxuICAgICAgICBtaWNyb3Bob25lRW5hYmxlOiBmYWxzZSxcbiAgICAgIH0pKTtcbiAgICAgIC8vIOaKm+WHuuS6uuWRmOeKtuaAgeWPmOabtFxuICAgICAgdGhpcy51cGRhdGVVc2Vyc1N0YXRlKGNhbGxJZCwgb3RoZXJzU3RhdGUsIHRyYWNlSWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmVtaXQoQ2FsbEhvb2tzVHlwZS5vblB1Ykludml0ZUNhbGxNaXNzLCBPYmplY3QuYXNzaWduKGRhdGEsIHtcbiAgICAgICAgZXh0cmE6IEpTT04uc3RyaW5naWZ5KGRhdGEpLFxuICAgICAgICByZWFzb246IFB1Ykludml0ZUNhbGxNaXNzUmVhc29uLk5PVF9JTlZJVEVFLFxuICAgICAgICByZWZlcjogaXNEaXJlY3RseSA/IFB1Ykludml0ZUNhbGxNaXNzUmVmZXIuUFVCX0lOVklURSA6IFB1Ykludml0ZUNhbGxNaXNzUmVmZXIuUFVMTF9LVl9JTlZJVEUsXG4gICAgICB9KSk7XG4gICAgfVxuXG4gICAgLy8g6L+H5ruk5Ye65YW25LuW55So5oi35ZKM6Ieq5bexXG4gICAgY29uc3Qgb3RoZXJJbnZpdGVkTWVtYmVyID0gY2FsbFNlc3Npb25Vc2Vycy5maWx0ZXIoKGl0ZW0pID0+IGl0ZW0udXNlcklkICE9PSBjdXJyZW50VXNlcklkICYmIGl0ZW0udXNlcklkICE9PSBpbnZpdGVVc2VySWQgJiYgaXRlbS5zZXNzaW9uU3RhdHVzID09PSBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZS5JTlZJVEVEKTtcbiAgICAvLyDmipvlh7rnvqTogYrkuK3ooqvpgoDor7fnmoTlhbbku5bkurpcbiAgICBpZiAob3RoZXJJbnZpdGVkTWVtYmVyLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIOmAmuefpSBjYWxsVHlwZSDnsbvlnovlj5jmm7RcbiAgICAgIGlmICh0aGlzLl9tYWluU2Vzc2lvbj8uZ2V0Q2FsbFR5cGUoKSA9PT0gUkNDYWxsUGx1c1R5cGUuU0lOR0xFICYmIHRoaXMuX21haW5TZXNzaW9uPy5nZXRDYWxsSWQoKSA9PT0gY2FsbElkKSB7XG4gICAgICAgIHRoaXMuX29uQ2FsbFR5cGVDaGFuZ2UodGhpcy5fbWFpblNlc3Npb24uZ2V0Q2FsbElkKCksIFJDQ2FsbFBsdXNUeXBlLk1VTFRJLCB0cmFjZUlkKTtcbiAgICAgICAgdGhpcy5fbWFpblNlc3Npb24/LnVwZGF0ZUNhbGxUeXBlKFJDQ2FsbFBsdXNUeXBlLk1VTFRJKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaW52aXRlZE1lbWJlcjogSU90aGVyTWVtSW5mb1tdID0gW107XG4gICAgICBjb25zdCB1c2Vyc1N0YXRlOiBJU2Vzc2lvblVzZXJbXSA9IFtdO1xuICAgICAgb3RoZXJJbnZpdGVkTWVtYmVyLmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICAgICAgY29uc3QgeyB1c2VySWQsIHNlc3Npb25TdGF0dXMsIHN5c1N0YXR1cyB9ID0gaXRlbTtcbiAgICAgICAgaW52aXRlZE1lbWJlci5wdXNoKHsgY2FsbElkLCB1c2VySWQsIHVzZXJTdGF0ZTogc2Vzc2lvblN0YXR1cyB9KTtcbiAgICAgICAgdXNlcnNTdGF0ZS5wdXNoKHtcbiAgICAgICAgICB1c2VySWQsXG4gICAgICAgICAgdXNlclN0YXRlOiBzZXNzaW9uU3RhdHVzLFxuICAgICAgICAgIHN5c3RlbVN0YXRlOiBzeXNTdGF0dXMsXG4gICAgICAgICAgY2FtZXJhRW5hYmxlOiBmYWxzZSxcbiAgICAgICAgICBtaWNyb3Bob25lRW5hYmxlOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMuX29uT3RoZXJNZW1iZXJJbnZpdGUoaW52aXRlZE1lbWJlcik7XG4gICAgICB0aGlzLnVwZGF0ZVVzZXJzU3RhdGUoY2FsbElkLCB1c2Vyc1N0YXRlLCB0cmFjZUlkKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog5pS25YiwIOaMguaWre+8iOWvueaWuemAmuivneWPlua2iOOAgemAmuivneaLkue7ne+8iVxuICAgKi9cbiAgcHJpdmF0ZSBfb25IYW5ndXAoZGF0YTogSUhhbmd1cEluZm9bXSwgY2FsbFNlc3Npb25hU3RhdHVzOiBSQ0NhbGxQbHVzQ2FsbFN0YXRlLCB0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICBpZiAodGhpcy5fbWFpblNlc3Npb24pIHtcbiAgICAgIC8vIOa4hemZpOWRvOWPq+i2heaXtuiuoeaXtuWZqFxuICAgICAgZGF0YS5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICAgIGlmIChpdGVtLmNhbGxJZCA9PT0gdGhpcy5fbWFpblNlc3Npb24hLmdldENhbGxJZCgpKSB7XG4gICAgICAgICAgaWYgKGl0ZW0udXNlclN0YXRlID09PSBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZS5DQU5DRUxMRUQpIHtcbiAgICAgICAgICAgIC8vIOa4hemZpOaOpeWQrOi2heaXtuiuoeaXtuWZqFxuICAgICAgICAgICAgdGhpcy5fc3RvcFRpbWVyKHRoaXMuX21haW5TZXNzaW9uIS5nZXRJbnZpdGVlVGltZXJJZCgpLCB0cmFjZUlkKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8g5ouS5o6l44CB5b+Z56KM44CB5pyq5o6l5ZCsIOa4hemZpOWRvOWPq+i2heaXtuiuoeaXtuWZqFxuICAgICAgICAgICAgdGhpcy5fc3RvcFRpbWVyKHRoaXMuX21haW5TZXNzaW9uIS5nZXRJbnZpdGVyVGltZXJJZCgpLCB0cmFjZUlkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDmlLbliLAg5o6l5ZCsXG4gICAqL1xuICBwcml2YXRlIF9vbkFjY2VwdChkYXRhOiBJQWNjZXB0SW5mb1tdLCB0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBzZXNzaW9uU3RhdGUgPSB0aGlzLl9tYWluU2Vzc2lvbj8uZ2V0U2Vzc2lvblN0YXRlKCk7XG4gICAgY29uc3QgdW5OZWVkVXBTdGF0ZSA9IFtcbiAgICAgIFJDQ2FsbFBsdXNDYWxsU3RhdGUuQ09OTkVDVElORyxcbiAgICAgIFJDQ2FsbFBsdXNDYWxsU3RhdGUuT05DQUxMLFxuICAgICAgUkNDYWxsUGx1c0NhbGxTdGF0ZS5CVVNZTElORV9XQUlULFxuICAgIF07XG4gICAgaWYgKHRoaXMuX21haW5TZXNzaW9uPy5nZXRDYWxsVHlwZSgpID09PSBSQ0NhbGxQbHVzVHlwZS5TSU5HTEVcbiAgICAgICYmIHNlc3Npb25TdGF0ZSAmJiB1bk5lZWRVcFN0YXRlLmluY2x1ZGVzKHNlc3Npb25TdGF0ZSlcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzdGFydENhbGxlcklkID0gdGhpcy5fbWFpblNlc3Npb24hLmdldFN0YXJ0Q2FsbGVySWQoKTtcbiAgICBjb25zdCBjdXJyZW50VXNlcklkID0gdGhpcy5fY29udGV4dC5nZXRDdXJyZW50SWQoKTtcblxuICAgIC8qKlxuICAgICAqIOWNleWRvOaUtuWIsOWvueaWueaOpeWQrOaXtu+8jOmcgOWujOaIkOWPkeW4g+i1hOa6kOS4gOezu+WIl+WKqOS9nFxuICAgICAqL1xuICAgIGlmICh0aGlzLl9tYWluU2Vzc2lvbj8uZ2V0Q2FsbFR5cGUoKSA9PT0gUkNDYWxsUGx1c1R5cGUuU0lOR0xFICYmIHN0YXJ0Q2FsbGVySWQgPT09IGN1cnJlbnRVc2VySWQpIHtcbiAgICAgIGNvbnN0IGFjY2VwdFVzZXJJbmZvID0gZGF0YS5maWx0ZXIoKGl0ZW0pID0+IGl0ZW0uZnJvbVVzZXJJZCAhPT0gY3VycmVudFVzZXJJZCk7XG4gICAgICBhY2NlcHRVc2VySW5mbyAmJiB0aGlzLmVtaXQoUkNDYWxsRW5naW5lLl9fSU5ORVJfU0VTU0lPTl9DT05ORUNUX18sIHRoaXMuZ2V0TG9jYWxNYWluU2Vzc2lvbigpIS5nZXRDYWxsSWQoKSwgdHJhY2VJZCk7XG4gICAgfVxuICAgIC8vIOabtOaWsOS4uyBzZXNzaW9uIOeKtuaAgVxuICAgIHRoaXMuX21haW5TZXNzaW9uPy51cGRhdGVTZXNzaW9uU3RhdGUoUkNDYWxsUGx1c0NhbGxTdGF0ZS5DT05ORUNUSU5HKTtcblxuICAgIC8vIOa4hemZpOWRvOWPq+i2heaXtuiuoeaXtuWZqFxuICAgIHRoaXMuX3N0b3BUaW1lcih0aGlzLl9tYWluU2Vzc2lvbiEuZ2V0SW52aXRlclRpbWVySWQoKSwgdHJhY2VJZCk7XG4gIH1cblxuICAvKipcbiAgICog5pS25Yiw54q25oCB5LiL5Y+RXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIF9vblN0YXR1c0Rvd24oZGF0YTogSVN0YXR1c0Rvd25Db250LCB0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICAvKipcbiAgICAgKiDpgJror53nirbmgIHkuLrov57mjqXnirbmgIHml7bvvIzkv53lrZjmnI3liqHkuIvlj5HnmoTpgJror53lvIDlp4vml7bpl7RcbiAgICAgKi9cbiAgICBjb25zdCB7XG4gICAgICBjYWxsU3RhdHVzLCBzdGFydFRpbWUsIHN5bmNUaW1lLCBjYWxsSWQsXG4gICAgfSA9IGRhdGE7XG4gICAgaWYgKGNhbGxJZCAhPT0gdGhpcy5fbWFpblNlc3Npb24/LmdldENhbGxJZCgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fY2FsbFN0YXJ0TWFwW2NhbGxJZF0gPSB0aGlzLl9jYWxsU3RhcnRNYXBbY2FsbElkXSB8fCB7fTtcblxuICAgIC8qKlxuICAgICAqIOS4iuaKpemAmuivneW8gOWni+iuoeaXtuS6i+S7tlxuICAgICAqIOadoeS7tu+8mumAmuivneeKtuaAgeS4uiBPTkNBTEwg5LiU5pyq5LiK5oql6L+H6YCa6K+d5byA5aeL6K6h5pe25LqL5Lu2XG4gICAgICovXG4gICAgaWYgKCF0aGlzLl9jYWxsU3RhcnRNYXBbY2FsbElkXS5pc1JlY2VpdmVDYWxsU3RhcnRUaW1lXG4gICAgICAmJiBjYWxsU3RhdHVzID09PSBSQ0NhbGxQbHVzQ2FsbFN0YXRlLk9OQ0FMTCkge1xuICAgICAgdGhpcy5fY2FsbFN0YXJ0TWFwW2NhbGxJZF0uaXNSZWNlaXZlQ2FsbFN0YXJ0VGltZSA9IHRydWU7XG4gICAgICBjb25zdCB7IGNvZGUsIGNsaWVudFN0YXJ0VGltZSB9ID0gYXdhaXQgdGhpcy5fdGltZUNvcnJlY3Rpb25lci5jYWxjQ2xpZW50U3RhcnRUaW1lKGNhbGxJZCwgc3RhcnRUaW1lISwgdHJhY2VJZCk7XG4gICAgICBpZiAoY29kZSA9PT0gUkNDYWxsUGx1c0lubmVyQ29kZS5TVUNDRVNTKSB7XG4gICAgICAgIHRoaXMuX3JlcG9ydEFwcEV2ZW50TW9kdWxlLm9uUmVjZWl2ZWRDYWxsU3RhcnRUaW1lKHtcbiAgICAgICAgICBjYWxsSWQsXG4gICAgICAgICAgY2FsbFN0YXJ0VGltZTogY2xpZW50U3RhcnRUaW1lISxcbiAgICAgICAgfSwgdHJhY2VJZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8g6K6h566X5piv5ZCm6YCa6K+d57uT5p2fXG4gICAgbGV0IHNlbGZFbmQgPSBmYWxzZTtcbiAgICBjb25zdCBjdXJyZW50VXNlcklkID0gdGhpcy5fY29udGV4dC5nZXRDdXJyZW50SWQoKTtcblxuICAgIC8vIOS4iuaKpeS6uuWRmOeKtuaAgeWPmOabtFxuICAgIGNvbnN0IGNoYW5nZWRVc2VycyA9IGRhdGEuY2FsbFNlc3Npb25Vc2Vycy5tYXAoKGl0ZW0pID0+IHtcbiAgICAgIGNvbnN0IGlzTGVmdCA9IFtcbiAgICAgICAgUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUuSURMRSxcbiAgICAgICAgUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUuREVDTElORUQsXG4gICAgICAgIFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLk1JU1NFRCxcbiAgICAgICAgUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUuTk9fQU5TV0VSLFxuICAgICAgICBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZS5DQU5DRUxMRUQsXG4gICAgICBdLmluY2x1ZGVzKGl0ZW0uc2Vzc2lvblN0YXR1cyk7XG4gICAgICBpZiAoaXNMZWZ0ICYmIGl0ZW0udXNlcklkID09PSBjdXJyZW50VXNlcklkKSB7XG4gICAgICAgIHNlbGZFbmQgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICB1c2VySWQ6IGl0ZW0udXNlcklkLFxuICAgICAgICB1c2VyU3RhdGU6IGl0ZW0uc2Vzc2lvblN0YXR1cyxcbiAgICAgICAgc3lzdGVtU3RhdGU6IGl0ZW0uc3lzU3RhdHVzLFxuICAgICAgICBzdGF0ZVRpbWU6IGl0ZW0uc3RhdHVzVGltZSxcbiAgICAgICAgY2FtZXJhRW5hYmxlOiBmYWxzZSxcbiAgICAgICAgbWljcm9waG9uZUVuYWJsZTogZmFsc2UsXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgY2hhbmdlZFVzZXJzLmxlbmd0aCA+IDAgJiYgdGhpcy51cGRhdGVVc2Vyc1N0YXRlKGNhbGxJZCwgY2hhbmdlZFVzZXJzLCB0cmFjZUlkKTtcblxuICAgIC8qKlxuICAgICAqIOayoeaciSBzZXNzaW9uIOS4jeWkhOeQhuS8muivneeKtuaAgeWPmOabtFxuICAgICAqL1xuICAgIGlmICghdGhpcy5fbWFpblNlc3Npb24gJiYgIXRoaXMuX2hvbGRTZXNzaW9ucy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyDorqHnrpflh7rlk43lupTliqjkvZzvvIzlubbmipvlh7rkv6Hmga9cbiAgICBjb25zdCB7XG4gICAgICBoYW5ndXBEYXRhLCBhY2NlcHREYXRhLCBvdGhlckludml0ZWREYXRhLFxuICAgIH0gPSBwYXJzZVN0YXR1c0RhdGEoZGF0YSk7XG5cbiAgICBoYW5ndXBEYXRhLmxlbmd0aCA+IDAgJiYgdGhpcy5fb25IYW5ndXAoaGFuZ3VwRGF0YSwgZGF0YS5jYWxsU3RhdHVzLCB0cmFjZUlkKTtcbiAgICBhY2NlcHREYXRhLmxlbmd0aCA+IDAgJiYgdGhpcy5fb25BY2NlcHQoYWNjZXB0RGF0YSwgdHJhY2VJZCk7XG5cbiAgICBpZiAob3RoZXJJbnZpdGVkRGF0YS5sZW5ndGggPiAwICYmIHRoaXMuX21haW5TZXNzaW9uPy5nZXRDYWxsVHlwZSgpID09PSBSQ0NhbGxQbHVzVHlwZS5NVUxUSSkge1xuICAgICAgdGhpcy5fb25PdGhlck1lbWJlckludml0ZShvdGhlckludml0ZWREYXRhKTtcbiAgICB9XG5cbiAgICAvLyDlj6rmnInlnKggY2FsbFNlc3Npb24g54q25oCB5Li6IEVuZGVkIOaXtumAmuefpSBvblNlc3Npb25DbG9zZVxuICAgIGlmIChkYXRhLmNhbGxTdGF0dXMgPT09IFJDQ2FsbFBsdXNDYWxsU3RhdGUuRU5ERUQgfHwgc2VsZkVuZCkge1xuICAgICAgdGhpcy5zZXNzaW9uQ2xvc2UoZGF0YSwgdHJhY2VJZCwgdHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOaUtuWIsOWFtuS7luerr+eahOeKtuaAgeS4i+WPkVxuICAgKi9cbiAgcHJpdmF0ZSBfb25PdGhlckNsaWVudFN0YXR1c0Rvd24oZGF0YTogSVN0YXR1c0Rvd25Db250LCB0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBjdXJyZW50VXNlcklkID0gdGhpcy5fY29udGV4dC5nZXRDdXJyZW50SWQoKTtcbiAgICBjb25zdCB7IGNhbGxJZCwgY2FsbFNlc3Npb25Vc2VycywgY2FsbFN0YXR1cyB9ID0gZGF0YTtcbiAgICBjb25zdCBjdXJyZW50VXNlciA9IGNhbGxTZXNzaW9uVXNlcnMuZmluZCgoeyB1c2VySWQgfSkgPT4gdXNlcklkID09PSBjdXJyZW50VXNlcklkKTtcblxuICAgIGlmIChjdXJyZW50VXNlciAmJiAodGhpcy5fbWFpblNlc3Npb24gfHwgdGhpcy5faG9sZFNlc3Npb25zLmxlbmd0aCkpIHtcbiAgICAgIC8vIOaYr+W3seerr+eKtuaAgeWPmOabtOS4lOWtmOWcqCBzZXNzaW9uIOWGjeWOu+mAmuefpeS6uuWRmOeKtuaAgeWPmOabtOWbnuiwg++8jOS4jeWtmOWcqCBzZXNzaW9uIOS4jemcgOimgemAmuefpVxuICAgICAgY29uc3QgeyB1c2VySWQsIHNlc3Npb25TdGF0dXMsIHN0YXR1c1RpbWUgfSA9IGN1cnJlbnRVc2VyO1xuICAgICAgaWYgKHNlc3Npb25TdGF0dXMgPT09IFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLkNPTk5FQ1RJTkcpIHtcbiAgICAgICAgY29uc3Qgc3RhdGVzID0gW1JDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLk9OQ0FMTCwgUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUuQ09OTkVDVElOR107XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIOWmguaenOiHquW3seacquaOpeWQrOS4u+mAmuivne+8jOaUtuWIsOWkmuerryBDb25uZWN0aW5nIOeKtuaAge+8jOmcgOaKm+WHuiBzZXNzaW9uQ2xvc2VcbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IGlzTWFpblNlc3Npb24gPSB0aGlzLl9tYWluU2Vzc2lvbj8uZ2V0Q2FsbElkKCkgPT09IGNhbGxJZDtcbiAgICAgICAgY29uc3QgY3VycmVudFVzZXJTYXRlID0gdGhpcy5fbWFpblNlc3Npb24/LmdldFVzZXJMaXN0KCkuZmluZCgoaXRlbSkgPT4gaXRlbS51c2VySWQgPT09IGN1cnJlbnRVc2VySWQpPy51c2VyU3RhdGU7XG4gICAgICAgIGNvbnN0IGlzQWNjZXB0TWFpblNlc3Npb24gPSBpc01haW5TZXNzaW9uICYmIGN1cnJlbnRVc2VyU2F0ZSAmJiBzdGF0ZXMuaW5jbHVkZXMoY3VycmVudFVzZXJTYXRlKTtcbiAgICAgICAgaWYgKCFpc0FjY2VwdE1haW5TZXNzaW9uKSB7XG4gICAgICAgICAgdGhpcy51cGRhdGVVc2Vyc1N0YXRlKGNhbGxJZCwgW3tcbiAgICAgICAgICAgIHVzZXJJZCxcbiAgICAgICAgICAgIHVzZXJTdGF0ZTogc2Vzc2lvblN0YXR1cyxcbiAgICAgICAgICAgIHN5c3RlbVN0YXRlOiBSQ0NhbGxQbHVzUmVhc29uLk9USEVSX0NMSUVOVF9BQ0NFUFQsXG4gICAgICAgICAgICBzdGF0ZVRpbWU6IHN0YXR1c1RpbWUsXG4gICAgICAgICAgICBjYW1lcmFFbmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgbWljcm9waG9uZUVuYWJsZTogZmFsc2UsXG4gICAgICAgICAgfV0sIHRyYWNlSWQpO1xuXG4gICAgICAgICAgdGhpcy5zZXNzaW9uQ2xvc2UoZGF0YSwgdHJhY2VJZCwgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOaUtuWIsOS6i+S7tuS4i+WPkVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBfb25FdmVudERvd24oZGF0YTogSUV2ZW50RG93bkNhbGxDb24sIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIGNvbnN0IHtcbiAgICAgIGNhbGxJZCwgZXZlbnRUaW1lLCBldmVudEFyZ3MsIGV2ZW50VHlwZSwgZnJvbVVzZXJJZCxcbiAgICB9ID0gZGF0YTtcbiAgICBpZiAoZXZlbnRUeXBlID09PSBDYWxsU2VydmVyRXZlbnRUeXBlLkNBTExfRFVSQVRJT04gJiYgY2FsbElkID09PSB0aGlzLl9tYWluU2Vzc2lvbj8uZ2V0Q2FsbElkKCkpIHtcbiAgICAgIGNvbnN0IHsgZmlyc3RGcmFtZVRpbWUgfSA9IGV2ZW50QXJncyBhcyB7IGZpcnN0RnJhbWVUaW1lOiBudW1iZXIgfTtcbiAgICAgIC8vIOiuoeeul+W8gOWni+aXtumXtFxuICAgICAgY29uc3QgeyBjb2RlLCBjbGllbnRTdGFydFRpbWU6IGNsaWVudEZpcnN0RnJhbWVUaW1lIH0gPSBhd2FpdCB0aGlzLl90aW1lQ29ycmVjdGlvbmVyLmNhbGNDbGllbnRTdGFydFRpbWUoY2FsbElkLCBmaXJzdEZyYW1lVGltZSwgdHJhY2VJZCk7XG4gICAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTF9FTkdJTkVfUkVDRUlWRV9GSVJTVF9GUkFNRV9USU1FX08sIGBjbGllbnRGaXJzdEZyYW1lVGltZTogJHtjbGllbnRGaXJzdEZyYW1lVGltZX1gLCB0cmFjZUlkKTtcbiAgICAgIGlmIChjb2RlID09PSBSQ0NhbGxQbHVzSW5uZXJDb2RlLlNVQ0NFU1MpIHtcbiAgICAgICAgdGhpcy5fcmVwb3J0QXBwRXZlbnRNb2R1bGUub25SZWNlaXZlZENhbGxGaXJzdEZyYW1lVGltZShjYWxsSWQsIGNsaWVudEZpcnN0RnJhbWVUaW1lISwgdHJhY2VJZCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOmAmuefpeWNleWRvCBkdXJhdGlvbiDlj5jmm7RcbiAgICovXG4gIHByaXZhdGUgX29uUmVjdlNpbkNhbGxEdXJhdGlvbihjYWxsSWQ6IHN0cmluZywgY2xpZW50U3RhcnRUaW1lOiBudW1iZXIsIGNsaWVudEZpcnN0RnJhbWVUaW1lOiBudW1iZXIsIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIGlmICh0aGlzLl9tYWluU2Vzc2lvbj8uZ2V0Q2FsbElkKCkgPT09IGNhbGxJZCkge1xuICAgICAgdGhpcy5fcmVwb3J0QXBwRXZlbnRNb2R1bGUub25SZWNlaXZlZENhbGxTdGFydFRpbWUoeyBjYWxsSWQsIC4uLnsgY2FsbFN0YXJ0VGltZTogY2xpZW50U3RhcnRUaW1lIH0gfSwgdHJhY2VJZCk7XG4gICAgICB0aGlzLl9yZXBvcnRBcHBFdmVudE1vZHVsZS5vblJlY2VpdmVkQ2FsbEZpcnN0RnJhbWVUaW1lKGNhbGxJZCwgY2xpZW50Rmlyc3RGcmFtZVRpbWUhLCB0cmFjZUlkKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog5pS25Yiw5aqS5L2T5Y+Y5pu055u45YWz5LqL5Lu2XG4gICAqL1xuICBwcml2YXRlIF9vblN3aXRjaE1lZGlhVHlwZShkYXRhOiBJRGlhbG9nRG93bkNhbGxDb24sIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIGNvbnN0IHtcbiAgICAgIGNhbGxJZCwgYWN0aW9uLCBleHRyYUtleVZhbCwgdHJhbnNhY3Rpb25JZCwgcHJvbW90ZXJJZCxcbiAgICB9ID0gZGF0YTtcbiAgICBjb25zdCB7IG1lZGlhVHlwZSwgcmVhc29uIH0gPSBleHRyYUtleVZhbDtcblxuICAgIGNvbnN0IGN1cnJlbnRDYWxsSWQgPSB0aGlzLl9tYWluU2Vzc2lvbj8uZ2V0Q2FsbElkKCk7XG4gICAgaWYgKGNhbGxJZCAhPT0gY3VycmVudENhbGxJZCkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExfRU5HSU5FX1JFQ0VJVkVfTUVESUFUWVBFX0NIQU5HRV9PLCBgbm90IGN1cnJlbnQgc2Vzc2lvbiBjYWxsSWQ6ICR7Y3VycmVudENhbGxJZH0sIHJlY3ZDYWxsSWQ6ICR7Y2FsbElkfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB7IHRyYW5zYWN0aW9uSWQ6IG9sZFRyYW5zSWQsIGFjdGlvbjogb2xkQWN0aW9uLCBtZWRpYVR5cGU6IE9sZE1lZGlhVHlwZSB9ID0gdGhpcy5fbWFpblNlc3Npb24/LmdldE9sZERpYWxvZ0RhdGEoKSB8fCB7fTtcbiAgICBpZiAob2xkVHJhbnNJZCA9PT0gdHJhbnNhY3Rpb25JZCAmJiBvbGRBY3Rpb24gPT09IGFjdGlvbiAmJiBPbGRNZWRpYVR5cGUgPT09IG1lZGlhVHlwZSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExfRU5HSU5FX1JFQ0VJVkVfTUVESUFUWVBFX0NIQU5HRV9PLCAnZHVwbGljYXRlIGRpYWxvZyBkYXRhJywgdHJhY2VJZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExfRU5HSU5FX1JFQ0VJVkVfTUVESUFUWVBFX0NIQU5HRV9PLCBgYWN0aW9uOiAke2FjdGlvbn0sIHJlYXNvbjogJHtyZWFzb259YCwgdHJhY2VJZCk7XG5cbiAgICB0aGlzLl9tYWluU2Vzc2lvbj8uc2V0T2xkRGlhbG9nRGF0YSh7IHRyYW5zYWN0aW9uSWQsIGFjdGlvbiwgbWVkaWFUeXBlIH0pO1xuXG4gICAgLy8g5Y2H57qn5rWB56iL5aSE55CGXG4gICAgaWYgKGFjdGlvbiA9PT0gRGlhbG9nQWN0aW9uLlJFUVVFU1QpIHtcbiAgICAgIHRoaXMuX29uUmVxdWVzdENoYW5nZU1lZGlhVHlwZSh7XG4gICAgICAgIHRyYW5zYWN0aW9uSWQ6IHRyYW5zYWN0aW9uSWQhLFxuICAgICAgICB1c2VySWQ6IHByb21vdGVySWQsXG4gICAgICAgIG1lZGlhVHlwZSxcbiAgICAgIH0sIHRyYWNlSWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgY2hhbmdlTWVkaWFUeXBlUmVzdWx0ID0gbnVsbDtcbiAgICAgIHN3aXRjaCAocmVhc29uKSB7XG4gICAgICAgIGNhc2UgRGlhbG9nQWN0aW9uLkNBTkNFTDpcbiAgICAgICAgICBjaGFuZ2VNZWRpYVR5cGVSZXN1bHQgPSBSQ0NhbGxQbHVzTWVkaWFUeXBlQ2hhbmdlUmVzdWx0LkNBTkNFTF9DSEFOR0VfTUVESUFfVFlQRTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBEaWFsb2dBY3Rpb24uQUNDRVBUOlxuICAgICAgICAgIGNoYW5nZU1lZGlhVHlwZVJlc3VsdCA9IFJDQ2FsbFBsdXNNZWRpYVR5cGVDaGFuZ2VSZXN1bHQuU0VSVkVSX0FMTE9XX01FRElBX1RZUEU7XG4gICAgICAgICAgdGhpcy5fbWFpblNlc3Npb24/LnVwZGF0ZU1lZGlhVHlwZSh0aGlzLl9tYWluU2Vzc2lvbiEuZ2V0UmVxTWVkaWFUeXBlKCkhKTtcbiAgICAgICAgICB0aGlzLl9tYWluU2Vzc2lvbj8udXBkYXRlUmVxTWVkaWFUeXBlKG51bGwpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIERpYWxvZ0FjdGlvbi5SRUZVU0U6XG4gICAgICAgICAgY2hhbmdlTWVkaWFUeXBlUmVzdWx0ID0gUkNDYWxsUGx1c01lZGlhVHlwZUNoYW5nZVJlc3VsdC5SRUZVU0VfQ0hBTkdFX01FRElBX1RZUEU7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgRGlhbG9nQWN0aW9uLlRJTUVPVVQ6XG4gICAgICAgICAgY2hhbmdlTWVkaWFUeXBlUmVzdWx0ID0gUkNDYWxsUGx1c01lZGlhVHlwZUNoYW5nZVJlc3VsdC5DSEFOR0VfTUVESUFfVFlQRV9USU1FT1VUO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBSQ0NhbGxQbHVzTWVkaWFUeXBlQ2hhbmdlUmVzdWx0W2NoYW5nZU1lZGlhVHlwZVJlc3VsdCBhcyBSQ0NhbGxQbHVzTWVkaWFUeXBlQ2hhbmdlUmVzdWx0XVxuICAgICAgJiYgdGhpcy5fcmVjZWl2ZU1lZGlhVHlwZUNoYW5nZVJlc3VsdCh7XG4gICAgICAgIHRyYW5zYWN0aW9uSWQ6IHRyYW5zYWN0aW9uSWQhLFxuICAgICAgICB1c2VySWQ6IHByb21vdGVySWQsXG4gICAgICAgIG1lZGlhVHlwZSxcbiAgICAgIH0sIGNoYW5nZU1lZGlhVHlwZVJlc3VsdCBhcyBSQ0NhbGxQbHVzTWVkaWFUeXBlQ2hhbmdlUmVzdWx0LCB0cmFjZUlkKTtcbiAgICB9XG5cbiAgICAvLyDpmY3nuqfpgJrnn6XlpITnkIZcbiAgICBpZiAoYWN0aW9uID09PSBEaWFsb2dBY3Rpb24uTk9USUNFICYmIG1lZGlhVHlwZSA9PT0gUkNDYWxsUGx1c01lZGlhVHlwZS5BVURJTyAmJiAhcmVhc29uKSB7XG4gICAgICB0aGlzLl9yZWNlaXZlTWVkaWFUeXBlQ2hhbmdlUmVzdWx0KHtcbiAgICAgICAgdHJhbnNhY3Rpb25JZDogdHJhbnNhY3Rpb25JZCEsXG4gICAgICAgIHVzZXJJZDogcHJvbW90ZXJJZCxcbiAgICAgICAgbWVkaWFUeXBlLFxuICAgICAgfSwgUkNDYWxsUGx1c01lZGlhVHlwZUNoYW5nZVJlc3VsdC5TRVJWRVJfQUxMT1dfTUVESUFfVFlQRSwgdHJhY2VJZCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOaUtuWIsCBjYWxsIGxvZyDml6Xlv5dcbiAgICovXG4gIHByaXZhdGUgX29uUmVjdkNhbGxFbmRMb2coZGF0YTogSVB1YkNhbGxMb2csIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIGNvbnN0IGNhbGxMb2cgPSB0cmFuMkNhbGxMb2coZGF0YSk7XG4gICAgdGhpcy5fcmVwb3J0QXBwRXZlbnRNb2R1bGUub25SZWNlaXZlZENhbGxSZWNvcmQoY2FsbExvZywgdHJhY2VJZCk7XG4gIH1cblxuICAvKipcbiAgICog6YCa6K+d57uT5p2fXG4gICAqL1xuICBwdWJsaWMgc2Vzc2lvbkNsb3NlKGRhdGE6IHsgY2FsbElkOiBzdHJpbmcsIHRvRGV2aWNlSWQ6IHN0cmluZ30sIHRyYWNlSWQ6IHN0cmluZywgaXNTZWxmSGFuZ3VwOiBib29sZWFuKSB7XG4gICAgY29uc3QgeyBjYWxsSWQgfSA9IGRhdGE7XG4gICAgY29uc3QgY3VycmVudFVzZXJJZCA9IHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudElkKCk7XG5cbiAgICAvLyDmraPluLjnu5PmnZ/vvIzmuIXpmaTmnKzlnLDlrZjlgqjnmoQgY2FsbElkXG4gICAgdGhpcy5fYWJub3JtYWxNb2R1bGUucmVtb3ZlQWJub3JtYWxDYWxsSWRzKGN1cnJlbnRVc2VySWQsIFtjYWxsSWRdKTtcblxuICAgIGxldCBjbG9zZWRTZXNzaW9uID0gW3RoaXMuX21haW5TZXNzaW9uLCAuLi50aGlzLl9ob2xkU2Vzc2lvbnNdLmZpbmQoKHNlc3Npb24pID0+IHNlc3Npb24gJiYgc2Vzc2lvbi5nZXRDYWxsSWQoKSA9PT0gY2FsbElkKTtcbiAgICBpZiAoIWNsb3NlZFNlc3Npb24pIHtcbiAgICAgIHRoaXMuX2xvZ2dlci53YXJuKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMX0VOR0lORV9SRUNFSVZFX0NMT1NFX1NFU1NJT05fTywgYHVuZXhwZWN0IHNlc3Npb24gY2FsbElkIC0+ICR7Y2FsbElkfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2xvZ2dlci53YXJuKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMX0VOR0lORV9SRUNFSVZFX0NMT1NFX1NFU1NJT05fTywgYGNhbGxJZDogJHtjYWxsSWR9YCwgdHJhY2VJZCk7XG5cbiAgICAvLyBzZXNzaW9uIGNsb3NlIOWQjue7k+adn+aJgOaciei2heaXtuiuoeaXtuWZqFxuICAgIGlmICh0aGlzLl9tYWluU2Vzc2lvbiAmJiB0aGlzLl9tYWluU2Vzc2lvbi5nZXRDYWxsSWQoKSA9PT0gY2FsbElkKSB7XG4gICAgICB0aGlzLl9tYWluU2Vzc2lvbi5nZXRBbGxUaW1lcklkcygpLmZvckVhY2goKHRpbWVySWQpID0+IHRoaXMuX3N0b3BUaW1lci5iaW5kKHRoaXMpKHRpbWVySWQsIHRyYWNlSWQpKTtcbiAgICAgIC8vIOe7k+adnyDkuIrmiqXnrKzkuIDluKdcbiAgICAgIGlmIChjbG9zZWRTZXNzaW9uLmdldENhbGxUeXBlKCkgPT09IFJDQ2FsbFBsdXNUeXBlLlNJTkdMRSkge1xuICAgICAgICB0aGlzLl9pc1VwRmlyc3RGcmFtZVRpbWUgPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGRlbGV0ZSB0aGlzLl9jYWxsU3RhcnRNYXBbY2FsbElkXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDmtL7lj5HpgJror53nu5PmnZ/vvIzlpITnkIbpgJror53nu5PmnZ/lkI4gUlRDIOmAgOaIv+mXtOetiemAu+i+kVxuICAgICAqL1xuICAgIHRoaXMuZW1pdChSQ0NhbGxFbmdpbmUuX19JTk5FUl9TRVNTSU9OX0NMT1NFX18sIGNhbGxJZCwgdHJhY2VJZCk7XG5cbiAgICAvKipcbiAgICAgKiDkuIrmiqXpgJror53nu5PmnZ9cbiAgICAgKiDlpJrnq6/lhbbku5bnq6/mjILmlq3pgJror53vvIzpnIDmiormnKznq6/kurrlkZjns7vnu5/nirbmgIHovazljJbkuLogUkNDYWxsUGx1c1JlYXNvbi5PVEhFUl9DTElFTlRfSEFOR1VQXG4gICAgICovXG4gICAgY29uc3QgY3J0VXNlckRhdGEgPSBjbG9zZWRTZXNzaW9uLmdldFVzZXJMaXN0KCkuZmluZCgoaXRlbSkgPT4gaXRlbS51c2VySWQgPT09IGN1cnJlbnRVc2VySWQpO1xuICAgIGxldCBoYW5ndXBSZWFzb247XG4gICAgaWYgKGlzU2VsZkhhbmd1cCAmJiBkYXRhLnRvRGV2aWNlSWQgIT09IHRoaXMuX3NpZ25hbE1vZHVsZS5nZXRTZXNzaW9uSWQoKSkge1xuICAgICAgaGFuZ3VwUmVhc29uID0gY2xvc2VkU2Vzc2lvbi5nZXRJc0xvY2FsQ2xpZW50SGFuZ3VwKCkgPyBjcnRVc2VyRGF0YSEuc3lzdGVtU3RhdGUgOiBSQ0NhbGxQbHVzUmVhc29uLk9USEVSX0NMSUVOVF9IQU5HVVA7XG4gICAgfVxuXG4gICAgdGhpcy5fcmVwb3J0QXBwRXZlbnRNb2R1bGUub25DYWxsRW5kZWQobmV3IFJDQ2FsbFBsdXNTZXNzaW9uKGNsb3NlZFNlc3Npb24sIHRoaXMsIHRoaXMuX2xvZ2dlciksIGhhbmd1cFJlYXNvbiB8fCBjcnRVc2VyRGF0YSEuc3lzdGVtU3RhdGUsIHRyYWNlSWQpO1xuXG4gICAgdGhpcy5fcmVtb3ZlU2Vzc2lvbihjYWxsSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIOagueaNriBjYWxsSWQg56e76ZmkIHNlc3Npb25cbiAgICovXG4gIHByaXZhdGUgX3JlbW92ZVNlc3Npb24oY2FsbElkOiBzdHJpbmcpIHtcbiAgICBpZiAoY2FsbElkID09PSB0aGlzLl9tYWluU2Vzc2lvbj8uZ2V0Q2FsbElkKCkpIHtcbiAgICAgIHRoaXMuX21haW5TZXNzaW9uID0gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9ob2xkU2Vzc2lvbnMuZmluZEluZGV4KChzZXNzaW9uKSA9PiBzZXNzaW9uPy5nZXRDYWxsSWQoKSA9PT0gY2FsbElkKTtcbiAgICAgIHRoaXMuX2hvbGRTZXNzaW9ucy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDkuI3lrZjlnKggbWFpblNlc3Npb24g5pe277yM5LuO5pyN5Yqh56uv6I635Y+W5pWw5o2u55Sf5oiQIG1haW5TZXNzaW9uLCDlubbpgJrnn6XkurrlkZjnirbmgIHlj5jmm7RcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgX2NyZWF0ZVNlc3Npb25CeVNlcnZlcihjYWxsSWQ6IHN0cmluZywgaXNOZWVkVXA6Ym9vbGVhbiA9IGZhbHNlLCB0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTF9FTkdJTkVfQ1JFQVRFX1NFU1NJT05fQllfU0VSVkVSX1QsIGBjYWxsSWQ6ICR7Y2FsbElkfWAsIHRyYWNlSWQpO1xuICAgIGNvbnN0IHsgY29kZSwgZGF0YSB9ID0gYXdhaXQgdGhpcy5nZXRDYWxsU2Vzc2lvbih7IGNhbGxJZCB9LCB0cmFjZUlkKTtcbiAgICBpZiAoY29kZSAhPT0gUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUykge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMX0VOR0lORV9DUkVBVEVfU0VTU0lPTl9CWV9TRVJWRVJfUiwgYGVycmNvZGU6ICR7Y29kZX1gLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTF9FTkdJTkVfQ1JFQVRFX1NFU1NJT05fQllfU0VSVkVSX1IsIGBjb2RlOiAke2NvZGV9LCBkYXRhOiAke0pTT04uc3RyaW5naWZ5KGRhdGEpfWAsIHRyYWNlSWQpO1xuXG4gICAgY29uc3Qge1xuICAgICAgY2FsbFR5cGUsIG1lZGlhVHlwZSwgY2FsbFNlc3Npb25Vc2Vycywgc3RhcnRDYWxsZXJJZCxcbiAgICB9ID0gZGF0YSE7XG5cbiAgICAvLyDnlJ/miJDkuLsgc2Vzc2lvblxuICAgIHRoaXMuX21haW5TZXNzaW9uID0gbmV3IFJDQ2FsbElubmVyU2Vzc2lvbihcbiAgICAgIGNhbGxJZCxcbiAgICAgIFJDQ2FsbFBsdXNDYWxsU3RhdGUuQ09OTkVDVElORyxcbiAgICAgIGNhbGxUeXBlLFxuICAgICAgbWVkaWFUeXBlLFxuICAgICAgc3RhcnRDYWxsZXJJZCxcbiAgICAgIHN0YXJ0Q2FsbGVySWQsXG4gICAgICBbXSxcbiAgICAgIHRoaXMuX2xvZ2dlcixcbiAgICApO1xuICAgIGlmIChpc05lZWRVcCkge1xuICAgICAgdGhpcy5fY2xlYXJNb2JpbGVPblBob25lKGNhbGxJZCwgdHJhY2VJZCk7XG4gICAgfVxuICAgIC8vIOS6uuWRmOeKtuaAgeWPmOabtOmAmuefpVxuICAgIHRoaXMudXBkYXRlVXNlcnNTdGF0ZShjYWxsSWQsIGNhbGxTZXNzaW9uVXNlcnMsIHRyYWNlSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIOWFvOWuueenu+WKqOerryBvblBob25lIOaXoOazlea2iOmZpOmXrumimFxuICAgKiBBMSDnp7vliqjnq6/lkowgQiDmraPlnKggY2FsbCDkuK3vvIzkuJQgb25QaG9uZSDnirbmgIHvvIwgQTEg5p2A6L+b56iL5ZCO77yMQiDnq6/lsZXnpLrnmoQgb25QaG9uZSDnirbmgIHml6Dms5XmtojlpLFcbiAgICogQTIg5aSa56uv5Zyo5o6l5ZCs5ZKM55u05o6l5Yqg5YWlIGNhbGwg5pe277yM5LiK5oqlIG9uUGhvbmVFbmQg54q25oCB77yM5raI6ZmkIEIg56uv5bGV56S655qEIG9uUGhvbmUg54q25oCBXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIF9jbGVhck1vYmlsZU9uUGhvbmUoY2FsbElkOiBzdHJpbmcsIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIGNvbnN0IHNlc3Npb24gPSBbdGhpcy5fbWFpblNlc3Npb24sIC4uLnRoaXMuX2hvbGRTZXNzaW9uc10uZmluZCgoaXRlbSkgPT4gaXRlbT8uZ2V0Q2FsbElkKCkgPT09IGNhbGxJZCk7XG4gICAgaWYgKHNlc3Npb24gJiYgc2Vzc2lvbi5nZXRDYWxsVHlwZSgpID09PSBSQ0NhbGxQbHVzVHlwZS5NVUxUSSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExfRU5HSU5FX1VQX09OX1BIT05FX0VORF9ULCBgY2FsbElkOiAke2NhbGxJZH1gLCB0cmFjZUlkKTtcbiAgICAgIGNvbnN0IHsgY29kZSB9ID0gYXdhaXQgdGhpcy5zeXN0ZW1TdGF0dXNVcCh7XG4gICAgICAgIGNhbGxJZCxcbiAgICAgICAgc3lzU3RhdHVzOiBSQ0NhbGxQbHVzUmVhc29uLk9OX1BIT05FX0VORCxcbiAgICAgICAgZm9yd2FyZDogRm9yd2FyZFR5cGUuQ1VSUkVOVCxcbiAgICAgIH0sIHRyYWNlSWQpO1xuXG4gICAgICBpZiAoY29kZSA9PT0gUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUykge1xuICAgICAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTF9FTkdJTkVfVVBfT05fUEhPTkVfRU5EX1IsIGBjYWxsSWQ6ICR7Y2FsbElkfWAsIHRyYWNlSWQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fbG9nZ2VyLndhcm4oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExfRU5HSU5FX1VQX09OX1BIT05FX0VORF9SLCBgY2FsbElkOiAke2NhbGxJZH0sIGVyckNvZGU6ICR7Y29kZX1gLCB0cmFjZUlkKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyDljp8gY2xpZW50IOS4reWumuS5ieeahOS6i+S7tlxuICBwcml2YXRlIF9vblVzZXJTdGF0ZUNoYW5nZShjYWxsSWQ6IHN0cmluZywgdXNlcnM6IElTZXNzaW9uVXNlcltdLCB0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBjdXJyZW50VXNlcklkID0gdGhpcy5fY29udGV4dC5nZXRDdXJyZW50SWQoKTtcbiAgICB1c2Vycy5mb3JFYWNoKCh1c2VyKSA9PiB7XG4gICAgICBjb25zdCB7IHVzZXJJZCwgdXNlclN0YXRlLCBzeXN0ZW1TdGF0ZSB9ID0gdXNlcjtcbiAgICAgIGlmICh1c2VySWQgPT09IGN1cnJlbnRVc2VySWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5fcmVwb3J0QXBwRXZlbnRNb2R1bGUub25SZW1vdGVVc2VyU3RhdGVDaGFuZ2VkKHtcbiAgICAgICAgY2FsbElkLFxuICAgICAgICB1c2VySWQsXG4gICAgICAgIHVzZXJTdGF0ZSxcbiAgICAgICAgcmVhc29uOiBzeXN0ZW1TdGF0ZSxcbiAgICAgIH0sIHRyYWNlSWQpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICog5pS25Yiw6Ieq5bexIHN5c3RlbVN0YXRlIOS4uiA5OTnvvIznm7TmjqXnprvlvIDmiL/pl7RcbiAgICAgKiDlpITnkIbooqvlj6vmjqXlkKznmoTnnqzpl7TvvIzkuLvlj6vlkIzml7bmjILmlq3nmoTmg4XlhrXvvIzkuI3mjonnprvlvIDmiL/pl7TpgJror53kuI3kvJrnu5PmnZ9cbiAgICAgKi9cbiAgICB1c2Vycy5mb3JFYWNoKCh7IHVzZXJJZCwgc3lzdGVtU3RhdGUgfSkgPT4ge1xuICAgICAgaWYgKHVzZXJJZCA9PT0gY3VycmVudFVzZXJJZCAmJiBzeXN0ZW1TdGF0ZSA9PT0gUkNDYWxsUGx1c1JlYXNvbi5BQk5PUk1BTF9FTkQpIHtcbiAgICAgICAgdGhpcy5lbWl0KFJDQ2FsbEVuZ2luZS5fX0lOTkVSX1NFU1NJT05fQ0xPU0VfXywgY2FsbElkLCB0cmFjZUlkKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX29uT3RoZXJNZW1iZXJJbnZpdGUoaW5mbzogSU90aGVyTWVtSW5mb1tdKSB7XG4gICAgaW5mby5mb3JFYWNoKChpbmZvKSA9PiB7XG4gICAgICBjb25zdCB7IHVzZXJJZCwgY2FsbElkIH0gPSBpbmZvO1xuICAgICAgY29uc3QgaW52aXRlclVzZXJJZCA9IHRoaXMuZ2V0TG9jYWxNYWluU2Vzc2lvbigpPy5nZXRJbnZpdGVyVXNlcklkKCk7XG4gICAgICB0aGlzLl9yZXBvcnRBcHBFdmVudE1vZHVsZS5vblJlbW90ZVVzZXJJbnZpdGVkKFt1c2VySWRdLCBpbnZpdGVyVXNlcklkISwgY2FsbElkKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX29uUmVxdWVzdENoYW5nZU1lZGlhVHlwZShpbmZvOiBJQ2hhbmdlTWVkaWFUeXBlSW5mbywgdHJhY2VJZDogc3RyaW5nKSB7XG4gICAgY29uc3QgeyB1c2VySWQsIHRyYW5zYWN0aW9uSWQsIG1lZGlhVHlwZSB9ID0gaW5mbztcbiAgICB0aGlzLl9yZXBvcnRBcHBFdmVudE1vZHVsZS5vblJlY2VpdmVkQ2hhbmdlTWVkaWFUeXBlUmVxdWVzdCh1c2VySWQsIHRyYW5zYWN0aW9uSWQsIG1lZGlhVHlwZSwgdHJhY2VJZCk7XG4gIH1cblxuICBwcml2YXRlIF9yZWNlaXZlTWVkaWFUeXBlQ2hhbmdlUmVzdWx0KGluZm86IElDaGFuZ2VNZWRpYVR5cGVJbmZvLCBjb2RlOiBSQ0NhbGxQbHVzTWVkaWFUeXBlQ2hhbmdlUmVzdWx0LCB0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICBpZiAoY29kZSA9PT0gUkNDYWxsUGx1c01lZGlhVHlwZUNoYW5nZVJlc3VsdC5TRVJWRVJfQUxMT1dfTUVESUFfVFlQRSkge1xuICAgICAgdGhpcy5lbWl0KFJDQ2FsbEVuZ2luZS5fX0lOTkVSX0NIQU5HRV9NRURJQV9UWVBFX18sIGluZm8ubWVkaWFUeXBlLCB0cmFjZUlkKTtcbiAgICB9XG4gICAgdGhpcy5fcmVwb3J0QXBwRXZlbnRNb2R1bGUub25SZWNlaXZlZENoYW5nZU1lZGlhVHlwZVJlc3VsdCh7XG4gICAgICAuLi5pbmZvLFxuICAgICAgY29kZSxcbiAgICB9LCB0cmFjZUlkKTtcbiAgfVxuXG4gIHByaXZhdGUgX29uQ2FsbFR5cGVDaGFuZ2UoY2FsbElkOiBzdHJpbmcsIGNhbGxUeXBlOiBSQ0NhbGxQbHVzVHlwZSwgdHJhY2VJZDogc3RyaW5nKSB7XG4gICAgdGhpcy5fcmVwb3J0QXBwRXZlbnRNb2R1bGUub25DYWxsVHlwZUNoYW5nZWQoY2FsbFR5cGUsIGNhbGxJZCwgdHJhY2VJZCk7XG4gIH1cbn1cbiIsImV4cG9ydCBlbnVtIFJUQ1Jlc291cmNlVGFnIHtcbiAgLyoqXG4gICAqIOaZrumAmumfs+inhumikea1gVxuICAgKi9cbiAgTk9STUFMID0gJ1JvbmdDbG91ZFJUQycsXG4gIC8qKlxuICAgKiDlsY/luZXliIbkuqvmtYFcbiAgICovXG4gIFNDUkVFTiA9ICdTY3JlZW5TaGFyZSdcbn1cbiIsImltcG9ydCB7XG4gIFBsdWdpbkNvbnRleHQsIElSdW50aW1lLCBSVENNb2RlLCBCYXNpY0xvZ2dlciwgRXZlbnRFbWl0dGVyLCBpc0Jvb2xlYW4sXG59IGZyb20gJ0Byb25nY2xvdWQvZW5naW5lJztcbmltcG9ydCB7XG4gIFJDUlRDUm9vbSxcbiAgUkNSVENDbGllbnQsXG4gIFJDUlRDQ29kZSxcbiAgUkNMb2NhbFRyYWNrLFxuICBSQ1JlbW90ZVRyYWNrLFxuICBSQ0xvY2FsQXVkaW9UcmFjayxcbiAgSVN1YnNjcmliZUF0dHIsXG4gIFJDUmVtb3RlVmlkZW9UcmFjayxcbiAgUkNSZW1vdGVBdWRpb1RyYWNrLFxuICBSQ0tpY2tSZWFzb24sXG4gIFJDVHJhY2ssXG4gIFJDTG9jYWxWaWRlb1RyYWNrLFxuICBJUHVibGlzaEF0dHJzLFxuICBJUkNSVENTdGF0ZVJlcG9ydCxcbiAgaGVscGVyLFxufSBmcm9tICdAcm9uZ2Nsb3VkL3BsdWdpbi1ydGMnO1xuaW1wb3J0IHtcbiAgSUF1ZGlvQ29uZmlnLFxuICBJQ2FsbFBsdXNJbml0T3B0cyxcbiAgSVN0YXR1c1JlcG9ydExpc3RlbmVyLFxuICBJVmlkZW9Db25maWcsXG4gIFJDQ2FsbFBsdXNDb2RlLFxuICBSQ0NhbGxQbHVzRnJhbWVSYXRlLFxuICBSQ0NhbGxQbHVzTWVkaWFUeXBlLFxuICBSQ0NhbGxQbHVzUGFja2V0TG9zc1N0YXRzLFxuICBSQ0NhbGxQbHVzUmVzb2x1dGlvbixcbn0gZnJvbSAnLi4vYXBpL2ludGVyZmFjZSc7XG5pbXBvcnQgeyBSVENSZXNvdXJjZVRhZyB9IGZyb20gJy4uL2VudW1zL1JUQ1Jlc291cmNlVGFnJztcbmltcG9ydCB7IHJldHJ5QXN5bmNGbiB9IGZyb20gJy4uL3V0aWxzL3JldHJ5JztcbmltcG9ydCB7IENhbGxIb29rc1R5cGUgfSBmcm9tICcuLi9pbnRlcmZhY2VzL0lDYWxsSG9va3MnO1xuaW1wb3J0IHsgUkNDYWxsUGx1c1JlYXNvbiB9IGZyb20gJy4uL2FwaS9lbnVtcy9SQ0NhbGxQbHVzUmVhc29uJztcbmltcG9ydCB7IFJDQ2FsbEtpY2tFeHRyYSB9IGZyb20gJy4uL2ludGVyZmFjZXMvSVJUQ01vZHVsZSc7XG5pbXBvcnQgeyBSQ0NhbGxQbHVzTG9nZ2VyVGFnIH0gZnJvbSAnLi4vYXBpL2VudW1zL1JDQ2FsbFBsdXNMb2dnZXJUYWcnO1xuaW1wb3J0IHsgSU1lZGlhTXV0ZUNoYW5nZUluZm8sIElNZW1iZXJJbmZvIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9JUkNDYWxsQ2xpZW50JztcbmltcG9ydCB7IFJDQ2FsbEVuZ2luZSB9IGZyb20gJy4uL1JDQ2FsbEVuZ2luZSc7XG5pbXBvcnQgeyBSQ0NhbGxQbHVzUmVwb3J0TW9kdWxlIH0gZnJvbSAnLi9SQ0NhbGxQbHVzUmVwb3J0TW9kdWxlJztcblxuaW50ZXJmYWNlIElKb2luUlRDUm9vbVJlcyB7XG4gIGNvZGU6IFJDUlRDQ29kZTtcbiAgcm9vbT86IFJDUlRDUm9vbSB8IHVuZGVmaW5lZDtcbiAgdXNlcklkcz86IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgdHJhY2tzPzogUkNSZW1vdGVUcmFja1tdIHwgdW5kZWZpbmVkO1xufVxuXG5pbnRlcmZhY2UgSVN1YlJlcyB7XG4gIGNvZGU6IFJDUlRDQ29kZTtcbiAgZmFpbGVkTGlzdD86IChJU3Vic2NyaWJlQXR0cilbXSB8IHVuZGVmaW5lZDtcbn1cblxuaW50ZXJmYWNlIElQdWJSZXMge1xuICBjb2RlOiBSQ1JUQ0NvZGU7XG4gIGxpdmVVcmw/OiBzdHJpbmcgfCB1bmRlZmluZWRcbn1cblxuaW50ZXJmYWNlIFJDS2lja0V4dHJhIHtcbiAgW2tleTogc3RyaW5nXTogYW55O1xufVxuXG5leHBvcnQgY2xhc3MgUlRDTW9kdWxlIGV4dGVuZHMgRXZlbnRFbWl0dGVyIHtcbiAgc3RhdGljIF9fSU5ORVJfUlRDX1BST0NFU1NfRkFJTEVEX186IHN0cmluZyA9ICdpbm5lci1ydGMtcHJvY2Vzcy1mYWlsZWQnXG5cbiAgc3RhdGljIF9fSU5ORVJfUlRDX1BFRVJDT05ORUNUSU9OX0FCTk9STUFMX0NMT1NFX186IHN0cmluZyA9ICdpbm5lci1ydGMtcGVlcmNvbm5lY3Rpb24tYWJub3JtYWwtY2xvc2UnXG5cbiAgc3RhdGljIF9fSU5ORVJfT05fU0VMRl9KT0lORURfXzogc3RyaW5nID0gJ2lubmVyLW9uLXNlbGYtam9pbmVkJ1xuXG4gIHN0YXRpYyBfX0lOTkVSX09OX09USEVSX0pPSU5FRF9fOiBzdHJpbmcgPSAnaW5uZXItb24tb3RoZXItam9pbmVkJ1xuXG4gIHN0YXRpYyBfX0lOTkVSX1JFQ0VJVkVfRklSU1RfRlJBTUVfXzogc3RyaW5nID0gJ2lubmVyLXJlY2VpdmUtZmlyc3QtZnJhbWUnXG5cbiAgc3RhdGljIF9fSU5ORVJfT05fS0lDS09GRl9fOiBzdHJpbmcgPSAnaW5uZXIta2lja29mZi1mcmFtZSdcblxuICBzdGF0aWMgX19JTk5FUl9PTl9ERVZJQ0VfRU5BQkxFX0NIQU5HRV9fOiBzdHJpbmcgPSAnaW5uZXItb24tZGV2aWNlLWVuYWJsZS1jaGFuZ2UnXG5cbiAgLyoqXG4gICAqIFJDUlRDIOWunuS+i1xuICAgKi9cbiAgcHVibGljIF9ydGNDbGllbnQ6IFJDUlRDQ2xpZW50XG5cbiAgLyoqXG4gICAqIOW3seaWueeahOmfs+inhumikSB0cmFja3NcbiAgICovXG4gIHByaXZhdGUgX2xvY2FsVHJhY2tzOiBSQ0xvY2FsVHJhY2tbXSA9IFtdXG5cbiAgLyoqXG4gICAqIFJDUlRDUm9vbSDlrp7kvotcbiAgICovXG4gIHB1YmxpYyBfcm9vbTogUkNSVENSb29tIHwgbnVsbCA9IG51bGxcblxuICBwcml2YXRlIF9jYWxsSWQ6IHN0cmluZyA9ICcnXG5cbiAgcHJpdmF0ZSBfY2FsbE1lZGlhVHlwZSE6IFJDQ2FsbFBsdXNNZWRpYVR5cGVcblxuICBwcml2YXRlIF92aWRlb0NvbmZpZzogSVZpZGVvQ29uZmlnID0ge1xuICAgIHJlc29sdXRpb246IFJDQ2FsbFBsdXNSZXNvbHV0aW9uLlc2NDBfSDQ4MCxcbiAgICBmcmFtZVJhdGU6IFJDQ2FsbFBsdXNGcmFtZVJhdGUuRlBTXzE1LFxuICB9XG5cbiAgcHJpdmF0ZSBfYXVkaW9Db25maWc6IElBdWRpb0NvbmZpZyA9IHt9XG5cbiAgcHJpdmF0ZSBfaXNQdWJUaW55OiBib29sZWFuID0gZmFsc2VcblxuICAvKipcbiAgICog6KeG6aKR6YWN572u5piv5ZCm5Y+Y5pu0XG4gICAqL1xuICBwcml2YXRlIF92aWRlb0NvbmZpZ0lzQ2hhbmdlOiBib29sZWFuID0gZmFsc2VcblxuICAvKipcbiAgICog6Z+z6aKR6YWN572u5piv5ZCm5Y+Y5pu0XG4gICAqL1xuICBwcml2YXRlIF9hdWRpb0NvbmZpZ0lzQ2hhbmdlOiBib29sZWFuID0gZmFsc2VcblxuICAvKipcbiAgICog5a2Y5YKo6K6+572u55qE5Lq65ZGY5ZKM6KeG5Zu+XG4gICAqL1xuICBwcml2YXRlIF91c2VyVmlld01hcDogeyBbdXNlcklkOiBzdHJpbmddOiB7IHZpZGVvVmlldzogSFRNTFZpZGVvRWxlbWVudCwgaXNUaW55OiBib29sZWFuIH0gfSA9IHt9XG5cbiAgcHJpdmF0ZSBfY2FsbFBsdXNTdGF0dXNSZXBvcnRMaXN0ZW5lcjogSVN0YXR1c1JlcG9ydExpc3RlbmVyIHwgbnVsbCA9IG51bGxcblxuICBwcml2YXRlIF9yZW1vdGVBdWRpb0VuYWJsZTogYm9vbGVhbiA9IHRydWVcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9jb250ZXh0OiBQbHVnaW5Db250ZXh0LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX3J1bnRpbWU6IElSdW50aW1lLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2luaXRPcHRzOiBJQ2FsbFBsdXNJbml0T3B0cyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9sb2dnZXI6IEJhc2ljTG9nZ2VyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NhbGxFbmdpbmU6IFJDQ2FsbEVuZ2luZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9yZXBvcnRBcHBFdmVudE1vZHVsZTogUkNDYWxsUGx1c1JlcG9ydE1vZHVsZSxcbiAgKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLl9ydGNDbGllbnQgPSBfaW5pdE9wdHM/LnJ0Y0NsaWVudDtcbiAgICB0aGlzLl9pc1B1YlRpbnkgPSBfaW5pdE9wdHMuaXNQdWJUaW55IHx8IGZhbHNlO1xuICB9XG5cbiAgc2V0Q2FsbFBsdXNTdGF0dXNSZXBvcnRMaXN0ZW5lcihsaXN0ZW5lcjogSVN0YXR1c1JlcG9ydExpc3RlbmVyKSB7XG4gICAgdGhpcy5fY2FsbFBsdXNTdGF0dXNSZXBvcnRMaXN0ZW5lciA9IGxpc3RlbmVyO1xuICB9XG5cbiAgLyoqXG4gICAqIOWPluaRhOWDj+WktOi1hOa6kFxuICAgKiDlhoXlrZjkuK3mnInml7bvvIzov5Tlm57lhoXlrZjkuK3nmoTop4bovahcbiAgICovXG4gIHB1YmxpYyBhc3luYyBnZXRDYW1lcmFWaWRlb1RyYWNrKHRyYWNlSWQ6IHN0cmluZyk6IFByb21pc2U8e2NvZGU6IG51bWJlciwgdHJhY2s/OiBSQ0xvY2FsVHJhY2t9PiB7XG4gICAgY29uc3QgZGVmYXVsdFZpZGVvVHJhY2sgPSB0aGlzLmdldExvY2FsVmlkZW9UcmFjaygpO1xuICAgIGNvbnN0IHsgY29kZSwgdHJhY2sgfSA9IChkZWZhdWx0VmlkZW9UcmFjayAmJiAhdGhpcy5fdmlkZW9Db25maWdJc0NoYW5nZSkgPyB7IHRyYWNrOiBkZWZhdWx0VmlkZW9UcmFjaywgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyB9IDogYXdhaXQgdGhpcy5fY3JlYXRlVmlkZW9UcmFjayh0cmFjZUlkKTtcbiAgICB0aGlzLl92aWRlb0NvbmZpZ0lzQ2hhbmdlID0gZmFsc2U7XG4gICAgaWYgKGNvZGUgIT09IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MsXG4gICAgICB0cmFjayxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOWPlum6puWFi+mjjui1hOa6kFxuICAgKiDlhoXlrZjkuK3mnInml7bvvIzov5Tlm57lhoXlrZjkuK3nmoTpn7PovahcbiAgICovXG4gIHB1YmxpYyBhc3luYyBnZXRNaWNyb3Bob25lQXVkaW9UcmFjayh0cmFjZUlkOiBzdHJpbmcpOiBQcm9taXNlPHtjb2RlOiBudW1iZXIsIHRyYWNrPzogUkNMb2NhbFRyYWNrfT4ge1xuICAgIGNvbnN0IGRlZmF1bHRBdWRpb1RyYWNrID0gdGhpcy5nZXRMb2NhbEF1ZGlvVHJhY2soKTtcbiAgICBjb25zdCB7IGNvZGUsIHRyYWNrIH0gPSAoZGVmYXVsdEF1ZGlvVHJhY2sgJiYgIXRoaXMuX2F1ZGlvQ29uZmlnSXNDaGFuZ2UpID8geyB0cmFjazogZGVmYXVsdEF1ZGlvVHJhY2ssIGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MgfSA6IGF3YWl0IHRoaXMuX2NyZWF0ZUF1ZGlvVHJhY2sodHJhY2VJZCk7XG4gICAgdGhpcy5fYXVkaW9Db25maWdJc0NoYW5nZSA9IGZhbHNlO1xuICAgIGlmIChjb2RlICE9PSBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTKSB7XG4gICAgICByZXR1cm4geyBjb2RlIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MsXG4gICAgICB0cmFjayxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOagueaNrumAmuivneexu+Wei+WIm+W7uumfs+OAgeinhumikei1hOa6kFxuICAgKiBAcGFyYW0gbWVkaWFUeXBlIOmfs+mikeaIlumfs+inhumikVxuICAgKi9cbiAgcHVibGljIGFzeW5jIGNyZWF0ZUNhbGxNZWRpYVRyYWNrcyhtZWRpYVR5cGU6IFJDQ2FsbFBsdXNNZWRpYVR5cGUsIHRyYWNlSWQ6IHN0cmluZyk6IFByb21pc2U8e2NvZGU6IG51bWJlcn0+IHtcbiAgICB0aGlzLl9jYWxsTWVkaWFUeXBlID0gbWVkaWFUeXBlO1xuICAgIGNvbnN0IHsgY29kZSB9ID0gYXdhaXQgdGhpcy5nZXRNaWNyb3Bob25lQXVkaW9UcmFjayh0cmFjZUlkKTtcbiAgICBpZiAoY29kZSAhPT0gUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUykge1xuICAgICAgcmV0dXJuIHsgY29kZSB9O1xuICAgIH1cblxuICAgIGlmIChtZWRpYVR5cGUgPT09IFJDQ2FsbFBsdXNNZWRpYVR5cGUuQVVESU9fVklERU8pIHtcbiAgICAgIGNvbnN0IHsgY29kZSB9ID0gYXdhaXQgdGhpcy5nZXRDYW1lcmFWaWRlb1RyYWNrKHRyYWNlSWQpO1xuICAgICAgaWYgKGNvZGUgIT09IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MpIHtcbiAgICAgICAgcmV0dXJuIHsgY29kZSB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MgfTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRWaWRlb0NvbmZpZyh2aWRlb0NvbmZpZzogSVZpZGVvQ29uZmlnKSB7XG4gICAgdGhpcy5fdmlkZW9Db25maWdJc0NoYW5nZSA9IHRydWU7XG4gICAgdGhpcy5fdmlkZW9Db25maWcgPSB2aWRlb0NvbmZpZztcbiAgfVxuXG4gIHB1YmxpYyBzZXRBdWRpb0NvbmZpZyhhdWRpb0NvbmZpZzogSUF1ZGlvQ29uZmlnKSB7XG4gICAgdGhpcy5fYXVkaW9Db25maWdJc0NoYW5nZSA9IHRydWU7XG4gICAgdGhpcy5fYXVkaW9Db25maWcgPSBhdWRpb0NvbmZpZztcbiAgfVxuXG4gIHB1YmxpYyBkZXN0cm95QWxsVHJhY2tzKHRyYWNlSWQ6IHN0cmluZykge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9SVENfTU9EVUxFX0RFU1RST1lfQUxMX1RSQUNLU19PLCAnJywgdHJhY2VJZCk7XG4gICAgdGhpcy5fbG9jYWxUcmFja3MuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgIHRyYWNrLmRlc3Ryb3koKTtcbiAgICB9KTtcbiAgICB0aGlzLl9sb2NhbFRyYWNrcy5sZW5ndGggPSAwO1xuICB9XG5cbiAgcHVibGljIHNldEFsbFJlbW90ZUF1ZGlvRW5hYmxlKGVuYWJsZTogYm9vbGVhbiwgdHJhY2VJZDogc3RyaW5nKSB7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1JUQ19NT0RVTEVfU0VUX0FMTF9SRU1PVEVfQVVESU9fRU5BQkxFX1QsIGBlbmFibGU6ICR7ZW5hYmxlfWAsIHRyYWNlSWQpO1xuXG4gICAgaWYgKCFpc0Jvb2xlYW4oZW5hYmxlKSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9SVENfTU9EVUxFX1NFVF9BTExfUkVNT1RFX0FVRElPX0VOQUJMRV9SLCBgcGFyYW0gZXJyb3IsIGVuYWJsZTogdHlwZSBpcyBib29sZWFuLCB2YWx1ZTogJHtlbmFibGV9YCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5QQVJBTV9FUlJPUiB9O1xuICAgIH1cblxuICAgIHRoaXMuX3JlbW90ZUF1ZGlvRW5hYmxlID0gZW5hYmxlO1xuXG4gICAgaWYgKCF0aGlzLl9yb29tKSB7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTIH07XG4gICAgfVxuXG4gICAgY29uc3QgYXVkaW9UcmFja3MgPSB0aGlzLl9yb29tIS5nZXRSZW1vdGVUcmFja3MoKS5maWx0ZXIoKHRyYWNrKSA9PiB0cmFjay5pc0F1ZGlvVHJhY2soKSk7XG4gICAgYXVkaW9UcmFja3MuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgIGlmIChlbmFibGUpIHtcbiAgICAgICAgdHJhY2sudW5tdXRlKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0cmFjay5tdXRlKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9TRVRfQUxMX1JFTU9URV9BVURJT19FTkFCTEVfUiwgJ3N1Y2Nlc3MnLCB0cmFjZUlkKTtcbiAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTIH07XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZGVzdHJveVRyYWNrKHRyYWNrOiBSQ0xvY2FsVHJhY2spIHtcbiAgICB0cmFjay5kZXN0cm95KCk7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLl9sb2NhbFRyYWNrcy5maW5kSW5kZXgoKGxvY2FsVHJhY2spID0+IGxvY2FsVHJhY2suZ2V0VHJhY2tJZCgpID09PSB0cmFjay5nZXRUcmFja0lkKCkpO1xuICAgIHRoaXMuX2xvY2FsVHJhY2tzLnNwbGljZShpbmRleCwgMSk7XG4gIH1cblxuICAvKipcbiAgICogc2Vzc2lvbiDov57mjqVcbiAgICovXG4gIGFzeW5jIHNlc3Npb25Db25uZWN0ZWQoY2FsbElkOiBzdHJpbmcsIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9SVENfTU9EVUxFX1NFU1NJT05fQ09OTkVDVF9ULCBgY2FsbElkOiAke2NhbGxJZH1gLCB0cmFjZUlkKTtcbiAgICAvLyAxLiDliqDmiL/pl7RcbiAgICB0cnkge1xuICAgICAgaWYgKCF0aGlzLl9yb29tKSB7XG4gICAgICAgIGNvbnN0IHsgY29kZSwgcm9vbSB9ID0gYXdhaXQgdGhpcy5qb2luUlRDUm9vbShjYWxsSWQsIHRyYWNlSWQpO1xuICAgICAgICBpZiAoY29kZSAhPT0gUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUykge1xuICAgICAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9TRVNTSU9OX0NPTk5FQ1RfUiwgYGVyckNvZGUgLT4gJHtjb2RlfWAsIHRyYWNlSWQpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyDms6jlhowgUlRDIOebuOWFs+ebkeWQrFxuICAgICAgICB0aGlzLl9jYWxsSWQgPSBjYWxsSWQ7XG4gICAgICAgIHRoaXMuX3JlZ1JUQ0xpc3RlbmVycygpO1xuXG4gICAgICAgIHRoaXMuX3Jvb20gPSByb29tITtcbiAgICAgICAgY29uc3Qgcm9vbVVzZXJzSWQgPSB0aGlzLl9yb29tPy5nZXRSZW1vdGVVc2VySWRzKCkgfHwgW107XG4gICAgICAgIGlmIChyb29tVXNlcnNJZC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdGhpcy5fb25PdGhlck1lbUpvaW5lZChyb29tVXNlcnNJZC5tYXAoKHVzZXJJZCkgPT4gKHsgY2FsbElkLCB1c2VySWQgfSkpLCB0cmFjZUlkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1JUQ19NT0RVTEVfU0VTU0lPTl9DT05ORUNUX1IsIGBjYWxsSWQgLT4gJHtjYWxsSWR9LCBlcnIgbXNnIC0+ICR7KGVycm9yIGFzIEVycm9yKS5tZXNzYWdlfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIDIuIOWPkeW4g+a1gVxuICAgIHRyeSB7XG4gICAgICBpZiAodGhpcy5fbG9jYWxUcmFja3MubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmVtaXQoQ2FsbEhvb2tzVHlwZS5vbkJlZm9yZVB1Ymxpc2gpO1xuICAgICAgICBjb25zdCBwdWJQYXJhbXMgPSB0aGlzLl9pc1B1YlRpbnlcbiAgICAgICAgICA/IHRoaXMuX2xvY2FsVHJhY2tzLm1hcCgodHJhY2spID0+ICh0cmFjay5pc1ZpZGVvVHJhY2soKSA/IHsgdHJhY2ssIGlzUHViVGlueTogdHJ1ZSB9IDogdHJhY2spKVxuICAgICAgICAgIDogdGhpcy5fbG9jYWxUcmFja3M7XG4gICAgICAgIGNvbnN0IHsgY29kZSB9ID0gYXdhaXQgdGhpcy5wdWJsaXNoKHB1YlBhcmFtcywgdHJhY2VJZCk7XG4gICAgICAgIHRoaXMuZW1pdChDYWxsSG9va3NUeXBlLm9uUHVibGlzaFJlcywgY29kZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9sb2dnZXIud2FybihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9TRVNTSU9OX0NPTk5FQ1RfUCwgJ3Nlc3Npb25Db25uZWN0ZWQgbG9jYWwgdHJhY2tzIGlzIGVtcHR5JywgdHJhY2VJZCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9TRVNTSU9OX0NPTk5FQ1RfUiwgYHB1Ymxpc2ggRXhjZXB0aW9uIGNhbGxJZCAtPiAke2NhbGxJZH0sIGVyciBtc2cgLT4gJHsoZXJyb3IgYXMgRXJyb3IpLm1lc3NhZ2V9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1JUQ19NT0RVTEVfU0VTU0lPTl9DT05ORUNUX1IsIGBjb2RlOiAke1JDQ2FsbFBsdXNDb2RlLlNVQ0NFU1N9YCwgdHJhY2VJZCk7XG4gIH1cblxuICBhc3luYyBzZXNzaW9uQ2xvc2UoY2FsbElkOiBzdHJpbmcsIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9SVENfTU9EVUxFX1NFU1NJT05fQ0xPU0VfVCwgYGNhbGxJZDogJHtjYWxsSWR9YCwgdHJhY2VJZCk7XG5cbiAgICAvKipcbiAgICAgKiDplIDmr4HmnKznq6/otYTmupBcbiAgICAgKi9cbiAgICB0aGlzLmRlc3Ryb3lBbGxUcmFja3ModHJhY2VJZCk7XG5cbiAgICBjb25zdCBjdXJyZW50Um9vbUlkID0gdGhpcy5fcm9vbT8uZ2V0Um9vbUlkKCk7XG4gICAgaWYgKHRoaXMuX3Jvb20gJiYgY2FsbElkID09PSBjdXJyZW50Um9vbUlkKSB7XG4gICAgICAvLyDpgIDlh7rmiL/pl7RcbiAgICAgIGNvbnN0IHsgY29kZSB9ID0gYXdhaXQgdGhpcy5fcnRjQ2xpZW50LmxlYXZlUm9vbSh0aGlzLl9yb29tKTtcbiAgICAgIC8vIOazqOmUgOWGheWtmOaVsOaNrlxuICAgICAgdGhpcy5fcmVsZWFzZVN0b3JlZERhdGEoKTtcbiAgICAgIGlmIChjb2RlICE9PSBSQ1JUQ0NvZGUuU1VDQ0VTUykge1xuICAgICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1JUQ19NT0RVTEVfU0VTU0lPTl9DTE9TRV9SLCBgbGVhdmVSb29tIGZhaWxlZCwgY29kZTogJHtjb2RlfWAsIHRyYWNlSWQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9TRVNTSU9OX0NMT1NFX1IsICdsZWF2ZVJvb20gc3VjY2VzcycsIHRyYWNlSWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9sb2dnZXIud2FybihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9TRVNTSU9OX0NMT1NFX1IsICdsZWF2ZVJvb20gdGhyb3cgZXhjZXB0aW9uOiBub3QgaW4gcm9vbScsIHRyYWNlSWQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDnpoHnlKjop4bpopEgdHJhY2tcbiAgICovXG4gIGFzeW5jIGRpc2FibGVWaWRlb1RyYWNrKCk6IFByb21pc2U8eyBjb2RlOiBudW1iZXIgfCBSQ1JUQ0NvZGUsIHRyYWNrPzogUkNMb2NhbFRyYWNrfT4ge1xuICAgIGNvbnN0IHRyYWNrID0gdGhpcy5nZXRMb2NhbFZpZGVvVHJhY2soKTtcbiAgICBpZiAoIXRyYWNrKSB7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5DQU1FUkFfQ0xPU0VEIH07XG4gICAgfVxuXG4gICAgLy8g56aB55So6KeG6aKRXG4gICAgY29uc3QgY29kZSA9IGF3YWl0IHRyYWNrLm11dGUoKTtcblxuICAgIHJldHVybiB7IGNvZGUsIHRyYWNrIH07XG4gIH1cblxuICAvKipcbiAgICog5ZCv55So6KeG6aKRdHJhY2tcbiAgICogMS4g5ZCv55So5YmN5bqU55So5bGC6ZyA5YWI5Yib5bu66KeG6aKRIHRyYWNrXG4gICAqL1xuICBhc3luYyBlbmFibGVWaWRlb1RyYWNrKHRyYWNlSWQ6IHN0cmluZyk6IFByb21pc2U8eyBjb2RlOiBudW1iZXIgfCBSQ1JUQ0NvZGV9PiB7XG4gICAgLy8g6I635Y+W5pys56uv6KeG6aKRIHRyYWNrXG4gICAgY29uc3QgdHJhY2sgPSB0aGlzLmdldExvY2FsVmlkZW9UcmFjaygpO1xuICAgIGlmICghdHJhY2spIHtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLkNBTUVSQV9DTE9TRUQgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDlpoLmnpzotYTmupDmsqHooqvnpoHnlKjvvIzov5Tlm57miJDlip9cbiAgICAgKi9cbiAgICBpZiAoIXRyYWNrIS5pc093bmVyTXV0ZWQoKSkge1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIOWQr+eUqOi1hOa6kFxuICAgICAqL1xuICAgIGNvbnN0IGNvZGUgPSBhd2FpdCB0cmFjayEudW5tdXRlKCk7XG4gICAgcmV0dXJuIHsgY29kZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOmAmuivneS4reWIh+aNouinhumikeiuvuWkh1xuICAgKi9cbiAgYXN5bmMgY2hhbmdlVmlkZW9EZXZpY2UodHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7IGNvZGU6IG51bWJlciwgdHJhY2s/OiBSQ0xvY2FsVHJhY2sgfT4ge1xuICAgIC8vIOaWsOiuvuWkh+eahOi9qFxuICAgIGNvbnN0IHJlY2VudFRyYWNrczogUkNMb2NhbFRyYWNrW10gPSBbXTtcbiAgICAvLyDmlbTnkIblkI7nmoTovahcbiAgICBjb25zdCBsb2NhbFRyYWNrczogUkNMb2NhbFRyYWNrW10gPSBbXTtcblxuICAgIGNvbnN0IHsgY29kZSwgdHJhY2sgfSA9IGF3YWl0IHRoaXMuX3J0Y0NsaWVudC5jcmVhdGVDYW1lcmFWaWRlb1RyYWNrKFJUQ1Jlc291cmNlVGFnLk5PUk1BTCwgdGhpcy5fdmlkZW9Db25maWcpO1xuICAgIGlmIChjb2RlICE9PSBSQ1JUQ0NvZGUuU1VDQ0VTUykge1xuICAgICAgcmV0dXJuIHsgY29kZSB9O1xuICAgIH1cblxuICAgIGNvbnN0IHsgbWluQml0cmF0ZSwgbWF4Qml0cmF0ZSB9ID0gdGhpcy5fdmlkZW9Db25maWc7XG4gICAgKG1pbkJpdHJhdGUgfHwgbWF4Qml0cmF0ZSkgJiYgdHJhY2shLnNldEJpdHJhdGUobWF4Qml0cmF0ZSEsIG1pbkJpdHJhdGUhKTtcblxuICAgIGxldCBuZWVkRGVzdHJveVRyYWNrOiBSQ0xvY2FsVHJhY2s7XG4gICAgdGhpcy5fbG9jYWxUcmFja3MgJiYgdGhpcy5fbG9jYWxUcmFja3MuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgIGlmICh0cmFjay5pc1ZpZGVvVHJhY2soKSkge1xuICAgICAgICAvLyDotYTmupDph4rmlL5cbiAgICAgICAgdHJhY2suZGVzdHJveSgpO1xuICAgICAgICBuZWVkRGVzdHJveVRyYWNrID0gdHJhY2s7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2NhbFRyYWNrcy5wdXNoKHRyYWNrKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIOS7juacrOWcsOe8k+WtmOS4reWIoOmZpOmUgOavgeeahCB0cmFja1xuICAgIHRoaXMuX2xvY2FsVHJhY2tzID0gdGhpcy5fbG9jYWxUcmFja3MuZmlsdGVyKChpdGVtKSA9PiBuZWVkRGVzdHJveVRyYWNrICYmIChpdGVtLmdldFRyYWNrSWQoKSAhPT0gbmVlZERlc3Ryb3lUcmFjay5nZXRUcmFja0lkKCkpKTtcblxuICAgIHJlY2VudFRyYWNrcy5wdXNoKHRyYWNrISk7XG5cbiAgICAvLyDnu5nmnKzlnLDliqDkuIrmlrDkuqfnlJ/nmoTop4bpopFcbiAgICBsb2NhbFRyYWNrcy5wdXNoKHRyYWNrISk7XG5cbiAgICB0aGlzLl9sb2NhbFRyYWNrcyA9IGxvY2FsVHJhY2tzO1xuXG4gICAgLy8g6YCa55+l5LiK5bGCIHRyYWNrUmVhZHlcbiAgICB0aGlzLl9vbkxvY2FsVHJhY2tSZWFkeShyZWNlbnRUcmFja3MsIHRyYWNlSWQpO1xuXG4gICAgLy8g5bey5Yqg5YWl5oi/6Ze0XG4gICAgaWYgKHRoaXMuX3Jvb20pIHtcbiAgICAgIC8vIOWPkeW4g+a1gVxuICAgICAgY29uc3QgeyBjb2RlIH0gPSBhd2FpdCB0aGlzLl9yb29tLnB1Ymxpc2gocmVjZW50VHJhY2tzKTtcbiAgICAgIGlmIChjb2RlICE9PSBSQ1JUQ0NvZGUuU1VDQ0VTUykge1xuICAgICAgICByZXR1cm4geyBjb2RlIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUywgdHJhY2sgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDnpoHnlKjpn7PpopEgdHJhY2tcbiAgICovXG4gIGFzeW5jIGRpc2FibGVBdWRpb1RyYWNrKCk6IFByb21pc2U8eyBjb2RlOiBudW1iZXIgfCBSQ1JUQ0NvZGUsIHRyYWNrPzogUkNMb2NhbFRyYWNrfT4ge1xuICAgIGNvbnN0IHRyYWNrID0gdGhpcy5nZXRMb2NhbEF1ZGlvVHJhY2soKTtcbiAgICBpZiAoIXRyYWNrKSB7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5NSUNST1BIT05FX0NMT1NFRCB9O1xuICAgIH1cblxuICAgIC8vIOemgeeUqOmfs+mikVxuICAgIGNvbnN0IGNvZGUgPSBhd2FpdCB0cmFjay5tdXRlKCk7XG5cbiAgICByZXR1cm4geyBjb2RlLCB0cmFjayB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOWqkuS9k+exu+Wei+WNh+OAgemZjVxuICAgKi9cbiAgYXN5bmMgY2hhbmdlTWVkaWFUeXBlKG1lZGlhVHlwZTogUkNDYWxsUGx1c01lZGlhVHlwZSwgdHJhY2VJZDogc3RyaW5nKSB7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1JUQ19NT0RVTEVfQ0hBTkdFX01FRElBX1RZUEVfVCwgYG1lZGlhVHlwZTogJHttZWRpYVR5cGV9YCwgdHJhY2VJZCk7XG4gICAgLyoqXG4gICAgICog5Y2H57qnIOmfs+mikSAtPiDpn7Pop4bpopFcbiAgICAgKiAxLiDkuJrliqHlsYLpnIDopoHlhYjpgJrov4cgY3JlYXRlTG9jYWxUcmFja3Mg5Yib5bu65pys5Zyw6KeG6aKRIHRyYWNrXG4gICAgICogMi4gU0RLIOWPquWkhOeQhuWPkeW4g+inhumikSB0cmFja1xuICAgICAqL1xuICAgIGlmIChtZWRpYVR5cGUgPT09IFJDQ2FsbFBsdXNNZWRpYVR5cGUuQVVESU9fVklERU8pIHtcbiAgICAgIC8vIDEuIOiOt+WPlue8k+WtmOS4reeahOinhumikSB0cmFja1xuICAgICAgbGV0IHRyYWNrID0gdGhpcy5nZXRMb2NhbFZpZGVvVHJhY2soKTtcbiAgICAgIGlmICghdHJhY2spIHtcbiAgICAgICAgY29uc3QgeyBjb2RlLCB0cmFjazogbmV3VHJhY2sgfSA9IGF3YWl0IHRoaXMuX2NyZWF0ZVZpZGVvVHJhY2sodHJhY2VJZCk7XG4gICAgICAgIGlmIChjb2RlICE9PSBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTKSB7XG4gICAgICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9SVENfTU9EVUxFX0NIQU5HRV9NRURJQV9UWVBFX1IsIGBjcmVhdGUgdmlkZW8gdHJhY2sgZXJyQ29kZTogJHtjb2RlfWAsIHRyYWNlSWQpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0cmFjayA9IG5ld1RyYWNrO1xuICAgICAgICBjb25zdCB7IG1pbkJpdHJhdGUsIG1heEJpdHJhdGUgfSA9IHRoaXMuX3ZpZGVvQ29uZmlnO1xuICAgICAgICAobWluQml0cmF0ZSB8fCBtYXhCaXRyYXRlKSAmJiB0cmFjayEuc2V0Qml0cmF0ZShtYXhCaXRyYXRlISwgbWluQml0cmF0ZSEpO1xuICAgICAgfVxuICAgICAgLy8gMi4g5Y+R5biD5rWBXG4gICAgICBjb25zdCBwdWJQYXJhbXMgPSB0aGlzLl9pc1B1YlRpbnkgPyB7IHRyYWNrOiB0cmFjayEsIGlzUHViVGlueTogdHJ1ZSB9IDogdHJhY2shO1xuICAgICAgY29uc3QgeyBjb2RlIH0gPSBhd2FpdCB0aGlzLnB1Ymxpc2goW3B1YlBhcmFtc10sIHRyYWNlSWQpO1xuICAgICAgaWYgKGNvZGUgIT09IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MpIHtcbiAgICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9SVENfTU9EVUxFX0NIQU5HRV9NRURJQV9UWVBFX1IsIGBwdWJsaXNoIGVyckNvZGU6ICR7Y29kZX1gLCB0cmFjZUlkKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIOmZjee6pyDpn7Pop4bpopEgLT4g6Z+z6aKRXG4gICAgICovXG4gICAgaWYgKG1lZGlhVHlwZSA9PT0gUkNDYWxsUGx1c01lZGlhVHlwZS5BVURJTykge1xuICAgICAgLy8gMS4g6I635Y+W5pys5Zyw6KeG6aKRIHRyYWNrXG4gICAgICBjb25zdCB0cmFjayA9IHRoaXMuZ2V0TG9jYWxWaWRlb1RyYWNrKCk7XG5cbiAgICAgIGlmICh0cmFjaykge1xuICAgICAgICAvLyDlj5bmtojlj5HluIPop4bpopFcbiAgICAgICAgY29uc3QgeyBjb2RlIH0gPSBhd2FpdCB0aGlzLl9yb29tIS51bnB1Ymxpc2goW3RyYWNrXSk7XG4gICAgICAgIGlmIChjb2RlICE9PSBSQ1JUQ0NvZGUuU1VDQ0VTUykge1xuICAgICAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9DSEFOR0VfTUVESUFfVFlQRV9SLCBgdW5wdWJsaXNoIGVyckNvZGU6ICR7Y29kZX1gLCB0cmFjZUlkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOmHiuaUvuinhumikSB0cmFja1xuICAgICAgICB0aGlzLmRlc3Ryb3lUcmFjayh0cmFjayk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9SVENfTU9EVUxFX0NIQU5HRV9NRURJQV9UWVBFX1IsICdzdWNjZXNzJywgdHJhY2VJZCk7XG4gIH1cblxuICAvKipcbiAgICog5Yqg5YWlIFJUQyDmiL/pl7RcbiAgICovXG4gIHB1YmxpYyBhc3luYyBqb2luUlRDUm9vbShjYWxsSWQ6IHN0cmluZywgdHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7IGNvZGU6IG51bWJlciwgcm9vbT86IFJDUlRDUm9vbSwgdHJhY2tzPzogUkNSZW1vdGVUcmFja1tdIH0+IHtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9KT0lOX1JUQ19ST09NX1QsIGBjYWxsOiAke2NhbGxJZH1gLCB0cmFjZUlkKTtcbiAgICBjb25zdCB7IGNvZGUsIHJvb20sIHRyYWNrcyB9ID0gYXdhaXQgcmV0cnlBc3luY0ZuIDxJSm9pblJUQ1Jvb21SZXM+KHtcbiAgICAgIGFzeW5jRm46IHRoaXMuX3J0Y0NsaWVudC5qb2luUlRDUm9vbS5iaW5kKHRoaXMuX3J0Y0NsaWVudCksXG4gICAgICBmbkFyZ3M6IFtjYWxsSWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBmYWxzZSwgUlRDTW9kZS5DQUxMXSxcbiAgICB9KTtcbiAgICBpZiAoY29kZSAhPT0gUkNSVENDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9KT0lOX1JUQ19ST09NX1IsIGBjYWxsSWQ6ICR7Y2FsbElkfSwgZXJyQ29kZTogJHtjb2RlfWAsIHRyYWNlSWQpO1xuICAgICAgdGhpcy5fb25SVENNZXRob2RGYWlsKFJDQ2FsbFBsdXNSZWFzb24uSk9JTl9ST09NX0VSUiwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlIH07XG4gICAgfVxuXG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1JUQ19NT0RVTEVfSk9JTl9SVENfUk9PTV9SLCAnc3VjY2VzcycsIHRyYWNlSWQpO1xuICAgIHRoaXMuX3Jvb20gPSByb29tITtcbiAgICB0aGlzLl9vblNlbGZKb2luZWQoeyBjYWxsSWQsIHVzZXJJZDogdGhpcy5fY29udGV4dC5nZXRDdXJyZW50SWQoKSB9LCB0cmFjZUlkKTtcbiAgICB0cmFja3M/Lmxlbmd0aCAmJiB0aGlzLl9vblJlbW90ZVRyYWNrUHVibGlzaCh0cmFja3MpO1xuXG4gICAgdGhpcy5fY2FsbElkID0gY2FsbElkO1xuICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MsIHJvb20sIHRyYWNrcyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJUQyDorqLpmIVcbiAgICovXG4gIHB1YmxpYyBhc3luYyBzdWJzY3JpYmVUcmFja3ModHJhY2tzOiAoSVN1YnNjcmliZUF0dHIpW10sIHRyYWNlSWQ6IHN0cmluZyk6IFByb21pc2U8eyBjb2RlOiBudW1iZXIgfT4ge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9SVENfTU9EVUxFX1NVQlNDUklCRV9ULCBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBwYXJhbXM6IHRyYWNrcy5tYXAoKGl0ZW0pID0+IHtcbiAgICAgICAgY29uc3QgeyB0cmFjaywgc3ViVGlueSB9ID0gaXRlbTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0cmFja0lkOiB0cmFjay5nZXRUcmFja0lkKCksXG4gICAgICAgICAgc3ViVGlueSxcbiAgICAgICAgfTtcbiAgICAgIH0pLFxuICAgIH0pLCB0cmFjZUlkKTtcblxuICAgIGlmICghdGhpcy5fcm9vbSkge1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyB9O1xuICAgIH1cblxuICAgIGNvbnN0IHsgY29kZSB9ID0gYXdhaXQgcmV0cnlBc3luY0ZuIDxJU3ViUmVzPih7XG4gICAgICBhc3luY0ZuOiB0aGlzLl9yb29tIS5zdWJzY3JpYmUuYmluZCh0aGlzLl9yb29tKSxcbiAgICAgIGZuQXJnczogW3RyYWNrc10sXG4gICAgICBvbkVycm9yOiAoY29kZSkgPT4ge30sXG4gICAgfSk7XG4gICAgaWYgKGNvZGUgIT09IFJDUlRDQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0aGlzLl9yZXBvcnRBcHBFdmVudE1vZHVsZS5vbkZldGNoUmVtb3RlTWVkaWFFcnJvcih0cmFja3MsIGNvZGUpO1xuXG4gICAgICB0aGlzLl9vblJUQ01ldGhvZEZhaWwoUkNDYWxsUGx1c1JlYXNvbi5TVUJTQ1JJQkVfRVJSLCB0cmFjZUlkKTtcblxuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9SVENfTU9EVUxFX1NVQlNDUklCRV9SLCBgZXJyb3JDb2RlOiAke2NvZGV9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlIH07XG4gICAgfVxuXG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1JUQ19NT0RVTEVfU1VCU0NSSUJFX1IsICdzdWNjZXNzJywgdHJhY2VJZCk7XG4gICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJUQyDlj5bmtojorqLpmIVcbiAgICovXG4gIHB1YmxpYyBhc3luYyB1bnN1YnNjcmliZVRyYWNrcyh0cmFja3M6IFJDUmVtb3RlVHJhY2tbXSwgdHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7IGNvZGU6IG51bWJlciB9PiB7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1JUQ19NT0RVTEVfVU5TVUJTQ1JJQkVfVCwgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgdHJhY2tJZHM6IHRyYWNrcy5tYXAoKHRyYWNrKSA9PiB0cmFjay5nZXRUcmFja0lkKCkpLFxuICAgIH0pLCB0cmFjZUlkKTtcblxuICAgIGlmICghdGhpcy5fcm9vbSkge1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyB9O1xuICAgIH1cblxuICAgIGNvbnN0IHsgY29kZSB9ID0gYXdhaXQgdGhpcy5fcm9vbSEudW5zdWJzY3JpYmUodHJhY2tzKTtcbiAgICBpZiAoY29kZSAhPT0gUkNSVENDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9VTlNVQlNDUklCRV9SLCBgZXJyb3JDb2RlOiAke2NvZGV9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlIH07XG4gICAgfVxuXG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1JUQ19NT0RVTEVfVU5TVUJTQ1JJQkVfUiwgJ3N1Y2Nlc3MnLCB0cmFjZUlkKTtcbiAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTIH07XG4gIH1cblxuICBwcml2YXRlIF9yZWxlYXNlU3RvcmVkRGF0YSgpIHtcbiAgICB0aGlzLl9yb29tID0gbnVsbDtcbiAgICB0aGlzLl9yZW1vdGVBdWRpb0VuYWJsZSA9IHRydWU7XG4gICAgdGhpcy5fdXNlclZpZXdNYXAgPSB7fTtcbiAgfVxuXG4gIGdldFJlbW90ZVRyYWNrcygpOiB7IFt1c2VySWQ6IHN0cmluZ106IFJDUmVtb3RlVHJhY2tbXX0ge1xuICAgIGNvbnN0IHRyYWNrczogeyBbdXNlcklkOiBzdHJpbmddOiBSQ1JlbW90ZVRyYWNrW119ID0ge307XG4gICAgaWYgKCF0aGlzLl9yb29tKSB7XG4gICAgICByZXR1cm4gdHJhY2tzO1xuICAgIH1cblxuICAgIGNvbnN0IHVzZXJJZHMgPSB0aGlzLl9yb29tLmdldFJlbW90ZVVzZXJJZHMoKTtcbiAgICB1c2VySWRzLmZvckVhY2goKHVzZXJJZDogc3RyaW5nKSA9PiB7XG4gICAgICB0cmFja3NbdXNlcklkXSA9IHRoaXMuX3Jvb20hLmdldFJlbW90ZVRyYWNrc0J5VXNlcklkKHVzZXJJZCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRyYWNrcztcbiAgfVxuXG4gIGdldFJlbW90ZVRyYWNrKHVzZXJJZDogc3RyaW5nLCBtZWRpYVR5cGU6IFJDQ2FsbFBsdXNNZWRpYVR5cGUpIHtcbiAgICByZXR1cm4gdGhpcy5fcm9vbT8uZ2V0UmVtb3RlVHJhY2tzQnlVc2VySWQodXNlcklkKS5maW5kKCh0cmFjaykgPT4gKChtZWRpYVR5cGUgPT09IFJDQ2FsbFBsdXNNZWRpYVR5cGUuQVVESU8pID8gdHJhY2suaXNBdWRpb1RyYWNrKCkgOiB0cmFjay5pc1ZpZGVvVHJhY2soKSkpO1xuICB9XG5cbiAgLyoqID09PT09PeengeacieaWueazlT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuICAvKipcbiAgICogUlRDIOS6i+S7tuebkeWQrOazqOWGjFxuICAgKi9cbiAgcHJpdmF0ZSBfcmVnUlRDTGlzdGVuZXJzKCkge1xuICAgIC8vIOazqOWGjOaIv+mXtOS6i+S7tuebkeWQrFxuICAgIHRoaXMuX3Jvb20hLnJlZ2lzdGVyUm9vbUV2ZW50TGlzdGVuZXIoe1xuICAgICAgLyoqXG4gICAgICAgKiDmnKznq6/ooqvouKLlh7rmiL/pl7Tml7bop6blj5FcbiAgICAgICAqIEBkZXNjcmlwdGlvbiDooqvouKLlh7rmiL/pl7Tlj6/og73mmK/nlLHkuo7mnI3liqHnq6/otoXlh7rkuIDlrprml7bpl7TmnKrog73mlLbliLAgcnRjUGluZyDmtojmga/vvIzmiYDku6XorqTkuLrlt7Hmlrnnprvnur/jgIJcbiAgICAgICAqIOWPpuS4gOenjeWPr+iDveaYr+W3seaWuSBydGNQaW5nIOWksei0peasoeaVsOi2heWHuuS4iumZkO+8jOaVheiAjOS4u+WKqOaWree6v1xuICAgICAgICogQHBhcmFtIGJ5U2VydmVyXG4gICAgICAgKiDlvZPlgLzkuLogZmFsc2Ug5pe277yM6K+05piO5pys56uvIHJ0Y1Bpbmcg6LaF5pe2XG4gICAgICAgKiDlvZPlgLzkuLogdHJ1ZSDml7bvvIzor7TmmI7mnKznq6/mlLbliLDooqvouKLlh7rmiL/pl7TpgJrnn6VcbiAgICAgICAqL1xuICAgICAgb25LaWNrT2ZmOiAoYnlTZXJ2ZXI6IGJvb2xlYW4sIHN0YXRlPzogUkNLaWNrUmVhc29uIHwgdW5kZWZpbmVkKSA9PiB7XG4gICAgICAgIHRoaXMuX29uS2lja09mZihieVNlcnZlciwgdGhpcy5fcm9vbSEuZ2V0Um9vbUlkKCksIHN0YXRlKTtcbiAgICAgICAgdGhpcy5fcmVsZWFzZVN0b3JlZERhdGEoKTtcbiAgICAgIH0sXG4gICAgICAvLyDov5znq6/nlKjmiLfliqDlhaVcbiAgICAgIG9uVXNlckpvaW46ICh1c2VySWQ6IHN0cmluZ1tdKSA9PiB7XG4gICAgICAgIGNvbnN0IGluZm8gPSB1c2VySWQubWFwKChpZCkgPT4gKHsgY2FsbElkOiB0aGlzLl9jYWxsSWQsIHVzZXJJZDogaWQgfSkpO1xuICAgICAgICBjb25zdCB0cmFjZUlkID0gdGhpcy5fbG9nZ2VyLmNyZWF0ZVRyYWNlSWQoKTtcbiAgICAgICAgdGhpcy5fb25PdGhlck1lbUpvaW5lZChpbmZvLCB0cmFjZUlkKTtcbiAgICAgIH0sXG4gICAgICAvLyDov5znq6/nlKjmiLfnprvlvIBcbiAgICAgIG9uVXNlckxlYXZlOiAodXNlcklkczogc3RyaW5nW10pID0+IHtcbiAgICAgICAgdXNlcklkcy5mb3JFYWNoKCh1c2VySWQpID0+IHtcbiAgICAgICAgICBkZWxldGUgdGhpcy5fdXNlclZpZXdNYXBbdXNlcklkXTtcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgLy8g6L+c56uv6LWE5rqQ5Y+R5biDXG4gICAgICBvblRyYWNrUHVibGlzaDogdGhpcy5fb25SZW1vdGVUcmFja1B1Ymxpc2guYmluZCh0aGlzKSxcbiAgICAgIC8vIOi/nOerr+i1hOa6kOWPlua2iOWPkeW4g1xuICAgICAgb25UcmFja1VucHVibGlzaDogdGhpcy5fb25UcmFja1VucHVibGlzaC5iaW5kKHRoaXMpLFxuICAgICAgLy8g6L+c56uv6LWE5rqQ5YeG5aSH5bCx57uqXG4gICAgICBvblRyYWNrUmVhZHk6ICh0cmFjazogUkNSZW1vdGVUcmFjaykgPT4ge1xuICAgICAgICB0aGlzLl9vblJlbW90ZVRyYWNrUmVhZHkoW3RyYWNrXSk7XG4gICAgICB9LFxuICAgICAgLy8g5Y+R5biD6ICF56aB55So44CB5ZCv55So6KeG6aKRXG4gICAgICBvblZpZGVvTXV0ZUNoYW5nZTogKHZpZGVvVHJhY2s6IFJDUmVtb3RlVmlkZW9UcmFjaykgPT4ge1xuICAgICAgICB0aGlzLl9vblZpZGVvTXV0ZUNoYWduZSh7XG4gICAgICAgICAgZnJvbVVzZXJJZDogdmlkZW9UcmFjay5nZXRVc2VySWQoKSxcbiAgICAgICAgICBtdXRlZDogdmlkZW9UcmFjay5pc093bmVyTXV0ZWQoKSxcbiAgICAgICAgICB0cmFja0lkOiB2aWRlb1RyYWNrLmdldFRyYWNrSWQoKSxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgLy8g5Y+R5biD6ICF56aB55So44CB5ZCv55So6Z+z6aKRXG4gICAgICBvbkF1ZGlvTXV0ZUNoYW5nZTogKGF1ZGlvVHJhY2s6IFJDUmVtb3RlQXVkaW9UcmFjaykgPT4ge1xuICAgICAgICB0aGlzLl9vbkF1ZGlvTXV0ZUNoYW5nZSh7XG4gICAgICAgICAgZnJvbVVzZXJJZDogYXVkaW9UcmFjay5nZXRVc2VySWQoKSxcbiAgICAgICAgICBtdXRlZDogYXVkaW9UcmFjay5pc093bmVyTXV0ZWQoKSxcbiAgICAgICAgICB0cmFja0lkOiBhdWRpb1RyYWNrLmdldFRyYWNrSWQoKSxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgb25SVENQZWVyQ29ubmVjdGlvbkNsb3NlQnlFeGNlcHRpb246IHRoaXMuX29uUlRDUGVlckNvbm5lY3Rpb25DbG9zZUJ5RXhjZXB0aW9uLmJpbmQodGhpcyksXG4gICAgfSk7XG4gICAgLy8g5rOo5YaM6LSo6YeP5pWw5o2u5oql5ZGK55uR5ZCsXG4gICAgdGhpcy5fcm9vbSEucmVnaXN0ZXJSZXBvcnRMaXN0ZW5lcih7XG4gICAgICBvblN0YXRlUmVwb3J0OiB0aGlzLl9vblJUQ1N0YXRlUmVwb3J0LmJpbmQodGhpcyksXG4gICAgfSk7XG4gICAgLy8g5rOo5YaM6Z+z6YeP5LiK5oql5LqL5Lu2XG4gICAgdGhpcy5fcm9vbSEub25BdWRpb0xldmVsQ2hhbmdlKChhdWRpb0xldmVsUmVwb3J0TGlzdCkgPT4ge1xuICAgICAgdGhpcy5fcmVwb3J0QXBwRXZlbnRNb2R1bGUub25Vc2VyQXVkaW9MZXZlbENoYW5nZWQoYXVkaW9MZXZlbFJlcG9ydExpc3QpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfb25Mb2NhbFRyYWNrUmVhZHkodHJhY2tzOiBSQ0xvY2FsVHJhY2tbXSwgdHJhY2VJZDogc3RyaW5nKSB7XG4gICAgdGhpcy5fcmVwb3J0QXBwRXZlbnRNb2R1bGUub25Vc2VyTWVkaWFBdmFpbGFibGUodHJhY2tzLCB0cmFjZUlkKTtcbiAgfVxuXG4gIHByaXZhdGUgX29uUmVtb3RlVHJhY2tSZWFkeSh0cmFja3M6IFJDUmVtb3RlVHJhY2tbXSkge1xuICAgIHRoaXMuX3JlcG9ydEFwcEV2ZW50TW9kdWxlLm9uVXNlck1lZGlhQXZhaWxhYmxlKHRyYWNrcyk7XG4gICAgdGhpcy5lbWl0KFJUQ01vZHVsZS5fX0lOTkVSX1JFQ0VJVkVfRklSU1RfRlJBTUVfXyk7XG4gIH1cblxuICBwcml2YXRlIF9vbktpY2tPZmYoYnlTZXJ2ZXI6IGJvb2xlYW4sIHJvb21JZDogc3RyaW5nLCBzdGF0ZT86IFJDS2lja1JlYXNvbiwga2lja0V4dHJhPzogUkNDYWxsS2lja0V4dHJhKSB7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1JUQ19NT0RVTEVfUkVDRUlWRV9LSUNLX09GRl9PLCBgcm9vbklkOiAke3Jvb21JZH0sIGJ5U2VydmVyOiAke2J5U2VydmVyfSwgc3RhdGU6ICR7c3RhdGV9LCBraWNrRXh0cmE6ICR7SlNPTi5zdHJpbmdpZnkoa2lja0V4dHJhKX1gKTtcbiAgICBsZXQgc3lzdGVtU3RhdGU6IFJDQ2FsbFBsdXNSZWFzb24gPSBSQ0NhbGxQbHVzUmVhc29uLkNPTk5FQ1RJT05fRVJSO1xuICAgIGlmIChieVNlcnZlcikge1xuICAgICAgaWYgKGtpY2tFeHRyYSkge1xuICAgICAgICBzeXN0ZW1TdGF0ZSA9IGtpY2tFeHRyYS5raWNrUmVhc29uQ29kZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN3aXRjaCAoc3RhdGUpIHtcbiAgICAgICAgICBjYXNlIFJDS2lja1JlYXNvbi5TRVJWRVJfS0lDSzpcbiAgICAgICAgICAgIHN5c3RlbVN0YXRlID0gUkNDYWxsUGx1c1JlYXNvbi5LSUNLRURfQllfU0VSVkVSO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSBSQ0tpY2tSZWFzb24uT1RIRVJfS0lDSzpcbiAgICAgICAgICAgIHN5c3RlbVN0YXRlID0gUkNDYWxsUGx1c1JlYXNvbi5PVEhFUl9DTElFTlRfSk9JTkVEO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSBSQ0tpY2tSZWFzb24uSU1fRElTQ09OTkVDVEVEOlxuICAgICAgICAgICAgc3lzdGVtU3RhdGUgPSBSQ0NhbGxQbHVzUmVhc29uLkNPTk5FQ1RJT05fRVJSO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSBSQ0tpY2tSZWFzb24uSU1fTE9HT1VUOlxuICAgICAgICAgICAgc3lzdGVtU3RhdGUgPSBSQ0NhbGxQbHVzUmVhc29uLkxPR09VVDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgUkNLaWNrUmVhc29uLk9USEVSX0NMSUVOVF9JTV9DT05ORUNURUQ6XG4gICAgICAgICAgICBzeXN0ZW1TdGF0ZSA9IFJDQ2FsbFBsdXNSZWFzb24uT1RIRVJfQ0xJRU5UX0xPR0lOO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmVtaXQoUlRDTW9kdWxlLl9fSU5ORVJfT05fS0lDS09GRl9fLCBzeXN0ZW1TdGF0ZSwgcm9vbUlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSVEMgUGVlciDlvILluLjlhbPpl61cbiAgICog56e75Yqo56uv5pyq5aSE55CG5q2k5Zue6LCD77yM5a6a5LmJIHN5c1N0YXR1cyDkuLogQ09OTkVDVElPTl9FUlJcbiAgICovXG4gIHByaXZhdGUgX29uUlRDUGVlckNvbm5lY3Rpb25DbG9zZUJ5RXhjZXB0aW9uKCkge1xuICAgIGNvbnN0IHRyYWNlSWQgPSB0aGlzLl9sb2dnZXIuY3JlYXRlVHJhY2VJZCgpO1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9SVENfTU9EVUxFX1JFQ0VJVkVfUEVFUkNPTk5FQ1RJT05fRVhDRVBUX0NMT1NFX08sICcnLCB0cmFjZUlkKTtcbiAgICB0aGlzLmVtaXQoUlRDTW9kdWxlLl9fSU5ORVJfUlRDX1BFRVJDT05ORUNUSU9OX0FCTk9STUFMX0NMT1NFX18sIHRyYWNlSWQpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBfb25TZWxmSm9pbmVkKGluZm86IElNZW1iZXJJbmZvLCB0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLmVtaXQoUlRDTW9kdWxlLl9fSU5ORVJfT05fU0VMRl9KT0lORURfXywgaW5mby5jYWxsSWQsIHRyYWNlSWQpO1xuICB9XG5cbiAgcHJpdmF0ZSBfb25SZW1vdGVUcmFja1B1Ymxpc2godHJhY2tzOiBSQ1JlbW90ZVRyYWNrW10pIHtcbiAgICBjb25zdCB0cmFjZUlkID0gdGhpcy5fbG9nZ2VyLmNyZWF0ZVRyYWNlSWQoKTtcbiAgICB0aGlzLl9vbkRldmljZUVuYWJsZUNoYW5nZSh0cmFja3MsIHRyYWNlSWQpO1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9SVENfTU9EVUxFX1JFQ0VJVkVfVFJBQ0tfUFVCTElTSF9PLCBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBjYWxsSWQ6IHRoaXMuX2NhbGxJZCxcbiAgICAgIHRyYWNrSWRzOiB0cmFja3MubWFwKCh0cmFjaykgPT4gdHJhY2suZ2V0VHJhY2tJZCgpKSxcbiAgICB9KSwgdHJhY2VJZCk7XG5cbiAgICBjb25zdCBuZWVkU3ViVHJhY2tzOiBJU3Vic2NyaWJlQXR0cltdID0gW107XG4gICAgdHJhY2tzLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICBjb25zdCB1c2VySWQgPSB0cmFjay5nZXRVc2VySWQoKTtcbiAgICAgIC8qKlxuICAgICAgICog5pS25Yiw6Z+z6aKR5pe277yM55u05o6l6K6i6ZiFXG4gICAgICAgKi9cbiAgICAgIGlmICh0cmFjay5pc0F1ZGlvVHJhY2soKSkge1xuICAgICAgICBuZWVkU3ViVHJhY2tzLnB1c2goeyB0cmFjaywgc3ViVGlueTogZmFsc2UgfSk7XG4gICAgICAgIHRoaXMuX3JlcG9ydEFwcEV2ZW50TW9kdWxlLm9uUmVtb3RlTWljcm9waG9uZVN0YXRlQ2hhbmdlZCh0aGlzLl9jYWxsSWQsIHRyYWNrKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5fdXNlclZpZXdNYXBbdXNlcklkXT8udmlkZW9WaWV3KSB7XG4gICAgICAgIHRoaXMuX3JlcG9ydEFwcEV2ZW50TW9kdWxlLm9uUmVtb3RlQ2FtZXJhU3RhdGVDaGFuZ2VkKHRoaXMuX2NhbGxJZCwgdHJhY2spO1xuICAgICAgICBjb25zdCB7IGlzVGlueSB9ID0gdGhpcy5fdXNlclZpZXdNYXBbdXNlcklkXTtcbiAgICAgICAgbmVlZFN1YlRyYWNrcy5wdXNoKHsgdHJhY2ssIHN1YlRpbnk6IGlzVGlueSB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBuZWVkU3ViVHJhY2tzLmxlbmd0aCAmJiB0aGlzLnN1YnNjcmliZVRyYWNrcyhuZWVkU3ViVHJhY2tzLCB0cmFjZUlkKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgX29uVHJhY2tVbnB1Ymxpc2godHJhY2tzOiBSQ1JlbW90ZVRyYWNrW10pIHtcbiAgICBjb25zdCB0cmFjZUlkID0gdGhpcy5fbG9nZ2VyLmNyZWF0ZVRyYWNlSWQoKTtcbiAgICB0aGlzLl9vbkRldmljZUVuYWJsZUNoYW5nZSh0cmFja3MsIHRyYWNlSWQpO1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9SVENfTU9EVUxFX1JFQ0VJVkVfVFJBQ0tfVU5QVUJMSVNIX08sIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIGNhbGxJZDogdGhpcy5fY2FsbElkLFxuICAgICAgdHJhY2tJZHM6IHRyYWNrcy5tYXAoKHRyYWNrKSA9PiB0cmFjay5nZXRUcmFja0lkKCkpLFxuICAgIH0pLCB0cmFjZUlkKTtcblxuICAgIGF3YWl0IHRoaXMudW5zdWJzY3JpYmVUcmFja3ModHJhY2tzLCB0cmFjZUlkKTtcbiAgfVxuXG4gIHByaXZhdGUgX29uQXVkaW9NdXRlQ2hhbmdlKGluZm86IElNZWRpYU11dGVDaGFuZ2VJbmZvKSB7XG4gICAgY29uc3QgdHJhY2VJZCA9IHRoaXMuX2xvZ2dlci5jcmVhdGVUcmFjZUlkKCk7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1JUQ19NT0RVTEVfUkVDRUlWRV9UUkFDS19FTkFCTEVfQ0hBTkdFX08sIEpTT04uc3RyaW5naWZ5KHsgaW5mbyB9KSwgdHJhY2VJZCk7XG4gICAgY29uc3QgdHJhY2sgPSB0aGlzLl9yb29tIS5nZXRSZW1vdGVUcmFjayhpbmZvLnRyYWNrSWQpO1xuICAgIHRoaXMuX29uRGV2aWNlRW5hYmxlQ2hhbmdlKFt0cmFjayFdLCB0cmFjZUlkKTtcbiAgICB0aGlzLl9yZXBvcnRBcHBFdmVudE1vZHVsZS5vblJlbW90ZU1pY3JvcGhvbmVTdGF0ZUNoYW5nZWQodGhpcy5fY2FsbElkLCB0cmFjayEpO1xuICB9XG5cbiAgcHJpdmF0ZSBfb25WaWRlb011dGVDaGFnbmUoaW5mbzogSU1lZGlhTXV0ZUNoYW5nZUluZm8pIHtcbiAgICBjb25zdCB0cmFjZUlkID0gdGhpcy5fbG9nZ2VyLmNyZWF0ZVRyYWNlSWQoKTtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9SRUNFSVZFX1RSQUNLX0VOQUJMRV9DSEFOR0VfTywgSlNPTi5zdHJpbmdpZnkoeyBpbmZvIH0pLCB0cmFjZUlkKTtcbiAgICBjb25zdCB0cmFjayA9IHRoaXMuX3Jvb20hLmdldFJlbW90ZVRyYWNrKGluZm8udHJhY2tJZCk7XG4gICAgdGhpcy5fb25EZXZpY2VFbmFibGVDaGFuZ2UoW3RyYWNrIV0sIHRyYWNlSWQpO1xuICAgIHRoaXMuX3JlcG9ydEFwcEV2ZW50TW9kdWxlLm9uUmVtb3RlQ2FtZXJhU3RhdGVDaGFuZ2VkKHRoaXMuX2NhbGxJZCwgdHJhY2shKTtcbiAgfVxuXG4gIHByaXZhdGUgX29uUlRDU3RhdGVSZXBvcnQocmVwb3J0OiBJUkNSVENTdGF0ZVJlcG9ydCkge1xuICAgIGNvbnN0IHsgc2VuZGVycywgcmVjZWl2ZXJzIH0gPSByZXBvcnQ7XG4gICAgc2VuZGVycy5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICBjb25zdCB7IGtpbmQsIHBhY2tldHNMb3N0UmF0ZSwgcnR0IH0gPSBpdGVtO1xuICAgICAgaWYgKHRoaXMuX2NhbGxNZWRpYVR5cGUgPT09IFJDQ2FsbFBsdXNNZWRpYVR5cGUuQVVESU9fVklERU8gJiYga2luZCA9PT0gJ2F1ZGlvJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLl9jYWxsUGx1c1N0YXR1c1JlcG9ydExpc3RlbmVyPy5vblNlbmRQYWNrZXRMb3NzKHBhY2tldHNMb3N0UmF0ZSB8fCAwLCBydHQgfHwgMCk7XG4gICAgfSk7XG4gICAgcmVjZWl2ZXJzLmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgdHJhY2tJZCwga2luZCwgcGFja2V0c0xvc3RSYXRlLCBiaXRyYXRlLFxuICAgICAgfSA9IGl0ZW07XG4gICAgICBpZiAodGhpcy5fY2FsbE1lZGlhVHlwZSA9PT0gUkNDYWxsUGx1c01lZGlhVHlwZS5BVURJT19WSURFTyAmJiBraW5kID09PSAnYXVkaW8nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHsgdXNlcklkIH0gPSBoZWxwZXIucGFyc2VUcmFja0lkKHRyYWNrSWQpO1xuICAgICAgY29uc3QgZGF0YToge1xuICAgICAgICBbdXNlcklkOiBzdHJpbmddOiBSQ0NhbGxQbHVzUGFja2V0TG9zc1N0YXRzO1xuICAgICAgfSA9IHt9O1xuICAgICAgZGF0YVt1c2VySWRdID0ge1xuICAgICAgICBwYWNrZXRMb3N0UmF0ZTogcGFja2V0c0xvc3RSYXRlISxcbiAgICAgICAgYml0UmF0ZTogYml0cmF0ZSxcbiAgICAgIH07XG4gICAgICB0aGlzLl9jYWxsUGx1c1N0YXR1c1JlcG9ydExpc3RlbmVyPy5vblJlY2VpdmVQYWNrZXRMb3NzKGRhdGEpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gKiBSVEMg5o6l5pS25pyA57uI5aSx6LSl5ZCO6ZyA6KaB6LCD55SoIGhhbmd1cCDmjILmlq3nmoTmg4XlhrVcbiAqL1xuICBwcml2YXRlIF9vblJUQ01ldGhvZEZhaWwoc3lzdGVtU3RhdGU6IFJDQ2FsbFBsdXNSZWFzb24sIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIHRoaXMuZW1pdChSVENNb2R1bGUuX19JTk5FUl9SVENfUFJPQ0VTU19GQUlMRURfXywgc3lzdGVtU3RhdGUsIHRyYWNlSWQpO1xuICB9XG5cbiAgcHJpdmF0ZSBfb25PdGhlck1lbUpvaW5lZChpbmZvOiBJTWVtYmVySW5mb1tdLCB0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLmVtaXQoUlRDTW9kdWxlLl9fSU5ORVJfT05fT1RIRVJfSk9JTkVEX18sIGluZm8sIHRyYWNlSWQpO1xuICB9XG5cbiAgcHJpdmF0ZSBfb25EZXZpY2VFbmFibGVDaGFuZ2UodHJhY2tzOiBSQ1JlbW90ZVRyYWNrW10sIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIHRoaXMuZW1pdChSVENNb2R1bGUuX19JTk5FUl9PTl9ERVZJQ0VfRU5BQkxFX0NIQU5HRV9fLCB0cmFja3MsIHRyYWNlSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIOWIm+W7uuacrOWcsOmfs+mikSB0cmFjaywg5Yib5bu65oiQ5Yqf5ZCO5L+d5a2Y5pys5Zyw5bm25Zue6LCD6YCa55+lXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIF9jcmVhdGVBdWRpb1RyYWNrKHRyYWNlSWQ6IHN0cmluZyk6IFByb21pc2U8e2NvZGU6IG51bWJlciwgdHJhY2s/OiBSQ0xvY2FsQXVkaW9UcmFja30+IHtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9DUkVBVEVfQVVESU9fVFJBQ0tfVCwgJycsIHRyYWNlSWQpO1xuXG4gICAgaWYgKHRoaXMuX2xvY2FsVHJhY2tzPy5zb21lKChpdGVtKSA9PiBpdGVtLmlzQXVkaW9UcmFjaygpKSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1JUQ19NT0RVTEVfQ1JFQVRFX0FVRElPX1RSQUNLX1IsICdzdWNjZXNzJywgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTIH07XG4gICAgfVxuXG4gICAgY29uc3QgeyBjb2RlLCB0cmFjayB9ID0gYXdhaXQgdGhpcy5fcnRjQ2xpZW50LmNyZWF0ZU1pY3JvcGhvbmVBdWRpb1RyYWNrKFJUQ1Jlc291cmNlVGFnLk5PUk1BTCwgdGhpcy5fYXVkaW9Db25maWcpO1xuICAgIGlmIChjb2RlICE9PSBSQ1JUQ0NvZGUuU1VDQ0VTUykge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9SVENfTU9EVUxFX0NSRUFURV9BVURJT19UUkFDS19SLCBgZXJyQ29kZTogJHtjb2RlfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZSB9O1xuICAgIH1cblxuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9SVENfTU9EVUxFX0NSRUFURV9BVURJT19UUkFDS19SLCAnc3VjY2VzcycsIHRyYWNlSWQpO1xuXG4gICAgY29uc3QgeyBtaW5CaXRyYXRlLCBtYXhCaXRyYXRlIH0gPSB0aGlzLl9hdWRpb0NvbmZpZztcbiAgICAobWluQml0cmF0ZSB8fCBtYXhCaXRyYXRlKSAmJiB0cmFjayEuc2V0Qml0cmF0ZShtYXhCaXRyYXRlISwgbWluQml0cmF0ZSEpO1xuXG4gICAgLy8g5pys5qyh57yT5a2YXG4gICAgdGhpcy5fbG9jYWxUcmFja3MucHVzaCh0cmFjayEpO1xuICAgIC8vIOmAmuefpeS4iuWxglxuICAgIHRoaXMuX29uTG9jYWxUcmFja1JlYWR5KFt0cmFjayFdLCB0cmFjZUlkKTtcbiAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTLCB0cmFjayB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOWIm+W7uuacrOWcsOinhumikSB0cmFjaywg5Yib5bu65oiQ5Yqf5ZCO5L+d5a2Y5pys5Zyw5bm25Zue6LCD6YCa55+lXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIF9jcmVhdGVWaWRlb1RyYWNrKHRyYWNlSWQ6IHN0cmluZyk6IFByb21pc2U8e2NvZGU6IG51bWJlciwgdHJhY2s/OiBSQ0xvY2FsVmlkZW9UcmFja30+IHtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9DUkVBVEVfVklERU9fVFJBQ0tfVCwgJycsIHRyYWNlSWQpO1xuXG4gICAgaWYgKHRoaXMuX2xvY2FsVHJhY2tzPy5zb21lKChpdGVtKSA9PiBpdGVtLmlzVmlkZW9UcmFjaygpICYmICFpdGVtLmlzRGVzdHJveWVkKCkpKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9DUkVBVEVfVklERU9fVFJBQ0tfUiwgJ3N1Y2Nlc3MnLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MgfTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGNvZGUsIHRyYWNrIH0gPSBhd2FpdCB0aGlzLl9ydGNDbGllbnQuY3JlYXRlQ2FtZXJhVmlkZW9UcmFjayhSVENSZXNvdXJjZVRhZy5OT1JNQUwsIHRoaXMuX3ZpZGVvQ29uZmlnKTtcbiAgICBpZiAoY29kZSAhPT0gUkNSVENDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9DUkVBVEVfVklERU9fVFJBQ0tfUiwgYGVyckNvZGU6ICR7Y29kZX1gLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9DUkVBVEVfVklERU9fVFJBQ0tfUiwgJ3N1Y2Nlc3MnLCB0cmFjZUlkKTtcblxuICAgIGNvbnN0IHsgbWluQml0cmF0ZSwgbWF4Qml0cmF0ZSB9ID0gdGhpcy5fdmlkZW9Db25maWc7XG4gICAgKG1pbkJpdHJhdGUgfHwgbWF4Qml0cmF0ZSkgJiYgdHJhY2shLnNldEJpdHJhdGUobWF4Qml0cmF0ZSEsIG1pbkJpdHJhdGUhKTtcblxuICAgIC8vIOacrOasoee8k+WtmFxuICAgIHRoaXMuX2xvY2FsVHJhY2tzLnB1c2godHJhY2shKTtcbiAgICAvLyDpgJrnn6XkuIrlsYJcbiAgICB0aGlzLl9vbkxvY2FsVHJhY2tSZWFkeShbdHJhY2shXSwgdHJhY2VJZCk7XG4gICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUywgdHJhY2sgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDojrflvpfmnKzlnLDnvJPlrZjop4bpopEgdHJhY2tcbiAgICovXG4gIHB1YmxpYyBnZXRMb2NhbFZpZGVvVHJhY2soKTogUkNMb2NhbFRyYWNrIHwgdW5kZWZpbmVkIHtcbiAgICBsZXQgbG9jYWxWaWRlb1RyYWNrOiBSQ0xvY2FsVHJhY2sgfCB1bmRlZmluZWQ7XG4gICAgaWYgKHRoaXMuX2xvY2FsVHJhY2tzKSB7XG4gICAgICBbbG9jYWxWaWRlb1RyYWNrXSA9IHRoaXMuX2xvY2FsVHJhY2tzLmZpbHRlcigodHJhY2spID0+IHRyYWNrLmlzVmlkZW9UcmFjaygpKTtcbiAgICB9XG4gICAgcmV0dXJuIGxvY2FsVmlkZW9UcmFjaztcbiAgfVxuXG4gIC8qKlxuICAgKiDojrflvpfmnKzlnLDnvJPlrZjpn7PpopEgdHJhY2tcbiAgICovXG4gIHB1YmxpYyBnZXRMb2NhbEF1ZGlvVHJhY2soKTogUkNMb2NhbFRyYWNrIHwgdW5kZWZpbmVkIHtcbiAgICBsZXQgbG9jYWxBdWRpb1RyYWNrOiBSQ0xvY2FsVHJhY2sgfCB1bmRlZmluZWQ7XG4gICAgaWYgKHRoaXMuX2xvY2FsVHJhY2tzKSB7XG4gICAgICBbbG9jYWxBdWRpb1RyYWNrXSA9IHRoaXMuX2xvY2FsVHJhY2tzLmZpbHRlcigodHJhY2spID0+IHRyYWNrLmlzQXVkaW9UcmFjaygpKTtcbiAgICB9XG4gICAgcmV0dXJuIGxvY2FsQXVkaW9UcmFjaztcbiAgfVxuXG4gIC8qKlxuICAgKiDlj5HluIPmnKzlnLDotYTmupDnmoTpgLvovpFcbiAgICovXG4gIHB1YmxpYyBhc3luYyBwdWJsaXNoKHRyYWNrczogKFJDTG9jYWxUcmFjayB8IElQdWJsaXNoQXR0cnMpW10sIHRyYWNlSWQ6IHN0cmluZyk6IFByb21pc2U8eyBjb2RlOiBudW1iZXJ9PiB7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1JUQ19NT0RVTEVfUFVCTElTSF9ULCBgdHJhY2tzSWRzOiAke3RyYWNrcy5tYXAoKGl0ZW0pID0+ICgoaXRlbSBpbnN0YW5jZW9mIFJDTG9jYWxUcmFjaykgPyBpdGVtLmdldFRyYWNrSWQoKSA6IGl0ZW0udHJhY2suZ2V0VHJhY2tJZCgpKSl9YCwgdHJhY2VJZCk7XG5cbiAgICBjb25zdCB7IGNvZGUgfSA9IGF3YWl0IHJldHJ5QXN5bmNGbiA8SVB1YlJlcz4oe1xuICAgICAgYXN5bmNGbjogdGhpcy5fcm9vbSEucHVibGlzaC5iaW5kKHRoaXMuX3Jvb20pLFxuICAgICAgZm5BcmdzOiBbdHJhY2tzXSxcbiAgICAgIG9uRXJyb3I6IChjb2RlKSA9PiB7fSxcbiAgICB9KTtcblxuICAgIGlmIChjb2RlICE9PSBSQ1JUQ0NvZGUuU1VDQ0VTUykge1xuICAgICAgdGhpcy5fb25SVENNZXRob2RGYWlsKFJDQ2FsbFBsdXNSZWFzb24uUFVCTElTSF9FUlIsIHRyYWNlSWQpO1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9SVENfTU9EVUxFX1BVQkxJU0hfUiwgYGVyckNvZGU6ICR7Y29kZX1gLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9QVUJMSVNIX1IsIGBjb2RlOiAke1JDQ2FsbFBsdXNDb2RlLlNVQ0NFU1N9YCwgdHJhY2VJZCk7XG4gICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyB9O1xuICB9XG5cbiAgcHVibGljIHB1Ymxpc2hWaWRlb1RyYWNrKCkge1xuICAgIGNvbnN0IGRlZmF1bHRWaWRlb1RyYWNrID0gdGhpcy5nZXRMb2NhbFZpZGVvVHJhY2soKTtcbiAgICBjb25zdCBwdWJQYXJhbXMgPSB0aGlzLl9pc1B1YlRpbnkgPyB7IHRyYWNrOiBkZWZhdWx0VmlkZW9UcmFjayEsIGlzUHViVGlueTogdHJ1ZSB9IDogZGVmYXVsdFZpZGVvVHJhY2shO1xuICAgIHJldHVybiB0aGlzLl9yb29tIS5wdWJsaXNoKFtwdWJQYXJhbXNdKTtcbiAgfVxuXG4gIHNldFZpZGVvVmlldyhsaXN0OiB7dXNlcklkOiBzdHJpbmcsIHZpZGVvRWxlbWVudDogSFRNTFZpZGVvRWxlbWVudCwgaXNUaW55PzogYm9vbGVhbn1bXSwgdHJhY2VJZDogc3RyaW5nKSB7XG4gICAgY29uc3QgbmVlZFN1YlRyYWNrczogSVN1YnNjcmliZUF0dHJbXSA9IFtdO1xuICAgIGxpc3QuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgY29uc3QgeyB1c2VySWQsIHZpZGVvRWxlbWVudCwgaXNUaW55ID0gZmFsc2UgfSA9IGl0ZW07XG4gICAgICB0aGlzLl91c2VyVmlld01hcFt1c2VySWRdID0ge1xuICAgICAgICB2aWRlb1ZpZXc6IHZpZGVvRWxlbWVudCxcbiAgICAgICAgaXNUaW55LFxuICAgICAgfTtcbiAgICAgIC8qKlxuICAgICAgICog6K6+572u5pys56uv6KeG5Zu+5pe277yM5Y+q5a2Y5YKo5pWw5o2u77yM5peg6ZyA6K6i6ZiFXG4gICAgICAgKi9cbiAgICAgIGlmICh1c2VySWQgPT09IHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudElkKCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgLyoqXG4gICAgICAgKiDorr7nva7ov5znq6/op4blm77ml7bvvIzlpoLmnpzlt7Lnu4/liqDlhaXmiL/pl7TvvIzliJnojrflj5bov5znq6/otYTmupDnm7TmjqXorqLpmIVcbiAgICAgICAqL1xuICAgICAgaWYgKCF0aGlzLl9yb29tKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlbW90ZVRyYWNrcyA9IHRoaXMuZ2V0UmVtb3RlVHJhY2tzKCk7XG4gICAgICBjb25zdCBzdWJQYXJhbXMgPSAocmVtb3RlVHJhY2tzIVt1c2VySWRdIHx8IFtdKS5tYXAoKHRyYWNrKSA9PiAoe1xuICAgICAgICB0cmFjayxcbiAgICAgICAgc3ViVGlueTogaXNUaW55LFxuICAgICAgfSkpLmZpbHRlcigoeyB0cmFjayB9KSA9PiAhdHJhY2suaXNTdWJzY3JpYmVkKCkpO1xuICAgICAgbmVlZFN1YlRyYWNrcy5wdXNoKC4uLnN1YlBhcmFtcyk7XG4gICAgfSk7XG5cbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9TRVRfVklERU9fVklFV19PLCBKU09OLnN0cmluZ2lmeShcbiAgICAgIHtcbiAgICAgICAgdXNlclZpZXdNYXA6IHRoaXMuX3VzZXJWaWV3TWFwLFxuICAgICAgICBuZWVkU3ViVHJhY2tJZHM6IG5lZWRTdWJUcmFja3MubWFwKCh7IHRyYWNrIH0pID0+IHRyYWNrLmdldFRyYWNrSWQoKSksXG4gICAgICB9LFxuICAgICksIHRyYWNlSWQpO1xuXG4gICAgbmVlZFN1YlRyYWNrcy5sZW5ndGggJiYgdGhpcy5zdWJzY3JpYmVUcmFja3MobmVlZFN1YlRyYWNrcywgdHJhY2VJZCk7XG4gIH1cblxuICAvKipcbiAgICog5Yig6Zmk6KeG5Zu+5pe277yM5Y+W5raI6K6i6ZiF6LWE5rqQXG4gICAqL1xuICByZW1vdmVWaWRlb1ZpZXcodXNlcklkczogc3RyaW5nW10sIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIGNvbnN0IHVuc3ViVHJhY2tzOiBSQ1JlbW90ZVRyYWNrW10gPSBbXTtcbiAgICB1c2VySWRzLmZvckVhY2goKHVzZXJJZDogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCB0cmFja3MgPSB0aGlzLmdldFJlbW90ZVRyYWNrcygpW3VzZXJJZF07XG4gICAgICBpZiAodHJhY2tzICYmIHRyYWNrcy5sZW5ndGgpIHtcbiAgICAgICAgY29uc3QgdmlkZW9UcmFjayA9IHRyYWNrcy5maWx0ZXIoKHRyYWNrKSA9PiB0cmFjay5pc1ZpZGVvVHJhY2soKSk7XG4gICAgICAgIHZpZGVvVHJhY2subGVuZ3RoICYmIHVuc3ViVHJhY2tzLnB1c2godmlkZW9UcmFja1swXSk7XG4gICAgICB9XG4gICAgICBkZWxldGUgdGhpcy5fdXNlclZpZXdNYXBbdXNlcklkXTtcbiAgICB9KTtcblxuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9SVENfTU9EVUxFX1JFTU9WRV9WSURFT19WSUVXX08sIEpTT04uc3RyaW5naWZ5KFxuICAgICAge1xuICAgICAgICB1c2VyVmlld01hcDogdGhpcy5fdXNlclZpZXdNYXAsXG4gICAgICAgIHVuc3ViVHJhY2tzOiB1bnN1YlRyYWNrcy5tYXAoKHRyYWNrKSA9PiB0cmFjay5nZXRUcmFja0lkKCkpLFxuICAgICAgfSxcbiAgICApLCB0cmFjZUlkKTtcblxuICAgIGlmICh1bnN1YlRyYWNrcy5sZW5ndGgpIHtcbiAgICAgIHRoaXMudW5zdWJzY3JpYmVUcmFja3ModW5zdWJUcmFja3MsIHRyYWNlSWQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDojrflj5blrZjlgqjnmoTkurrlkZjlkowgdmlkZW8g5YWD57Sg5pWw5o2uXG4gICAqL1xuICBnZXRVc2VyVmlld01hcCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdXNlclZpZXdNYXA7XG4gIH1cblxuICAvKipcbiAgICog5pKt5pS+5aqS5L2T6LWE5rqQXG4gICAqL1xuICBhc3luYyBwbGF5TWVkaWEodXNlcklkOiBzdHJpbmcsIG1lZGlhVHlwZTogUkNDYWxsUGx1c01lZGlhVHlwZSwgdmlkZW9WaWV3OiBIVE1MVmlkZW9FbGVtZW50LCB0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9QTEFZX01FRElBX1QsIGB1c2VySWQ6ICR7dXNlcklkfSwgbWVkaWFUeXBlOiAke21lZGlhVHlwZX0sIHZpZGVvVmlldzogJHt2aWRlb1ZpZXc/Lm5vZGVOYW1lfWAsIHRyYWNlSWQpO1xuICAgIGxldCB0cmFjazogUkNUcmFjayB8IG51bGwgPSBudWxsO1xuICAgIC8qKlxuICAgICAqIOWMuuWIhuacrOerr+WSjOi/nOerr1xuICAgICAqL1xuICAgIGlmICh1c2VySWQgPT09IHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudElkKCkpIHtcbiAgICAgIHRyYWNrID0gKG1lZGlhVHlwZSA9PT0gUkNDYWxsUGx1c01lZGlhVHlwZS5BVURJTykgPyB0aGlzLmdldExvY2FsQXVkaW9UcmFjaygpISA6IHRoaXMuZ2V0TG9jYWxWaWRlb1RyYWNrKCkhO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLWRlc3RydWN0dXJpbmdcbiAgICAgIHRyYWNrID0gdGhpcy5nZXRSZW1vdGVUcmFja3MoKVt1c2VySWRdLmZpbHRlcigodHJhY2spID0+IChtZWRpYVR5cGUgPT09IFJDQ2FsbFBsdXNNZWRpYVR5cGUuQVVESU8gPyB0cmFjay5pc0F1ZGlvVHJhY2soKSA6IHRyYWNrLmlzVmlkZW9UcmFjaygpKSlbMF07XG4gICAgfVxuXG4gICAgaWYgKCF0cmFjaykge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9SVENfTU9EVUxFX1BMQVlfTUVESUFfUiwgYGVycm9yIGNvZGU6ICR7UkNDYWxsUGx1c0NvZGUuTUVESUFfUkVTT1VSQ0VfSU5WQUxJRUR9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5NRURJQV9SRVNPVVJDRV9JTlZBTElFRCB9O1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IGNvZGUgfSA9IHRyYWNrLmlzQXVkaW9UcmFjaygpID8gYXdhaXQgdHJhY2sucGxheSgpIDogYXdhaXQgdHJhY2sucGxheSh2aWRlb1ZpZXcpO1xuICAgICAgLyoqXG4gICAgICAgKiDlpITnkIbpgJror53liY3orr7nva7kuobpnZnpn7PmiYDmnInov5znq6/pn7PpopHmtYFcbiAgICAgICAqL1xuICAgICAgdHJhY2suaXNBdWRpb1RyYWNrKCkgJiYgIXRoaXMuX3JlbW90ZUF1ZGlvRW5hYmxlICYmIHRyYWNrLm11dGUoKTtcblxuICAgICAgaWYgKGNvZGUgIT09IFJDUlRDQ29kZS5TVUNDRVNTKSB7XG4gICAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfUlRDX01PRFVMRV9QTEFZX01FRElBX1IsIGBlcnJDb2RlOiAke2NvZGV9YCwgdHJhY2VJZCk7XG4gICAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9SVENfTU9EVUxFX1BMQVlfTUVESUFfUiwgJ3N1Y2Nlc3MnLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MgfTtcbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX1JUQ19NT0RVTEVfUExBWV9NRURJQV9SLCBgZXJyQ29kZTogJHtSQ0NhbGxQbHVzQ29kZS5QTEFZX01FRElBX0ZBSUxFRH0sIG1lc3NhZ2U6ICR7ZXJyb3IubWVzc2FnZX0sYCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5QTEFZX01FRElBX0ZBSUxFRCB9O1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0IHsgQmFzaWNMb2dnZXIgfSBmcm9tICdAcm9uZ2Nsb3VkL2VuZ2luZSc7XG5pbXBvcnQge1xuICBJU3Vic2NyaWJlQXR0cixcbiAgUkNMb2NhbEF1ZGlvVHJhY2ssXG4gIFJDUlRDQ29kZSxcbiAgUkNSZW1vdGVBdWRpb1RyYWNrLFxuICBSQ1JlbW90ZVRyYWNrLFxuICBSQ1RyYWNrLFxufSBmcm9tICdAcm9uZ2Nsb3VkL3BsdWdpbi1ydGMnO1xuaW1wb3J0IHsgUkNDYWxsUGx1c0xvZ2dlclRhZyB9IGZyb20gJy4uL2FwaS9lbnVtcy9SQ0NhbGxQbHVzTG9nZ2VyVGFnJztcbmltcG9ydCB7XG4gIElDYWxsUGx1c0V2ZW50TGlzdGVuZXIsXG4gIElSQ0NhbGxQbHVzQ2FsbFJlY29yZCxcbiAgUkNDYWxsUGx1c01lZGlhVHlwZSxcbiAgUkNDYWxsUGx1c1JlYXNvbixcbiAgUkNDYWxsUGx1c1Nlc3Npb24sXG4gIFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLFxuICBSQ0NhbGxQbHVzVHlwZSxcbn0gZnJvbSAnLi4vYXBpL2ludGVyZmFjZSc7XG5pbXBvcnQgeyBSQ0NhbGxQbHVzTWVkaWFUeXBlQ2hhbmdlUmVzdWx0IH0gZnJvbSAnLi4vZW51bXMvUkNDYWxsUGx1c01lZGlhVHlwZUNoYW5nZVJlc3VsdCc7XG5cbmV4cG9ydCBjbGFzcyBSQ0NhbGxQbHVzUmVwb3J0TW9kdWxlIHtcbiAgcHJpdmF0ZSBfbGlzdGVuZXIhOiBJQ2FsbFBsdXNFdmVudExpc3RlbmVyXG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBfbG9nZ2VyOiBCYXNpY0xvZ2dlcixcbiAgKSB7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiDnirbmgIHmnLrkuovku7bms6jlhoxcbiAgICovXG4gIHB1YmxpYyByZWdpc3RlckV2ZW50TGlzdGVuZXIobGlzdGVuZXI6IElDYWxsUGx1c0V2ZW50TGlzdGVuZXIpIHtcbiAgICB0aGlzLl9saXN0ZW5lciA9IGxpc3RlbmVyO1xuICB9XG5cbiAgLyoqXG4gICog5Zue6LCD5bqU55So5bGC5LqL5Lu2XG4gICogQHBhcmFtIGV2ZW50TmFtZVxuICAqIEBwYXJhbSBhdHRyc1xuICAqIEByZXR1cm5zXG4gICovXG4gIHByaXZhdGUgX2NhbGxBcHBMaXN0ZW5lcihldmVudE5hbWU6IGtleW9mIElDYWxsUGx1c0V2ZW50TGlzdGVuZXIsIC4uLmF0dHJzOiBhbnlbXSkge1xuICAgIGNvbnN0IGhhbmRsZSA9IHRoaXMuX2xpc3RlbmVyPy5bZXZlbnROYW1lXSBhcyBGdW5jdGlvbjtcbiAgICBpZiAoIWhhbmRsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgaGFuZGxlKC4uLmF0dHJzKTtcbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9DQUxMX0VWRU5UX0xJU1RFTkVSX08sIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgbmFtZTogZXJyb3IubmFtZSxcbiAgICAgICAgbWVzc2FnZTogZXJyb3IubWVzc2FnZSxcbiAgICAgIH0pKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgb25SZWNlaXZlZENhbGwoc2Vzc2lvbjogUkNDYWxsUGx1c1Nlc3Npb24sIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfQ0FMTF9FVkVOVF9MSVNURU5FUl9PLCBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBldmVudFR5cGU6ICdvblJlY2VpdmVkQ2FsbCcsXG4gICAgICBjYWxsSWQ6IHNlc3Npb24uZ2V0Q2FsbElkKCksXG4gICAgfSksIHRyYWNlSWQpO1xuICAgIHRoaXMuX2NhbGxBcHBMaXN0ZW5lcignb25SZWNlaXZlZENhbGwnLCBzZXNzaW9uKTtcbiAgfVxuXG4gIHB1YmxpYyBvblJlbW90ZVVzZXJJbnZpdGVkKGludml0ZWVVc2VyTGlzdDogc3RyaW5nW10sIGludml0ZXJVc2VySWQ6IHN0cmluZywgY2FsbElkOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0NBTExfRVZFTlRfTElTVEVORVJfTywgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgZXZlbnRUeXBlOiAnb25SZW1vdGVVc2VySW52aXRlZCcsXG4gICAgICBpbnZpdGVlVXNlckxpc3QsXG4gICAgICBpbnZpdGVyVXNlcklkLFxuICAgICAgY2FsbElkLFxuICAgIH0pKTtcbiAgICB0aGlzLl9jYWxsQXBwTGlzdGVuZXIoJ29uUmVtb3RlVXNlckludml0ZWQnLCBpbnZpdGVlVXNlckxpc3QsIGludml0ZXJVc2VySWQhLCBjYWxsSWQpO1xuICB9XG5cbiAgcHVibGljIG9uQ2FsbENvbm5lY3RlZChzZXNzaW9uOiBSQ0NhbGxQbHVzU2Vzc2lvbikge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfQ0FMTF9FVkVOVF9MSVNURU5FUl9PLCBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBldmVudFR5cGU6ICdvbkNhbGxDb25uZWN0ZWQnLFxuICAgICAgY2FsbElkOiBzZXNzaW9uLmdldENhbGxJZCgpLFxuICAgIH0pKTtcbiAgICB0aGlzLl9jYWxsQXBwTGlzdGVuZXIoJ29uQ2FsbENvbm5lY3RlZCcsIHNlc3Npb24pO1xuICB9XG5cbiAgcHVibGljIG9uQ2FsbFR5cGVDaGFuZ2VkKGNhbGxUeXBlOiBSQ0NhbGxQbHVzVHlwZSwgY2FsbElkOiBzdHJpbmcsIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfQ0FMTF9FVkVOVF9MSVNURU5FUl9PLCBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBldmVudFR5cGU6ICdvbkNhbGxUeXBlQ2hhbmdlZCcsXG4gICAgICBjYWxsSWQsXG4gICAgICBjYWxsVHlwZSxcbiAgICB9KSwgdHJhY2VJZCk7XG4gICAgdGhpcy5fY2FsbEFwcExpc3RlbmVyKCdvbkNhbGxUeXBlQ2hhbmdlZCcsIGNhbGxUeXBlLCBjYWxsSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIOWinumHj+S4iuaKpei/nOerr+S6uuWRmOeKtuaAgeWPmOWMllxuICAgKi9cbiAgcHVibGljIG9uUmVtb3RlVXNlclN0YXRlQ2hhbmdlZChkYXRhOiB7XG4gICAgY2FsbElkOiBzdHJpbmcsXG4gICAgdXNlcklkOiBzdHJpbmcsXG4gICAgdXNlclN0YXRlOiBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZSxcbiAgICByZWFzb24/OiBSQ0NhbGxQbHVzUmVhc29uLFxuICB9LCB0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCB7XG4gICAgICBjYWxsSWQsIHVzZXJJZCwgdXNlclN0YXRlLCByZWFzb24sXG4gICAgfSA9IGRhdGE7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9DQUxMX0VWRU5UX0xJU1RFTkVSX08sIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIGV2ZW50VHlwZTogJ29uUmVtb3RlVXNlclN0YXRlQ2hhbmdlZCcsXG4gICAgICBjYWxsSWQsXG4gICAgICB1c2VySWQsXG4gICAgICB1c2VyU3RhdGUsXG4gICAgICByZWFzb24sXG4gICAgfSksIHRyYWNlSWQpO1xuICAgIHRoaXMuX2NhbGxBcHBMaXN0ZW5lcignb25SZW1vdGVVc2VyU3RhdGVDaGFuZ2VkJywgY2FsbElkLCB1c2VySWQsIHVzZXJTdGF0ZSwgcmVhc29uKTtcbiAgfVxuXG4gIHB1YmxpYyBvbkNhbGxFbmRlZChzZXNzaW9uOiBSQ0NhbGxQbHVzU2Vzc2lvbiwgcmVhc29uOiBSQ0NhbGxQbHVzUmVhc29uLCB0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0NBTExfRVZFTlRfTElTVEVORVJfTywgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgZXZlbnRUeXBlOiAnb25DYWxsRW5kZWQnLFxuICAgICAgY2FsbElkOiBzZXNzaW9uLmdldENhbGxJZCgpLFxuICAgICAgY2xvc2VSZWFzb246IHJlYXNvbixcbiAgICB9KSwgdHJhY2VJZCk7XG4gICAgdGhpcy5fY2FsbEFwcExpc3RlbmVyKCdvbkNhbGxFbmRlZCcsIHNlc3Npb24sIHJlYXNvbik7XG4gIH1cblxuICBwdWJsaWMgb25SZW1vdGVDYW1lcmFTdGF0ZUNoYW5nZWQoY2FsbElkOiBzdHJpbmcsIHRyYWNrOiBSQ1JlbW90ZVRyYWNrKSB7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9DQUxMX0VWRU5UX0xJU1RFTkVSX08sIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIGV2ZW50VHlwZTogJ29uUmVtb3RlQ2FtZXJhU3RhdGVDaGFuZ2VkJyxcbiAgICAgIGNhbGxJZCxcbiAgICAgIHRyYWNrSWQ6IHRyYWNrPy5nZXRUcmFja0lkKCksXG4gICAgICBlbmFibGU6IHRyYWNrPy5pc093bmVyTXV0ZWQoKSxcbiAgICB9KSk7XG4gICAgY29uc3QgdXNlcklkID0gdHJhY2s/LmdldFVzZXJJZCgpO1xuICAgIHRoaXMuX2NhbGxBcHBMaXN0ZW5lcignb25SZW1vdGVDYW1lcmFTdGF0ZUNoYW5nZWQnLCBjYWxsSWQsIHVzZXJJZCwgdHJhY2s/LmlzT3duZXJNdXRlZCgpKTtcbiAgfVxuXG4gIHB1YmxpYyBvblJlbW90ZU1pY3JvcGhvbmVTdGF0ZUNoYW5nZWQoY2FsbElkOiBzdHJpbmcsIHRyYWNrOiBSQ1JlbW90ZVRyYWNrKSB7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9DQUxMX0VWRU5UX0xJU1RFTkVSX08sIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIGV2ZW50VHlwZTogJ29uUmVtb3RlTWljcm9waG9uZVN0YXRlQ2hhbmdlZCcsXG4gICAgICBjYWxsSWQsXG4gICAgICB0cmFja0lkOiB0cmFjaz8uZ2V0VHJhY2tJZCgpLFxuICAgICAgZW5hYmxlOiB0cmFjaz8uaXNPd25lck11dGVkKCksXG4gICAgfSkpO1xuICAgIGNvbnN0IHVzZXJJZCA9IHRyYWNrPy5nZXRVc2VySWQoKTtcbiAgICB0aGlzLl9jYWxsQXBwTGlzdGVuZXIoJ29uUmVtb3RlTWljcm9waG9uZVN0YXRlQ2hhbmdlZCcsIGNhbGxJZCwgdXNlcklkLCB0cmFjaz8uaXNPd25lck11dGVkKCkpO1xuICB9XG5cbiAgcHVibGljIG9uUmVjZWl2ZWRDYWxsUmVjb3JkKHJlY29yZDogSVJDQ2FsbFBsdXNDYWxsUmVjb3JkLCB0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0NBTExfRVZFTlRfTElTVEVORVJfTywgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgZXZlbnRUeXBlOiAnb25SZWNlaXZlZENhbGxSZWNvcmQnLFxuICAgICAgcmVjb3JkLFxuICAgIH0pLCB0cmFjZUlkKTtcbiAgICB0aGlzLl9jYWxsQXBwTGlzdGVuZXIoJ29uUmVjZWl2ZWRDYWxsUmVjb3JkJywgcmVjb3JkKTtcbiAgfVxuXG4gIHB1YmxpYyBvblJlY2VpdmVkQ2hhbmdlTWVkaWFUeXBlUmVxdWVzdCh1c2VySWQ6IHN0cmluZywgdHJhbnNhY3Rpb25JZDogc3RyaW5nLCBtZWRpYVR5cGU6IFJDQ2FsbFBsdXNNZWRpYVR5cGUsIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfQ0FMTF9FVkVOVF9MSVNURU5FUl9PLCBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBldmVudFR5cGU6ICdvblJlY2VpdmVkQ2hhbmdlTWVkaWFUeXBlUmVxdWVzdCcsXG4gICAgICB1c2VySWQsXG4gICAgICB0cmFuc2FjdGlvbklkLFxuICAgIH0pLCB0cmFjZUlkKTtcbiAgICB0aGlzLl9jYWxsQXBwTGlzdGVuZXIoJ29uUmVjZWl2ZWRDaGFuZ2VNZWRpYVR5cGVSZXF1ZXN0JywgdXNlcklkLCB0cmFuc2FjdGlvbklkLCBtZWRpYVR5cGUpO1xuICB9XG5cbiAgcHVibGljIG9uUmVjZWl2ZWRDaGFuZ2VNZWRpYVR5cGVSZXN1bHQoaW5mbzoge1xuICAgIHVzZXJJZDogc3RyaW5nLFxuICAgIHRyYW5zYWN0aW9uSWQ6IHN0cmluZyxcbiAgICBtZWRpYVR5cGU6IFJDQ2FsbFBsdXNNZWRpYVR5cGUsXG4gICAgY29kZTogUkNDYWxsUGx1c01lZGlhVHlwZUNoYW5nZVJlc3VsdFxuICB9LCB0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCB7XG4gICAgICB1c2VySWQsIHRyYW5zYWN0aW9uSWQsIG1lZGlhVHlwZSwgY29kZSxcbiAgICB9ID0gaW5mbztcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0NBTExfRVZFTlRfTElTVEVORVJfTywgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgZXZlbnRUeXBlOiAnb25SZWNlaXZlZENoYW5nZU1lZGlhVHlwZVJlc3VsdCcsXG4gICAgICB1c2VySWQsXG4gICAgICBtZWRpYVR5cGUsXG4gICAgfSksIHRyYWNlSWQpO1xuICAgIHRoaXMuX2NhbGxBcHBMaXN0ZW5lcignb25SZWNlaXZlZENoYW5nZU1lZGlhVHlwZVJlc3VsdCcsIHtcbiAgICAgIHVzZXJJZCwgdHJhbnNhY3Rpb25JZCwgbWVkaWFUeXBlLCBjb2RlLFxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIG9uUmVjZWl2ZWRDYWxsU3RhcnRUaW1lKGluZm86IHsgY2FsbElkOiBzdHJpbmcsIGNhbGxTdGFydFRpbWU6IG51bWJlciB9LCB0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0NBTExfRVZFTlRfTElTVEVORVJfTywgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgZXZlbnRUeXBlOiAnb25SZWNlaXZlZENhbGxTdGFydFRpbWUnLFxuICAgICAgaW5mbyxcbiAgICB9KSwgdHJhY2VJZCk7XG4gICAgdGhpcy5fY2FsbEFwcExpc3RlbmVyKCdvblJlY2VpdmVkQ2FsbFN0YXJ0VGltZScsIGluZm8pO1xuICB9XG5cbiAgcHVibGljIG9uUmVjZWl2ZWRDYWxsRmlyc3RGcmFtZVRpbWUoY2FsbElkOiBzdHJpbmcsIGNhbGxGaXJzdEZyYW1lVGltZTogbnVtYmVyLCB0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0NBTExfRVZFTlRfTElTVEVORVJfTywgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgZXZlbnRUeXBlOiAnb25SZWNlaXZlZENhbGxGaXJzdEZyYW1lVGltZScsXG4gICAgICBjYWxsSWQsXG4gICAgICBjYWxsRmlyc3RGcmFtZVRpbWUsXG4gICAgfSksIHRyYWNlSWQpO1xuICAgIHRoaXMuX2NhbGxBcHBMaXN0ZW5lcignb25SZWNlaXZlZENhbGxGaXJzdEZyYW1lVGltZScsIGNhbGxJZCwgY2FsbEZpcnN0RnJhbWVUaW1lKTtcbiAgfVxuXG4gIHB1YmxpYyBvblVzZXJNZWRpYUF2YWlsYWJsZSh0cmFja3M6IFJDVHJhY2tbXSwgdHJhY2VJZD86IHN0cmluZykge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfQ0FMTF9FVkVOVF9MSVNURU5FUl9PLCBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBldmVudFR5cGU6ICdvblVzZXJNZWRpYUF2YWlsYWJsZScsXG4gICAgICB0cmFja0lkczogdHJhY2tzLm1hcCgodHJhY2spID0+IHRyYWNrLmdldFRyYWNrSWQoKSksXG4gICAgfSksIHRyYWNlSWQpO1xuXG4gICAgdHJhY2tzLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICBjb25zdCB1c2VySWQgPSB0cmFjay5nZXRVc2VySWQoKTtcbiAgICAgIGNvbnN0IG1lZGlhVHlwZSA9IHRyYWNrLmlzQXVkaW9UcmFjaygpID8gUkNDYWxsUGx1c01lZGlhVHlwZS5BVURJTyA6IFJDQ2FsbFBsdXNNZWRpYVR5cGUuVklERU87XG4gICAgICB0aGlzLl9jYWxsQXBwTGlzdGVuZXIoJ29uVXNlck1lZGlhQXZhaWxhYmxlJywgdXNlcklkLCBtZWRpYVR5cGUpO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIG9uRmV0Y2hSZW1vdGVNZWRpYUVycm9yKHRyYWNrczogSVN1YnNjcmliZUF0dHJbXSwgY29kZTogUkNSVENDb2RlKSB7XG4gICAgdHJhY2tzLmZvckVhY2goKHsgdHJhY2sgfSkgPT4ge1xuICAgICAgY29uc3QgdXNlcklkID0gdHJhY2suZ2V0VXNlcklkKCk7XG4gICAgICB0aGlzLl9jYWxsQXBwTGlzdGVuZXIoJ29uRmV0Y2hSZW1vdGVNZWRpYUVycm9yJywgdXNlcklkLCBjb2RlKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBvblVzZXJBdWRpb0xldmVsQ2hhbmdlZChhdWRpb0xldmVsUmVwb3J0TGlzdDoge1xuICAgIHRyYWNrOiBSQ0xvY2FsQXVkaW9UcmFjayB8IFJDUmVtb3RlQXVkaW9UcmFjaztcbiAgICBhdWRpb0xldmVsOiBudW1iZXI7XG4gIH1bXSkge1xuICAgIGF1ZGlvTGV2ZWxSZXBvcnRMaXN0LmZvckVhY2goKHsgdHJhY2ssIGF1ZGlvTGV2ZWwgfSkgPT4ge1xuICAgICAgY29uc3QgdXNlcklkID0gdHJhY2suZ2V0VXNlcklkKCk7XG4gICAgICB0aGlzLl9jYWxsQXBwTGlzdGVuZXIoJ29uVXNlckF1ZGlvTGV2ZWxDaGFuZ2VkJywgdXNlcklkLCBhdWRpb0xldmVsKTtcbiAgICB9KTtcbiAgfVxufVxuIiwiZXhwb3J0IGVudW0gQ2FsbFNlcnZlckVycm9yQ29kZSB7XG4gIC8qKlxuICAgKiDmnKrnn6XplJnor69cbiAgICovXG4gIFVOS05PV19FUlIgPSA0MTAwMCxcbiAgLyoqXG4gICAqIOaVsOaNruW6k+mUmeivr1xuICAgKi9cbiAgREJfRVJSID0gNDEwMDEsXG4gIC8qKlxuICAgKiBqc29uIOmUmeivr1xuICAgKi9cbiAgSlNPTl9FUlIgPSA0MTAwMixcbiAgLyoqXG4gICAqIGpzb24g5qC85byP6ZSZ6K+vXG4gICAqL1xuICBJTlZBTElEX0pTT05fRVJSID0gNDEwMDMsXG4gIC8qKlxuICAgKiDlj4LmlbDkuKLlpLFcbiAgICovXG4gIE1JU1NJTkdfUEFSQU1TID0gNDEwMDQsXG4gIC8qKlxuICAgKiDlj4LmlbDkuI3og73kuLrnqbpcbiAgICovXG4gIFBBUkFNU19SRVFVSVJFRCA9IDQxMDA1LFxuICAvKipcbiAgICog5pWw5o2u5qC85byP6ZSZ6K+vXG4gICAqL1xuICBEQVRBX0ZPUk1BVF9FUlIgPSA0MTAwNixcbiAgLyoqXG4gICAqIOaWueazleacquWunueOsFxuICAgKi9cbiAgTUVUSE9EX05PVF9JTVBMRU1FTlRFRCA9IDQxMDA3LFxuICAvKipcbiAgICogY2FsbCDkuI3lrZjlnKjmiJblt7Lnu5PmnZ9cbiAgICovXG4gIENBTExfTk9UX0VYSVNUID0gNDEwMTAsXG4gIC8qKlxuICAgKiDljZXlkbwg6KKr6YKA6K+36ICF5LiN6IO96LaF6L+H5Lik5Lq6XG4gICAqL1xuICBTSU5HQUxfRVhDRUVEX1RXT19JTlZJVEVFID0gNDEwMTEsXG4gIC8qKlxuICAgKiDnvqTnu4Tlkbzlj6votoXov4fop4TlrprkurrmlbDvvIjmnIDlpJogMzIg5Lq677yJXG4gICAqL1xuICBHUk9VUF9FWENFRURTX1FVT1JVTSA9IDQxMDEyLFxuICAvKipcbiAgICog5pON5L2c5bey6L+H5pyfXG4gICAqL1xuICBPUEVSQVRJT05fRVhQSVJFRCA9IDQxMDEzLFxuICAvKipcbiAgICog5b2T5YmN6K6+5aSH5q2j5Zyo5ZG85Y+r5LitXG4gICAqL1xuICBERVZJQ0VfSVNfQ0FMTElORyA9IDQxMDE0LFxuICAvKipcbiAgICog5LiK5oql55qEIHN0cmVhbVJlYWR5VGltZSDml6DmlYhcbiAgICovXG4gIFJFUE9SVF9TVFJFQU1fUkVBRFlfVElNRV9JU19JTlZBTElEID0gNDEwMTgsXG4gIC8qKlxuICAgKiDkuI3og73lkbzoh6rlt7FcbiAgICovXG4gIE5PVF9DQUxMX1lPVVJTRUxGID0gNDEwMTksXG4gIC8qKlxuICAgKiDkvJror53nirbmgIHkuI3lrZjlnKhcbiAgICovXG4gIFNFU1NJT05fU1RBVFVTX05PVF9FWElTVCA9IDQxMDIwLFxuICAvKipcbiAgICogaGFuZ3VwIOaTjeS9nOWcqOW9k+WJjeeKtuaAgeS4jeWFgeiuuOiwg+eUqFxuICAgKi9cbiAgSEFOR1VQX05PVF9BTExPVyA9IDQxMDIxLFxuICAvKipcbiAgICogYWNjZXB0IOaTjeS9nOWcqOW9k+WJjeeKtuaAgeS4jeWFgeiuuOiwg+eUqFxuICAgKi9cbiAgQUNDRVBUX05PVF9BTExPVyA9IDQxMDIyLFxuICAvKipcbiAgICog5pON5L2c5Zyo5b2T5YmN5pa55rOV5LiN5YWB6K646LCD55SoXG4gICAqL1xuICBPUEVSQVRJT05fTk9UX0FMTE9XID0gNDEwMjUsXG4gIC8qKlxuICAgKiDkuJrliqFJZOS4jeato+ehruaIluiAheS4muWKoeW3sue7k+adn1xuICAgKi9cbiAgVFJBTlNBQ1RJT05fSURfRVJSID0gNDExMDAsXG4gIC8qKlxuICAgKiDpn7PpopHljYfnuqfop4bpopHlt7Looqvlj5HotbfogIXlj5bmtohcbiAgICovXG4gIFVQX1ZJREVPX0NBTkNFTEVEID0gNDEwNTAsXG4gIC8qKlxuICAgKiDlvZPliY3pgJror53lt7Lnu4/mmK/pn7PpopHpgJror53vvIzml6DpnIDpmY3nuqdcbiAgICovXG4gIENVUlJFTlRfQ0FMTF9JU19BVURJTyA9IDQxMDUxLFxuICAvKipcbiAgICog5b2T5YmN6YCa6K+d5bey57uP5piv6KeG6aKR6YCa6K+d77yM5peg6ZyA5Y2H57qnXG4gICAqL1xuICAgQ1VSUkVOVF9DQUxMX0lTX1ZJREVPID0gNDEwNTIsXG59XG4iLCJpbXBvcnQge1xuICBCYXNpY0xvZ2dlciwgZ2V0VVVJRCwgSVJ1bnRpbWUsIGlzQm9vbGVhbiwgaXNOdW1iZXIsIGlzU3RyaW5nLCBpc1VuZGVmaW5lZCwgbm90RW1wdHlBcnJheSwgbm90RW1wdHlTdHJpbmcsIFBsdWdpbkNvbnRleHQsIFJDQ29ubmVjdGlvblN0YXR1cyxcbn0gZnJvbSAnQHJvbmdjbG91ZC9lbmdpbmUnO1xuaW1wb3J0IHsgUkNSZW1vdGVUcmFjaywgUkNSVENDb2RlLCBkZXZpY2UgfSBmcm9tICdAcm9uZ2Nsb3VkL3BsdWdpbi1ydGMnO1xuaW1wb3J0IHsgUkNDYWxsUGx1c0NvZGUgfSBmcm9tICcuL2VudW1zL1JDQ2FsbFBsdXNDb2RlJztcbmltcG9ydCB7IFJDQ2FsbFBsdXNMb2dnZXJUYWcgfSBmcm9tICcuL2VudW1zL1JDQ2FsbFBsdXNMb2dnZXJUYWcnO1xuaW1wb3J0IHtcbiAgUkNDYWxsUGx1c0ZyYW1lUmF0ZSxcbiAgUkNDYWxsUGx1c1Jlc29sdXRpb24sXG4gIElDYWxsUGx1c0V2ZW50TGlzdGVuZXIsXG4gIElDYWxsUGx1c0luaXRPcHRzLFxuICBJU3RhdHVzUmVwb3J0TGlzdGVuZXIsXG4gIElSQ0NhbGxQbHVzR2V0Q2FsbFJlY29yZFJlcyxcbiAgUkNDYWxsUGx1c0NhbGxVc2VyLFxuICBSQ0NhbGxQbHVzTWVkaWFUeXBlLFxuICBSQ0NhbGxQbHVzU2Vzc2lvbixcbiAgUkNDYWxsUGx1c1R5cGUsXG4gIFJDQ2FsbFBsdXNTZXNzaW9uVXNlclN0YXRlLFxuICBJQXVkaW9Db25maWcsXG4gIElWaWRlb0NvbmZpZyxcbiAgUkNDYWxsUGx1c0NhbGxTdGF0ZSxcbiAgSVJDQ2FsbFBsdXNDYWxsUmVjb3JkLFxufSBmcm9tICcuL2ludGVyZmFjZSc7XG5pbXBvcnQgUkNBdWRpb0NvbmZpZ0J1aWxkZXIgZnJvbSAnLi9SQ0F1ZGlvQ29uZmlnQnVpbGRlcic7XG5pbXBvcnQgUkNWaWRlb0NvbmZpZ0J1aWxkZXIgZnJvbSAnLi9SQ1ZpZGVvQ29uZmlnQnVpbGRlcic7XG5pbXBvcnQgeyBSQ0NhbGxQbHVzUmVhc29uIH0gZnJvbSAnLi9lbnVtcy9SQ0NhbGxQbHVzUmVhc29uJztcbmltcG9ydCB7XG4gIGdldEhhbmd1cFN5c3RlbVN0YXRlLCBpc1N1cHBvcnRNZWRpYVNlcnZlciwgdmFsaWRhdGVCaXRyYXRlLCB2YWxpZGF0ZVZpZGVvTm9kZU5hbWUsXG59IGZyb20gJy4uL3V0aWxzL2hlbHBlcic7XG5pbXBvcnQgUkNDYWxsUEx1c1N0YXRpc3RpY3MgZnJvbSAnLi4vbW9kdWxlcy9SQ0NhbGxQTHVzU3RhdGlzdGljcyc7XG5pbXBvcnQgeyBSQ0NhbGxQbHVzU3RhdGlzdGljc1RhZyB9IGZyb20gJy4uL2VudW1zL1JDQ2FsbFBsdXNTdGF0aXN0aWNzVGFnJztcbmltcG9ydCB7XG4gIElIYW5ndXBGb3JCdXN5T3B0cywgSU1lbWJlckluZm8sXG59IGZyb20gJy4uL2ludGVyZmFjZXMvSVJDQ2FsbENsaWVudCc7XG5pbXBvcnQgeyBSQ0NhbGxFbmdpbmUgfSBmcm9tICcuLi9SQ0NhbGxFbmdpbmUnO1xuaW1wb3J0IHsgUlRDTW9kdWxlIH0gZnJvbSAnLi4vbW9kdWxlcy9SVENNb2R1bGUnO1xuaW1wb3J0IHsgRm9yd2FyZFR5cGUgfSBmcm9tICcuLi9lbnVtcy9Gb3J3YXJkVHlwZSc7XG5pbXBvcnQgeyBSQ0NhbGxQbHVzUmVwb3J0TW9kdWxlIH0gZnJvbSAnLi4vbW9kdWxlcy9SQ0NhbGxQbHVzUmVwb3J0TW9kdWxlJztcbmltcG9ydCB7IENhbGxTZXJ2ZXJFcnJvckNvZGUgfSBmcm9tICcuLi9lbnVtcy9DYWxsU2VydmVyRXJyb3JDb2RlJztcblxuZXhwb3J0IGNsYXNzIFJDQ2FsbFBsdXNDbGllbnQge1xuICAvKipcbiAgICog5pGE5YOP5aS06YeH6ZuG6YWN572uXG4gICAqL1xuICBwcml2YXRlIF92aWRlb0NvbmZpZzogSVZpZGVvQ29uZmlnID0ge1xuICAgIHJlc29sdXRpb246IFJDQ2FsbFBsdXNSZXNvbHV0aW9uLlc2NDBfSDQ4MCxcbiAgICBmcmFtZVJhdGU6IFJDQ2FsbFBsdXNGcmFtZVJhdGUuRlBTXzE1LFxuICB9XG5cbiAgLyoqXG4gICAqIOm6puWFi+mjjumHh+mbhumFjee9rlxuICAgKi9cbiAgcHJpdmF0ZSBfYXVkaW9Db25maWc6IElBdWRpb0NvbmZpZyA9IHt9XG5cbiAgLyoqXG4gICAqIOe7n+iuoeWfi+eCueexu1xuICAgKi9cbiAgcHJpdmF0ZSBfY2FsbFBsdXNTdGF0aXN0aWNzOiBSQ0NhbGxQTHVzU3RhdGlzdGljc1xuXG4gIC8qKlxuICAgKiBjbGllbnQgY2FsbElkXG4gICAqL1xuICBwcml2YXRlIF9jbGllbnRDYWxsSWQ6IHN0cmluZyA9ICcnXG5cbiAgLyoqXG4gICAqIOaYr+WQpuS4uuS4u+WKqOaMguaWrVxuICAgKi9cbiAgcHJpdmF0ZSBfaXNMYXVuY2hIYW5ndXAgPSBmYWxzZVxuXG4gIC8qKlxuICAgKiDlkbzlj6vov4fnqIvkuK3mjILmlq1cbiAgICovXG4gIHByaXZhdGUgX25lZWRIYW5ndXBDYWxsSWQ6IHN0cmluZyB8IG51bGwgPSBudWxsXG5cbiAgcHJpdmF0ZSBfY2FsbEVuZ2luZTogUkNDYWxsRW5naW5lO1xuXG4gIHByaXZhdGUgX3J0Y01vZHVsZTogUlRDTW9kdWxlO1xuXG4gIC8qKlxuICAgKiDkuIrmiqXlupTnlKjlsYLkuovku7bmqKHlnZdcbiAgICovXG4gIF9yZXBvcnRBcHBFdmVudE1vZHVsZTogUkNDYWxsUGx1c1JlcG9ydE1vZHVsZVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NvbnRleHQ6IFBsdWdpbkNvbnRleHQsXG4gICAgcHJpdmF0ZSByZWFkb25seSBfbG9nZ2VyOiBCYXNpY0xvZ2dlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9ydW50aW1lOiBJUnVudGltZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9pbml0T3B0czogSUNhbGxQbHVzSW5pdE9wdHMsXG4gICkge1xuICAgIHRoaXMuX3JlcG9ydEFwcEV2ZW50TW9kdWxlID0gbmV3IFJDQ2FsbFBsdXNSZXBvcnRNb2R1bGUoX2xvZ2dlcik7XG4gICAgdGhpcy5fY2FsbFBsdXNTdGF0aXN0aWNzID0gbmV3IFJDQ2FsbFBMdXNTdGF0aXN0aWNzKHRoaXMuX2xvZ2dlciwgdGhpcy5fY29udGV4dCk7XG4gICAgLy8g5Yid5aeL5YyW54q25oCB5py65a6e5L6LXG4gICAgdGhpcy5fY2FsbEVuZ2luZSA9IG5ldyBSQ0NhbGxFbmdpbmUodGhpcy5fY29udGV4dCwgdGhpcy5fcnVudGltZSwgdGhpcy5faW5pdE9wdHMsIHRoaXMuX2xvZ2dlciwgdGhpcy5fcmVwb3J0QXBwRXZlbnRNb2R1bGUpO1xuXG4gICAgdGhpcy5fcnRjTW9kdWxlID0gbmV3IFJUQ01vZHVsZSh0aGlzLl9jb250ZXh0LCB0aGlzLl9ydW50aW1lLCB0aGlzLl9pbml0T3B0cywgdGhpcy5fbG9nZ2VyLCB0aGlzLl9jYWxsRW5naW5lLCB0aGlzLl9yZXBvcnRBcHBFdmVudE1vZHVsZSk7XG5cbiAgICB0aGlzLl9ydGNNb2R1bGUub24oUlRDTW9kdWxlLl9fSU5ORVJfUlRDX1BST0NFU1NfRkFJTEVEX18sIHRoaXMuX3J0Y1Byb2Nlc3NGYWlsSGFuZGxlLmJpbmQodGhpcykpO1xuICAgIHRoaXMuX3J0Y01vZHVsZS5vbihSVENNb2R1bGUuX19JTk5FUl9SVENfUEVFUkNPTk5FQ1RJT05fQUJOT1JNQUxfQ0xPU0VfXywgdGhpcy5fcGVlckNvbm5lY3Rpb25BYm5vcm1hbENsb3NlLmJpbmQodGhpcykpO1xuICAgIHRoaXMuX3J0Y01vZHVsZS5vbihSVENNb2R1bGUuX19JTk5FUl9PTl9TRUxGX0pPSU5FRF9fLCB0aGlzLl9zZWxmSm9pbmVkSGFuZGxlLmJpbmQodGhpcykpO1xuICAgIHRoaXMuX3J0Y01vZHVsZS5vbihSVENNb2R1bGUuX19JTk5FUl9PTl9PVEhFUl9KT0lORURfXywgdGhpcy5fb3RoZXJKb2luZWRIYW5kbGUuYmluZCh0aGlzKSk7XG4gICAgdGhpcy5fcnRjTW9kdWxlLm9uKFJUQ01vZHVsZS5fX0lOTkVSX1JFQ0VJVkVfRklSU1RfRlJBTUVfXywgdGhpcy5fcmVjZWl2ZUZpcnN0RnJhbWVIYW5kbGUuYmluZCh0aGlzKSk7XG4gICAgdGhpcy5fcnRjTW9kdWxlLm9uKFJUQ01vZHVsZS5fX0lOTkVSX09OX0tJQ0tPRkZfXywgdGhpcy5fa2lja29mZkhhbmRsZS5iaW5kKHRoaXMpKTtcbiAgICB0aGlzLl9ydGNNb2R1bGUub24oUlRDTW9kdWxlLl9fSU5ORVJfT05fREVWSUNFX0VOQUJMRV9DSEFOR0VfXywgdGhpcy5fcmVjZWl2ZURldmljZUVuYWJsZUNoYW5nZUhhbmRsZS5iaW5kKHRoaXMpKTtcblxuICAgIC8qKlxuICAgICAqIOmAmuivneW7uueri+WQju+8jFJUQyDmqKHlnZfpnIDlj5HluIPotYTmupBcbiAgICAgKi9cbiAgICB0aGlzLl9jYWxsRW5naW5lLm9uKFJDQ2FsbEVuZ2luZS5fX0lOTkVSX1NFU1NJT05fQ09OTkVDVF9fLCB0aGlzLl9ydGNNb2R1bGUuc2Vzc2lvbkNvbm5lY3RlZC5iaW5kKHRoaXMuX3J0Y01vZHVsZSkpO1xuICAgIC8qKlxuICAgICAqIOmAmuivneaMguaWreWQju+8jFJUQyDmqKHlnZfpnIDpgIDlh7rmiL/pl7TjgIHlpITnkIblhoXlrZjmlbDmja5cbiAgICAgKi9cbiAgICB0aGlzLl9jYWxsRW5naW5lLm9uKFJDQ2FsbEVuZ2luZS5fX0lOTkVSX1NFU1NJT05fQ0xPU0VfXywgdGhpcy5fc2Vzc2lvbkNsb3NlSGFuZGxlLmJpbmQodGhpcykpO1xuICAgIC8qKlxuICAgICAqIOWkhOeQhiBSVEMg5qih5Z2X5aqS5L2T5Y2H6ZmN57qn6YC76L6RXG4gICAgICovXG4gICAgdGhpcy5fY2FsbEVuZ2luZS5vbihSQ0NhbGxFbmdpbmUuX19JTk5FUl9DSEFOR0VfTUVESUFfVFlQRV9fLCB0aGlzLl9ydGNNb2R1bGUuY2hhbmdlTWVkaWFUeXBlLmJpbmQodGhpcy5fcnRjTW9kdWxlKSk7XG4gICAgLyoqXG4gICAgICog5pS25Yiw6YCa6K+d6YKA6K+35ZCO77yM6ZyA5LiK5oql5Z+L54K5XG4gICAgICovXG4gICAgdGhpcy5fY2FsbEVuZ2luZS5vbihSQ0NhbGxFbmdpbmUuX19JTk5FUl9JTlZJVEVfXywgKG5ld1Nlc3Npb24sIGludml0ZVNvdXJjZSkgPT4ge1xuICAgICAgdGhpcy5fY2FsbFBsdXNTdGF0aXN0aWNzLnJlcG9ydFN0YXRpc3RpY3NEYXRhKFJDQ2FsbFBsdXNTdGF0aXN0aWNzVGFnLkxfUVNfUkVDRUlWRV9DQUxMX1MsIFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MsICtuZXcgRGF0ZSgpLCBuZXdTZXNzaW9uLCAnJywgaW52aXRlU291cmNlKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDliqDmiL/pl7TjgIHlj5HluIPjgIHorqLpmIXlpLHotKXml7bpnIDnu5PmnZ/pgJror53vvIzlubbkuIrmiqXljp/lm6BcbiAgICovXG4gIHByaXZhdGUgX3J0Y1Byb2Nlc3NGYWlsSGFuZGxlKHN5c3RlbVN0YXRlOiBSQ0NhbGxQbHVzUmVhc29uLCB0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBtYWluU2Vzc2lvbiA9IHRoaXMuX2NhbGxFbmdpbmUuZ2V0TG9jYWxNYWluU2Vzc2lvbigpO1xuICAgIGlmIChtYWluU2Vzc2lvbikge1xuICAgICAgY29uc3QgY2FsbElkID0gbWFpblNlc3Npb24uZ2V0Q2FsbElkKCk7XG4gICAgICB0aGlzLl9jYWxsRW5naW5lLnN5c3RlbVN0YXR1c1VwKHtcbiAgICAgICAgY2FsbElkLFxuICAgICAgICBzeXNTdGF0dXM6IHN5c3RlbVN0YXRlLFxuICAgICAgICBmb3J3YXJkOiBGb3J3YXJkVHlwZS5DVVJSRU5ULFxuICAgICAgfSwgdHJhY2VJZCk7XG4gICAgICB0aGlzLl9jYWxsUGx1c1N0YXRpc3RpY3MucmVwb3J0U3RhdGlzdGljc0RhdGEoUkNDYWxsUGx1c1N0YXRpc3RpY3NUYWcuTF9RU19BQk5PUk1BTF9IQU5HVVBfUywgUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUywgK25ldyBEYXRlKCksIG1haW5TZXNzaW9uKTtcbiAgICAgIHRoaXMuX19pbm5lckhhbmd1cCh7IGNhbGxJZCwgc3lzdGVtU3RhdGUgfSwgdHJhY2VJZCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIHJ0YyBwZWVyQ29ubmVjdGlvbiDlvILluLjmlq3lvIDml7bpnIDnu5PmnZ/pgJror53vvIzlubbkuIrmiqXljp/lm6BcbiAgICovXG4gIHByaXZhdGUgX3BlZXJDb25uZWN0aW9uQWJub3JtYWxDbG9zZSh0cmFjZUlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBtYWluU2Vzc2lvbiA9IHRoaXMuX2NhbGxFbmdpbmUuZ2V0TG9jYWxNYWluU2Vzc2lvbigpO1xuICAgIGlmIChtYWluU2Vzc2lvbikge1xuICAgICAgLy8g5LiK5oql54q25oCB6K6p5a+55pa555+l6YGT6Ieq5bex56a75byA55qE5Y6f5ZugXG4gICAgICB0aGlzLl9jYWxsRW5naW5lLnN5c3RlbVN0YXR1c1VwKHtcbiAgICAgICAgY2FsbElkOiBtYWluU2Vzc2lvbi5nZXRDYWxsSWQoKSxcbiAgICAgICAgc3lzU3RhdHVzOiBSQ0NhbGxQbHVzUmVhc29uLkNPTk5FQ1RJT05fRVJSLFxuICAgICAgICBmb3J3YXJkOiBGb3J3YXJkVHlwZS5DVVJSRU5ULFxuICAgICAgfSwgdHJhY2VJZCk7XG4gICAgICB0aGlzLl9jYWxsRW5naW5lLmVuZEN1cnJlbnRTZXNzaW9uKFJDQ2FsbFBsdXNSZWFzb24uQ09OTkVDVElPTl9FUlIsIG1haW5TZXNzaW9uLmdldENhbGxJZCgpLCB0cmFjZUlkKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog5pys56uv5Yqg5YWlIFJUQyDmiL/pl7TvvIzpnIDmm7TmlrDmnKzkurogT05DQUxMIOeKtuaAge+8jOmHjeaWsOagoeaXtlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBfc2VsZkpvaW5lZEhhbmRsZShjYWxsSWQ6IHN0cmluZywgdHJhY2VJZDogc3RyaW5nKSB7XG4gICAgY29uc3QgdXNlcklkID0gdGhpcy5fY29udGV4dC5nZXRDdXJyZW50SWQoKTtcbiAgICBjb25zdCBzZXNzaW9uID0gdGhpcy5fY2FsbEVuZ2luZS5nZXRMb2NhbE1haW5TZXNzaW9uKCk7XG4gICAgdGhpcy5fcmVwb3J0QXBwRXZlbnRNb2R1bGUub25DYWxsQ29ubmVjdGVkKHNlc3Npb24hKTtcblxuICAgIC8qKlxuICAgICAqIOabtOaWsOiHquW3seeahOeKtuaAgVxuICAgICAqL1xuICAgIGNvbnN0IHZpZGVvVHJhY2sgPSB0aGlzLl9ydGNNb2R1bGUuZ2V0TG9jYWxWaWRlb1RyYWNrKCk7XG4gICAgY29uc3QgYXVkaW9UcmFjayA9IHRoaXMuX3J0Y01vZHVsZS5nZXRMb2NhbEF1ZGlvVHJhY2soKTtcbiAgICBjb25zdCBjYW1lcmFFbmFibGUgPSB2aWRlb1RyYWNrID8gIXZpZGVvVHJhY2suaXNPd25lck11dGVkKCkgOiBmYWxzZTtcbiAgICBjb25zdCBtaWNyb3Bob25lRW5hYmxlID0gYXVkaW9UcmFjayA/ICFhdWRpb1RyYWNrLmlzT3duZXJNdXRlZCgpIDogZmFsc2U7XG5cbiAgICB0aGlzLl9jYWxsRW5naW5lLnNldFVzZXJEZXZpY2VFbmFibGUodXNlcklkLCBSQ0NhbGxQbHVzTWVkaWFUeXBlLlZJREVPLCBjYW1lcmFFbmFibGUsIHRyYWNlSWQpO1xuICAgIHRoaXMuX2NhbGxFbmdpbmUuc2V0VXNlckRldmljZUVuYWJsZSh1c2VySWQsIFJDQ2FsbFBsdXNNZWRpYVR5cGUuQVVESU8sIG1pY3JvcGhvbmVFbmFibGUsIHRyYWNlSWQpO1xuXG4gICAgY29uc3Qgc2VsZlN0YXRlID0gW1xuICAgICAge1xuICAgICAgICB1c2VySWQsXG4gICAgICAgIHVzZXJTdGF0ZTogUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUuT05DQUxMLFxuICAgICAgICBzeXN0ZW1TdGF0ZTogUkNDYWxsUGx1c1JlYXNvbi5PTkNBTEwsXG4gICAgICAgIGNhbWVyYUVuYWJsZSxcbiAgICAgICAgbWljcm9waG9uZUVuYWJsZSxcbiAgICAgIH0sXG4gICAgXTtcbiAgICB0aGlzLl9jYWxsRW5naW5lLnVwZGF0ZVVzZXJzU3RhdGUoY2FsbElkLCBzZWxmU3RhdGUsIHRyYWNlSWQpO1xuXG4gICAgLy8g6YeN5paw5byA5aeL5qCh5pe26YC76L6RXG4gICAgdGhpcy5fY2FsbEVuZ2luZS5zdGFydFRpbWVDb3JyZWN0aW9uKHRyYWNlSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIOi/nOerr+S6uuWRmOWKoOWFpeaIv+mXtO+8jOabtOaWsOi/nOerr+S6uuWRmOeKtuaAgeWSjOmAmuivneeKtuaAgeS4uiBPTkNBTExcbiAgICovXG4gIHByaXZhdGUgX290aGVySm9pbmVkSGFuZGxlKGluZm86IElNZW1iZXJJbmZvW10sIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIC8vIOabtOaWsOWKoOWFpeaIv+mXtOS6uuWRmOeKtuaAgVxuICAgIGxldCBjYWxsSWQgPSAnJztcbiAgICBjb25zdCB1c2Vyc1N0YXRlID0gaW5mby5tYXAoKGl0ZW0pID0+IHtcbiAgICAgIGNhbGxJZCA9IGl0ZW0uY2FsbElkO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdXNlcklkOiBpdGVtLnVzZXJJZCxcbiAgICAgICAgdXNlclN0YXRlOiBSQ0NhbGxQbHVzU2Vzc2lvblVzZXJTdGF0ZS5PTkNBTEwsXG4gICAgICAgIHN5c3RlbVN0YXRlOiBSQ0NhbGxQbHVzUmVhc29uLk9OQ0FMTCxcbiAgICAgICAgY2FtZXJhRW5hYmxlOiBmYWxzZSxcbiAgICAgICAgbWljcm9waG9uZUVuYWJsZTogZmFsc2UsXG4gICAgICB9O1xuICAgIH0pO1xuICAgIHRoaXMuX2NhbGxFbmdpbmUudXBkYXRlVXNlcnNTdGF0ZShjYWxsSWQsIHVzZXJzU3RhdGUsIHRyYWNlSWQpO1xuXG4gICAgLy8g5pyJ5Lq65Y+q5Yqg5oi/6Ze077yM5LiN5Y+R5rWB77yM5pWF5q2k5aSE5Lmf5pu05paw5Li6IENPTk5FQ1RFRFxuICAgIGlmICh0aGlzLl9jYWxsRW5naW5lLmdldExvY2FsTWFpblNlc3Npb24oKT8uZ2V0U3RhdGUoKSAhPT0gUkNDYWxsUGx1c0NhbGxTdGF0ZS5PTkNBTEwpIHtcbiAgICAgIHRoaXMuX2NhbGxFbmdpbmUudXBkYXRlTWFpblNlc3Npb25TdGF0ZShSQ0NhbGxQbHVzQ2FsbFN0YXRlLk9OQ0FMTCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOaUtuWIsOmmluW4p+S4iuaKpee7meS4muWKoeWxglxuICAgKi9cbiAgcHJpdmF0ZSBfcmVjZWl2ZUZpcnN0RnJhbWVIYW5kbGUodHJhY2VJZDogc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMuX2NhbGxFbmdpbmUuZ2V0TG9jYWxNYWluU2Vzc2lvbigpPy5nZXRTdGF0ZSgpICE9PSBSQ0NhbGxQbHVzQ2FsbFN0YXRlLk9OQ0FMTCkge1xuICAgICAgdGhpcy5fY2FsbEVuZ2luZS51cGRhdGVNYWluU2Vzc2lvblN0YXRlKFJDQ2FsbFBsdXNDYWxsU3RhdGUuT05DQUxMKTtcbiAgICB9XG5cbiAgICAvLyDnu5kgQ2FsbFNlcnZlciDkuIrmiqXmtYHliLDovr5cbiAgICB0aGlzLl9jYWxsRW5naW5lLnVwRmlyc3RGcmFtZVRpbWUodHJhY2VJZCk7XG4gIH1cblxuICAvKipcbiAgICog6KKr6Lii5Ye65oi/6Ze05pe277yM6ZyA57uT5p2f6YCa6K+dXG4gICAqL1xuICBwcml2YXRlIF9raWNrb2ZmSGFuZGxlKHN5c3RlbVN0YXRlOiBSQ0NhbGxQbHVzUmVhc29uLCByb29tSWQ6IHN0cmluZywgdHJhY2VJZDogc3RyaW5nKSB7XG4gICAgLyoqXG4gICAgICog5pys56uv572R57uc5pyJ6Zeu6aKY77yMcGluZyDlpLHotKXml7ZcbiAgICAgKi9cbiAgICBpZiAoc3lzdGVtU3RhdGUgPT09IFJDQ2FsbFBsdXNSZWFzb24uQ09OTkVDVElPTl9FUlIpIHtcbiAgICAgIHRoaXMuX2NhbGxFbmdpbmUuZW5kQ3VycmVudFNlc3Npb24oc3lzdGVtU3RhdGUsIHJvb21JZCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOiiq+acjeWKoeerr+i4ouWHuuaXtueahOWkhOeQhlxuICAgICAqL1xuICAgIGNvbnN0IG1haW5TZXNzaW9uID0gdGhpcy5fY2FsbEVuZ2luZS5nZXRMb2NhbE1haW5TZXNzaW9uKCk7XG4gICAgaWYgKG1haW5TZXNzaW9uKSB7XG4gICAgICBjb25zdCBjYWxsSWQgPSBtYWluU2Vzc2lvbi5nZXRDYWxsSWQoKTtcbiAgICAgIHRoaXMuX2NhbGxQbHVzU3RhdGlzdGljcy5yZXBvcnRTdGF0aXN0aWNzRGF0YShSQ0NhbGxQbHVzU3RhdGlzdGljc1RhZy5MX1FTX0FCTk9STUFMX0hBTkdVUF9TLCBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTLCArbmV3IERhdGUoKSwgbWFpblNlc3Npb24sIHRoaXMuX2NsaWVudENhbGxJZCk7XG5cbiAgICAgIC8vIOS4iuaKpeeKtuaAgeebtOaOpeiuqeWvueaWueefpemBk+iHquW3seemu+W8gOeahOWOn+WboFxuICAgICAgdGhpcy5fY2FsbEVuZ2luZS5zeXN0ZW1TdGF0dXNVcCh7XG4gICAgICAgIGNhbGxJZCxcbiAgICAgICAgc3lzU3RhdHVzOiBzeXN0ZW1TdGF0ZSxcbiAgICAgICAgZm9yd2FyZDogRm9yd2FyZFR5cGUuQ1VSUkVOVCxcbiAgICAgIH0sIHRyYWNlSWQpO1xuXG4gICAgICAvLyDnm7TmjqXnu5PmnZ/lt7HmlrnpgJror51cbiAgICAgIHRoaXMuX2NhbGxFbmdpbmUuZW5kQ3VycmVudFNlc3Npb24oc3lzdGVtU3RhdGUsIHJvb21JZCwgdHJhY2VJZCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOi/nOerr+i1hOa6kOmfs+inhumikeeKtuaAgeWPmOWMlu+8jOmcgOabtOaWsCBzZXNzaW9uIOS4reS6uuWRmOeahOiuvuWkh+eKtuaAgVxuICAgKi9cbiAgcHJpdmF0ZSBfcmVjZWl2ZURldmljZUVuYWJsZUNoYW5nZUhhbmRsZSh0cmFja3M6IFJDUmVtb3RlVHJhY2tbXSwgdHJhY2VJZDogc3RyaW5nKSB7XG4gICAgdHJhY2tzLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICBjb25zdCB1c2VySWQgPSB0cmFjay5nZXRVc2VySWQoKTtcbiAgICAgIGNvbnN0IG1lZGlhVHlwZSA9IHRyYWNrLmlzQXVkaW9UcmFjaygpID8gUkNDYWxsUGx1c01lZGlhVHlwZS5BVURJTyA6IFJDQ2FsbFBsdXNNZWRpYVR5cGUuVklERU87XG4gICAgICB0aGlzLl9jYWxsRW5naW5lLnNldFVzZXJEZXZpY2VFbmFibGUodXNlcklkLCBtZWRpYVR5cGUsICF0cmFjay5pc093bmVyTXV0ZWQoKSwgdHJhY2VJZCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICog6YCa6K+d5oyC5pat5pe277yM6ZyA5riF56m65YaF5a2Y77yM56a75byA5oi/6Ze0XG4gICAqL1xuICBwcml2YXRlIF9zZXNzaW9uQ2xvc2VIYW5kbGUoY2FsbElkOiBzdHJpbmcsIHRyYWNlSWQ6IHN0cmluZykge1xuICAgIC8qKlxuICAgICAqIOS7heWcqOiiq+WKqOaMguaWreaXtua4heepuuWIm+W7uueahOWuouaIt+erryBjYWxsSWTvvIxcbiAgICAgKiDkuI3lvbHlk43kuLvliqjlkbzlj6vlkI7mjILmlq3ml7bkuIrmiqUg5a6i5oi356uvIGNhbGxJZFxuICAgICAqL1xuICAgIGlmICghdGhpcy5faXNMYXVuY2hIYW5ndXApIHtcbiAgICAgIHRoaXMuX2NsaWVudENhbGxJZCA9ICcnO1xuICAgIH1cbiAgICB0aGlzLl9pc0xhdW5jaEhhbmd1cCA9IGZhbHNlO1xuICAgIHRoaXMuX3J0Y01vZHVsZS5zZXNzaW9uQ2xvc2UoY2FsbElkLCB0cmFjZUlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDms6jlhozlupTnlKjlsYLkuovku7ZcbiAgICog5YyF5ZCr4oCc5pS25Yiw5ZG85Y+r44CB6YCa6K+d57uT5p2f44CB6YCa6K+d5Lq65ZGY54q25oCB5Y+Y5pu044CB6YCa6K+d57G75Z6L5Y+Y5pu04oCd562J5LqL5Lu2XG4gICAqIElDYWxsUGx1c0V2ZW50TGlzdGVuZXIg5a+56LGh6K+35Y+C6ICDIGFwaURvY1xuICAgKi9cbiAgc2V0Q2FsbFBsdXNFdmVudExpc3RlbmVyKGxpc3RlbmVyOiBJQ2FsbFBsdXNFdmVudExpc3RlbmVyKSB7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9TRVRfRVZFTlRfTElTVEVORVJfTywgbGlzdGVuZXIgPyBPYmplY3Qua2V5cyhsaXN0ZW5lcikuam9pbignLCcpIDogbnVsbCk7XG4gICAgdGhpcy5fcmVwb3J0QXBwRXZlbnRNb2R1bGUucmVnaXN0ZXJFdmVudExpc3RlbmVyKGxpc3RlbmVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDms6jlhozpn7Pop4bpopHkuIrkuIvooYzkuKLljIXmlbDmja7nm5HlkKxcbiAgICog5q+P56eS5LiK5oql5LiA5qyhXG4gICAqIEBwYXJhbSBsaXN0ZW5lciDnsbvlnovkuLogSVN0YXR1c1JlcG9ydExpc3RlbmVy77yM6K+m57uG5a6a5LmJ5Y+v5Y+C6ICDIGFwaURvY1xuICAgKiBAcGFyYW0gbGlzdGVuZXIub25TZW5kUGFja2V0TG9zcyAg5Y+R6YCB5Lii5YyF546H5L+h5oGv5Zue6LCDXG4gICAqIEBwYXJhbSBsaXN0ZW5lci5vblJlY2VpdmVQYWNrZXRMb3NzIOaOpeaUtuS4ouWMheeOh+S/oeaBr+Wbnuiwg1xuICAgKi9cbiAgc2V0U3RhdHVzUmVwb3J0TGlzdGVuZXIobGlzdGVuZXI6IElTdGF0dXNSZXBvcnRMaXN0ZW5lcikge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfU0VUX1NUQVRVU19SRVBPUlRfTElTVEVORVJfTywgbGlzdGVuZXIgPyBPYmplY3Qua2V5cyhsaXN0ZW5lcikuam9pbignLCcpIDogbnVsbCk7XG4gICAgdGhpcy5fcnRjTW9kdWxlLnNldENhbGxQbHVzU3RhdHVzUmVwb3J0TGlzdGVuZXIobGlzdGVuZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIOiuvue9ruimgeingueci+S6uuWRmCjljIXmi6zoh6rlt7Hlkozlr7nmlrkp55qE5aqS5L2T5pKt5pS+5ZmoXG4gICAqIEBwYXJhbSBsaXN0IOS4uuS4gOS4quWIl+ihqO+8jOWPr+S8oOWFpeWkmuS6uueahOWqkuS9k+aSreaUvuWZqFxuICAgKiBAcGFyYW0gaXRlbS51c2VySWQg55So5oi3IGlkXG4gICAqIEBwYXJhbSBpdGVtLnZpZGVvRWxlbWVudCDkuIDkuKogdmlkZW8g5YWD57Sg77yM55So5LqO5pKt5pS+6KeG6aKR77yM6ZyA6KaB5oyC6L295Zyo5Lia5Yqh5bGC6aG16Z2i5LiKXG4gICAqIEBwYXJhbSBpdGVtLmlzVGlueSDmmK/lkKbop4LnnIvliKvkurrnmoTlsI/mtYHvvIzlsI/nqpflj6Pml7blj6/ku6XphY3nva7kuLogdHJ1Ze+8jOWPr+iKguecgeW4puWuve+8jHVzZXJJZCDkuLrov5znq6/nlKjmiLfml7bmnInmlYhcbiAgICogQHJldHVybnMgY29kZSDov5Tlm57mmK/lkKborr7nva7miJDlip9cbiAgICovXG4gIHNldFZpZGVvVmlldyhsaXN0OiB7dXNlcklkOiBzdHJpbmcsIHZpZGVvRWxlbWVudDogSFRNTFZpZGVvRWxlbWVudCwgaXNUaW55PzogYm9vbGVhbn1bXSk6IHsgY29kZTogbnVtYmVyIH0ge1xuICAgIGNvbnN0IHRyYWNlSWQgPSB0aGlzLl9sb2dnZXIuY3JlYXRlVHJhY2VJZCgpO1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfU0VUX1ZJREVPX1ZJRVdfVCwgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgbGlzdDogbGlzdC5tYXAoKGl0ZW0pID0+IHtcbiAgICAgICAgY29uc3QgeyB1c2VySWQsIHZpZGVvRWxlbWVudCwgaXNUaW55IH0gPSBpdGVtO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHVzZXJJZCxcbiAgICAgICAgICBlbGVtZW50TmFtZTogdmlkZW9FbGVtZW50Py5ub2RlTmFtZSxcbiAgICAgICAgICBpc1RpbnksXG4gICAgICAgIH07XG4gICAgICB9KSxcbiAgICB9KSwgdHJhY2VJZCk7XG5cbiAgICAvKipcbiAgICAgKiDlj4LmlbDmo4DmtYtcbiAgICAgKi9cbiAgICBpZiAoIW5vdEVtcHR5QXJyYXkobGlzdCkpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1NFVF9WSURFT19WSUVXX1IsIGBwYXJhbXMgZXJyLCBsaXN0OiBub3QgZW1wdHkgYXJyYXksIHZhbHVlOiAke0pTT04uc3RyaW5naWZ5KGxpc3QpfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuUEFSQU1fRVJST1IgfTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgbGlzdC5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgIGNvbnN0IGl0ZW0gPSBsaXN0W2luZGV4XTtcbiAgICAgIGNvbnN0IHsgdXNlcklkLCB2aWRlb0VsZW1lbnQgfSA9IGl0ZW07XG4gICAgICBpZiAoIW5vdEVtcHR5U3RyaW5nKHVzZXJJZCkpIHtcbiAgICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfU0VUX1ZJREVPX1ZJRVdfUiwgYHBhcmFtcyBlcnIsIHVzZXJJZDogbm90IGVtcHR5IHN0cmluZywgdmFsdWU6ICR7dXNlcklkfWAsIHRyYWNlSWQpO1xuICAgICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5QQVJBTV9FUlJPUiB9O1xuICAgICAgfVxuXG4gICAgICBpZiAoIXZhbGlkYXRlVmlkZW9Ob2RlTmFtZSh2aWRlb0VsZW1lbnQpKSB7XG4gICAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1NFVF9WSURFT19WSUVXX1IsIGBwYXJhbXMgZXJyLCB2aWRlb0VsZW1lbnQ6IG5lZWQgYSB2aWRlbyBlbGVtZW50LCB2YWx1ZTogJHt2aWRlb0VsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCA/IHZpZGVvRWxlbWVudC5ub2RlTmFtZSA6IHZpZGVvRWxlbWVudH1gLCB0cmFjZUlkKTtcbiAgICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuUEFSQU1fRVJST1IgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1NFVF9WSURFT19WSUVXX1IsICdzdWNjZXMnLCB0cmFjZUlkKTtcbiAgICB0aGlzLl9ydGNNb2R1bGUuc2V0VmlkZW9WaWV3KGxpc3QsIHRyYWNlSWQpO1xuICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDliKDpmaTmn5DkuKrkurrnmoTlqpLkvZPmkq3mlL7lmahcbiAgICog5LiN6KeC55yL5p+Q5Liq5Lq655qE6KeG6aKR5pe277yM5Lia5Yqh5bGC5Y+v5Lul55u05o6l56e76Zmk5a+55bqU55qEIHZpZGVvIOagh+etvu+8jFxuICAgKiDosIMgcmVtb3ZlVmlkZW9WaWV3IOaWueazle+8jFNESyDlhoXpg6jkvJrlgZzmraLmjqXmlLblr7nmlrnnmoTlqpLkvZPkvKDovpNcbiAgICogQHBhcmFtIHVzZXJJZHMg55So5oi3IGlkIOWIl+ihqFxuICAgKiBAcmV0dXJucyBjb2RlIOi/lOWbnuaYr+WQpuWIoOmZpOaIkOWKn1xuICAgKi9cbiAgcmVtb3ZlVmlkZW9WaWV3KHVzZXJJZHM6IHN0cmluZ1tdKTogeyBjb2RlOiBudW1iZXIgfSB7XG4gICAgY29uc3QgdHJhY2VJZCA9IHRoaXMuX2xvZ2dlci5jcmVhdGVUcmFjZUlkKCk7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9SRU1PVkVfVklERU9fVklFV19ULCBKU09OLnN0cmluZ2lmeSh7XG4gICAgICB1c2VySWRzLFxuICAgIH0pLCB0cmFjZUlkKTtcblxuICAgIC8qKlxuICAgICAqIOWPguaVsOajgOa1i1xuICAgICAqL1xuICAgIGlmICghKFxuICAgICAgbm90RW1wdHlBcnJheSh1c2VySWRzKVxuICAgICAgJiYgdXNlcklkcy5ldmVyeSgodXNlcklkKSA9PiBub3RFbXB0eVN0cmluZyh1c2VySWQpKVxuICAgICkpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1JFTU9WRV9WSURFT19WSUVXX1IsIGBwYXJhbXMgZXJyLCB1c2VySWRzOiBub3QgZW1wdHkgYXJyYXksIHVzZXJJZDogbm90IGVtcHR5IHN0cmluZywgdmFsdWU6ICR7SlNPTi5zdHJpbmdpZnkodXNlcklkcyl9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5QQVJBTV9FUlJPUiB9O1xuICAgIH1cblxuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfUkVNT1ZFX1ZJREVPX1ZJRVdfUiwgJ3N1Y2NlcycsIHRyYWNlSWQpO1xuXG4gICAgdGhpcy5fcnRjTW9kdWxlLnJlbW92ZVZpZGVvVmlldyh1c2VySWRzLCB0cmFjZUlkKTtcbiAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTIH07XG4gIH1cblxuICAvKipcbiAgICog5pKt5pS+5oyH5a6a5Lq65ZGY55qE6Z+z6KeG6aKR5aqS5L2TXG4gICAqIOaSreaUvuafkOS4quS6uueahOinhumikeWJje+8jOivt+ehruS/neW3sue7j+iwg+eUqCBgc2V0VmlkZW9WaWV3YCDmlrnms5XkuLrlhbborr7nva7op4bpopHop4blm75cbiAgICogQHBhcmFtIHVzZXJJZCDmjIflrpropoHmn6XnnIvmn5DkuKrkurrnmoTlqpLkvZPotYTmupBcbiAgICogQHBhcmFtIG1lZGlhVHlwZSDmjIflrprmkq3mlL7pn7PpopHov5jmmK/op4bpopFcbiAgICogQHJldHVybnMg6L+U5Zue5piv5ZCm5pKt5pS+5oiQ5YqfXG4gICAqL1xuICBhc3luYyBwbGF5TWVkaWEodXNlcklkOiBzdHJpbmcsIG1lZGlhVHlwZTogUkNDYWxsUGx1c01lZGlhVHlwZSk6IFByb21pc2U8eyBjb2RlOiBudW1iZXIgfT4ge1xuICAgIGNvbnN0IHRyYWNlSWQgPSB0aGlzLl9sb2dnZXIuY3JlYXRlVHJhY2VJZCgpO1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfUExBWV9NRURJQV9ULCBKU09OLnN0cmluZ2lmeSh7XG4gICAgICB1c2VySWQsXG4gICAgICBtZWRpYVR5cGUsXG4gICAgfSksIHRyYWNlSWQpO1xuXG4gICAgLyoqXG4gICAgICog5Y+C5pWw5qCh6aqMXG4gICAgICovXG4gICAgaWYgKCFub3RFbXB0eVN0cmluZyh1c2VySWQpKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9QTEFZX01FRElBX1IsIGBwYXJhbXMgZXJyLCB1c2VySWQ6IG5vdCBlbXB0eSBzdHJpbmcsIHZhbHVlOiAke3VzZXJJZH1gLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlBBUkFNX0VSUk9SIH07XG4gICAgfVxuXG4gICAgaWYgKGlzVW5kZWZpbmVkKFJDQ2FsbFBsdXNNZWRpYVR5cGVbbWVkaWFUeXBlXSkpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1BMQVlfTUVESUFfUiwgYHBhcmFtcyBlcnIsIG1lZGlhVHlwZSBpcyBpbGxlZ2FsLCB2YWx1ZTogJHttZWRpYVR5cGV9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5QQVJBTV9FUlJPUiB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIOWIpOaWreS4muWKoeWxguaYr+WQpuiuvue9rui/h+W9k+WJjeS6uuWRmOeahOinhumikeinhuWbvlxuICAgICAqL1xuICAgIGNvbnN0IHsgdmlkZW9WaWV3IH0gPSB0aGlzLl9ydGNNb2R1bGUuZ2V0VXNlclZpZXdNYXAoKVt1c2VySWRdIHx8IHt9O1xuICAgIGlmIChtZWRpYVR5cGUgIT09IFJDQ2FsbFBsdXNNZWRpYVR5cGUuQVVESU8gJiYgIXZpZGVvVmlldykge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfUExBWV9NRURJQV9SLCBgZXJyQ29kZTogJHtSQ0NhbGxQbHVzQ29kZS5WSURFT19WSUVXX05PVF9TRVR9LCB2aWRlbyB2aWV3IG5vdCBzZXRgLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlZJREVPX1ZJRVdfTk9UX1NFVCB9O1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9ydGNNb2R1bGUucGxheU1lZGlhKHVzZXJJZCwgbWVkaWFUeXBlLCB2aWRlb1ZpZXcsIHRyYWNlSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIOWIm+W7uuinhumikemFjee9ruaehOW7uuWZqFxuICAgKiBAcmV0dXJucyBSQ1ZpZGVvQ29uZmlnQnVpbGRlciDnlKjkuo7mnoTpgKDop4bpopHph4fpm4bml7bnmoTphY3nva7pobnvvIzlj6/ku6Xorr7nva7mkYTlg4/lpLTorr7lpIcgaWTjgIHluKfnjofjgIHliIbovqjnjofnrYnvvIxcbiAgICog6K6+572u5a6M6ZyA6LCDIGJ1aWxkIOaWueazle+8jOacgOe7iOWcqCBzZXRWaWRlb0NvbmZpZyDlkI7nlJ/mlYhcbiAgICovXG4gIGNyZWF0ZVZpZGVvQ29uZmlnQnVpbGRlcigpOiBSQ1ZpZGVvQ29uZmlnQnVpbGRlciB7XG4gICAgcmV0dXJuIG5ldyBSQ1ZpZGVvQ29uZmlnQnVpbGRlcih0aGlzLl9sb2dnZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIOiuvue9ruinhumikemFjee9rlxuICAgKiDkuIvmrKHph4fpm4bml7bnlJ/mlYjvvIzlpoLliIfmjaLmkYTlg4/lpLTjgIHph43mlrDlu7rnq4vpgJror51cbiAgICovXG4gIHNldFZpZGVvQ29uZmlnKGNmZzogSVZpZGVvQ29uZmlnKTogeyBjb2RlOiBudW1iZXIgfSB7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9TRVRfVklERU9fQ09ORklHX1QsIEpTT04uc3RyaW5naWZ5KGNmZykpO1xuXG4gICAgY29uc3Qge1xuICAgICAgZnJhbWVSYXRlLCByZXNvbHV0aW9uLCBtYXhCaXRyYXRlLCBtaW5CaXRyYXRlLFxuICAgIH0gPSBjZmc7XG5cbiAgICBpZiAoIVJDQ2FsbFBsdXNGcmFtZVJhdGVbZnJhbWVSYXRlXSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfU0VUX1ZJREVPX0NPTkZJR19SLCBgcGFyYW0gZXJyb3IsIGZyYW1lUmF0ZSBpcyBpbGxlZ2FsLCB2YWx1ZTogJHtmcmFtZVJhdGV9YCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5QQVJBTV9FUlJPUiB9O1xuICAgIH1cblxuICAgIGlmICghUkNDYWxsUGx1c1Jlc29sdXRpb25bcmVzb2x1dGlvbl0pIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1NFVF9WSURFT19DT05GSUdfUiwgYHBhcmFtIGVycm9yLCByZXNvbHV0aW9uIGlzIGlsbGVnYWwsIHZhbHVlOiAke3Jlc29sdXRpb259YCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5QQVJBTV9FUlJPUiB9O1xuICAgIH1cblxuICAgIGNvbnN0IHsgY29kZSwgZXJyb3JNc2cgfSA9IHZhbGlkYXRlQml0cmF0ZShtaW5CaXRyYXRlLCBtYXhCaXRyYXRlKTtcbiAgICBpZiAoY29kZSAhPT0gUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUykge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfU0VUX1ZJREVPX0NPTkZJR19SLCBlcnJvck1zZyk7XG4gICAgfVxuXG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9TRVRfVklERU9fQ09ORklHX1IsICdzdWNjZXNzJyk7XG4gICAgdGhpcy5fdmlkZW9Db25maWcgPSB7IC4uLmNmZyB9O1xuICAgIHRoaXMuX3J0Y01vZHVsZS5zZXRWaWRlb0NvbmZpZyh0aGlzLl92aWRlb0NvbmZpZyk7XG4gICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOWIm+W7uumfs+mikemFjee9ruaehOW7uuWZqFxuICAgKiBAcmV0dXJucyBSQ0F1ZGlvQ29uZmlnQnVpbGRlciDnlKjkuo7mnoTpgKDpn7PpopHph4fpm4bml7bnmoTphY3nva7pobnvvIzlj6/ku6Xorr7nva7puqblhYvpo47orr7lpIcgaWRcbiAgICog6K6+572u5a6M6ZyA6LCDIGJ1aWxkIOaWueazle+8jOacgOe7iOWcqCBzZXRBdWRpb0NvbmZpZyDlkI7nlJ/mlYhcbiAgICovXG4gIGNyZWF0ZUF1ZGlvQ29uZmlnQnVpbGRlcigpOiBSQ0F1ZGlvQ29uZmlnQnVpbGRlciB7XG4gICAgcmV0dXJuIG5ldyBSQ0F1ZGlvQ29uZmlnQnVpbGRlcih0aGlzLl9sb2dnZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIOiuvue9rumfs+mikemFjee9rlxuICAgKiDkuIvmrKHph4fpm4bml7bnlJ/mlYjvvIzlpoLph43mlrDlu7rnq4vpgJror51cbiAgICovXG4gIHNldEF1ZGlvQ29uZmlnKGNmZzogSUF1ZGlvQ29uZmlnKTogeyBjb2RlOiBudW1iZXIgfSB7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9TRVRfQVVESU9fQ09ORklHX1QsIEpTT04uc3RyaW5naWZ5KGNmZykpO1xuICAgIGNvbnN0IHsgc2FtcGxlUmF0ZSwgbWluQml0cmF0ZSwgbWF4Qml0cmF0ZSB9ID0gY2ZnO1xuICAgIGlmIChzYW1wbGVSYXRlICYmICFpc051bWJlcihzYW1wbGVSYXRlKSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfU0VUX0FVRElPX0NPTkZJR19SLCBgcGFyYW0gZXJyb3IsIHNhbXBsZVJhdGU6IHR5cGUgaXMgbnVtYmVyLCB2YWx1ZTogJHtzYW1wbGVSYXRlfWApO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuUEFSQU1fRVJST1IgfTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGNvZGUsIGVycm9yTXNnIH0gPSB2YWxpZGF0ZUJpdHJhdGUobWluQml0cmF0ZSwgbWF4Qml0cmF0ZSk7XG4gICAgaWYgKGNvZGUgIT09IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1NFVF9BVURJT19DT05GSUdfUiwgZXJyb3JNc2cpO1xuICAgIH1cblxuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfU0VUX0FVRElPX0NPTkZJR19SLCAnc3VjY2VzcycpO1xuXG4gICAgdGhpcy5fYXVkaW9Db25maWcgPSB7IC4uLmNmZyB9O1xuICAgIHRoaXMuX3J0Y01vZHVsZS5zZXRBdWRpb0NvbmZpZyh0aGlzLl9hdWRpb0NvbmZpZyk7XG4gICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOWPkei1t+WRvOWPq1xuICAgKiBAcGFyYW0gdXNlcklkcyDooqvlj6vkurrlkZggdXNlcklkIOWIl+ihqO+8jOWNleS6uuWRvOWPq+S7hemcgOWcqOaVsOe7hOS4reaUvue9ruWvueaWueS4gOS6uueahCB1c2VySWRcbiAgICogQHBhcmFtIHR5cGUg5Y2V5Lq65ZG85Y+rIG9yIOWkmuS6uuWRvOWPq1xuICAgKiBAcGFyYW0gbWVkaWFUeXBlIOmAmuivneWqkuS9k+exu+Weizog6Z+z6aKRIG9yIOmfs+inhumikVxuICAgKiBAcmV0dXJucyBjYWxsSWQg5ZG85Y+r5oiQ5Yqf5ZCO77yM5Lqn55Sf55qE5Lya6K+dIGlkXG4gICAqL1xuICBhc3luYyBzdGFydENhbGwodXNlcklkczogc3RyaW5nW10sIGNhbGxUeXBlOiBSQ0NhbGxQbHVzVHlwZSA9IFJDQ2FsbFBsdXNUeXBlLlNJTkdMRSwgbWVkaWFUeXBlOiBSQ0NhbGxQbHVzTWVkaWFUeXBlID0gUkNDYWxsUGx1c01lZGlhVHlwZS5BVURJT19WSURFTyk6IFByb21pc2U8eyBjb2RlOiBudW1iZXIsIGNhbGxJZD86IHN0cmluZyB9PiB7XG4gICAgdGhpcy5fY2xpZW50Q2FsbElkID0gZ2V0VVVJRCgpO1xuICAgIGNvbnN0IHN0YXJ0VGltZSA9ICtuZXcgRGF0ZSgpO1xuICAgIGNvbnN0IHRyYWNlSWQgPSB0aGlzLl9sb2dnZXIuY3JlYXRlVHJhY2VJZCgpO1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfU1RBUlRfQ0FMTF9ULCBgdXNlcklkczogJHt1c2VySWRzLmpvaW4oJywnKX0sIGNhbGxUeXBlOiAke2NhbGxUeXBlfSwgbWVkaWFUeXBlOiAke21lZGlhVHlwZX1gLCB0cmFjZUlkKTtcblxuICAgIGlmICh0aGlzLl9jb250ZXh0LmdldENvbm5lY3Rpb25TdGF0dXMoKSAhPT0gUkNDb25uZWN0aW9uU3RhdHVzLkNPTk5FQ1RFRCkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfU1RBUlRfQ0FMTF9SLCBgZXJyQ29kZTogJHtSQ0NhbGxQbHVzQ29kZS5TSUdOQUxfRElTQ09OTkVDVEVEfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU0lHTkFMX0RJU0NPTk5FQ1RFRCB9O1xuICAgIH1cblxuICAgIGNvbnN0IG5hdmlJbmZvID0gdGhpcy5fY29udGV4dC5nZXROYXZpSW5mbygpO1xuICAgIGlmICghbmF2aUluZm8gfHwgIWlzU3VwcG9ydE1lZGlhU2VydmVyKG5hdmlJbmZvKSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfU1RBUlRfQ0FMTF9SLCBgZXJyQ29kZTogJHtSQ0NhbGxQbHVzQ29kZS5SVENfU0VSVklDRV9VTkFWQUlMQUJMRX1gLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlJUQ19TRVJWSUNFX1VOQVZBSUxBQkxFIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog5Y+C5pWw5qCh6aqMXG4gICAgICovXG4gICAgaWYgKCEoXG4gICAgICBub3RFbXB0eUFycmF5KHVzZXJJZHMpXG4gICAgICAmJiB1c2VySWRzLmV2ZXJ5KCh1c2VySWQpID0+IG5vdEVtcHR5U3RyaW5nKHVzZXJJZCkpXG4gICAgKSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfU1RBUlRfQ0FMTF9SLCBgcGFyYW1zIGVyciwgdXNlcklkczogbm90IGVtcHR5IGFycmF5LCB1c2VySWQ6IG5vdCBlbXB0eSBzdHJpbmcsIHZhbHVlOiAke0pTT04uc3RyaW5naWZ5KHVzZXJJZHMpfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuUEFSQU1fRVJST1IgfTtcbiAgICB9XG5cbiAgICBpZiAoaXNVbmRlZmluZWQoUkNDYWxsUGx1c1R5cGVbY2FsbFR5cGVdKSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfU1RBUlRfQ0FMTF9SLCBgcGFyYW1zIGVyciwgY2FsbFR5cGUgaXMgaWxsZWdhbCwgdmFsdWU6ICR7Y2FsbFR5cGV9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5QQVJBTV9FUlJPUiB9O1xuICAgIH1cblxuICAgIGlmIChpc1VuZGVmaW5lZChSQ0NhbGxQbHVzTWVkaWFUeXBlW21lZGlhVHlwZV0pKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9TVEFSVF9DQUxMX1IsIGBwYXJhbXMgZXJyLCBtZWRpYVR5cGUgaXMgaWxsZWdhbCwgdmFsdWU6ICR7bWVkaWFUeXBlfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuUEFSQU1fRVJST1IgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDljZXogYogdXNlcklkcyDplb/luqbkuI3og73otoXov4cgMVxuICAgICAqL1xuICAgIGlmICh1c2VySWRzLmxlbmd0aCA+IDEgJiYgY2FsbFR5cGUgPT09IFJDQ2FsbFBsdXNUeXBlLlNJTkdMRSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfU1RBUlRfQ0FMTF9SLCBgcGFyYW1zIGVyciwgWW91IGNhbiBvbmx5IGNhbGwgb25lIHBlcnNvbiBpbiBhIHNpbmdsZSBjYWxsLCB1c2VySWRzOiAke3VzZXJJZHMuam9pbignLCcpfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuUEFSQU1fRVJST1IgfTtcbiAgICB9XG5cbiAgICAvLyDlt7LlrZjlnKggc2Vzc2lvbiDkuI3lhYHorrjlho3lj5Hotbflkbzlj6tcbiAgICBpZiAodGhpcy5fY2FsbEVuZ2luZS5nZXRMb2NhbE1haW5TZXNzaW9uKCkpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1NUQVJUX0NBTExfUiwgYGVyckNvZGU6ICR7UkNDYWxsUGx1c0NvZGUuU0VTU0lPTl9FWElTVH0sIHNlc3Npb24gZXhpc3RgLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlNFU1NJT05fRVhJU1QgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDpn7Pop4bpopHpgJror53vvIzpnIDmj5DliY3ph4fpm4bpn7Pop4bpopHotYTmupBcbiAgICAgKi9cbiAgICBjb25zdCB7IGNvZGU6IGdldE1lZGlhVHJhY2tzQ29kZSB9ID0gYXdhaXQgdGhpcy5fcnRjTW9kdWxlLmNyZWF0ZUNhbGxNZWRpYVRyYWNrcyhtZWRpYVR5cGUsIHRyYWNlSWQpO1xuICAgIGlmIChnZXRNZWRpYVRyYWNrc0NvZGUgIT09IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1NUQVJUX0NBTExfUiwgYGNyZWF0ZSBtZWlkYSB0cmFja3MgZXJyb3IgY29kZTogJHtnZXRNZWRpYVRyYWNrc0NvZGV9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBnZXRNZWRpYVRyYWNrc0NvZGUgfTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGNvZGUsIGRhdGEgfSA9IGF3YWl0IHRoaXMuX2NhbGxFbmdpbmUuc3RhcnRDYWxsKHtcbiAgICAgIHRvVXNlcnM6IHVzZXJJZHMubWFwKCh1c2VySWQpID0+ICh7IHVzZXJJZCB9KSksXG4gICAgICBjYWxsVHlwZSxcbiAgICAgIG1lZGlhVHlwZSxcbiAgICAgIGNhbGxJZDogdGhpcy5fY2xpZW50Q2FsbElkLFxuICAgIH0sIHRyYWNlSWQpO1xuXG4gICAgdGhpcy5fY2FsbFBsdXNTdGF0aXN0aWNzLnJlcG9ydFN0YXRpc3RpY3NEYXRhKFJDQ2FsbFBsdXNTdGF0aXN0aWNzVGFnLkxfUVNfU1RBUlRfQ0FMTF9TLCBjb2RlLCBzdGFydFRpbWUsIG51bGwsIHRoaXMuX2NsaWVudENhbGxJZCwgbnVsbCwgeyBtZWRpYVR5cGUsIGNhbGxUeXBlLCBjYWxsSWQ6IGRhdGE/LmNhbGxJZCB8fCAnJyB9KTtcblxuICAgIGlmIChjb2RlICE9PSBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0aGlzLl9ydGNNb2R1bGUuZGVzdHJveUFsbFRyYWNrcyh0cmFjZUlkKTtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1NUQVJUX0NBTExfUiwgYHNpZ25hbCBlcnJvciBjb2RlOiAke2NvZGV9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog5ZG85Y+r6L+H56iL5Lit5oyC5patXG4gICAgICovXG4gICAgY29uc3QgeyBjYWxsSWQsIGNsaWVudENhbGxJZCB9ID0gZGF0YSE7XG4gICAgaWYgKHRoaXMuX25lZWRIYW5ndXBDYWxsSWQgPT09IGNsaWVudENhbGxJZCkge1xuICAgICAgdGhpcy5fY2FsbEVuZ2luZS5jbGVhckFsbFRpbWVyKGNhbGxJZCwgdHJhY2VJZCk7XG4gICAgICB0aGlzLl9jYWxsRW5naW5lLmhhbmd1cCh7IGNhbGxJZCB9LCB0cmFjZUlkKTtcbiAgICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfU1RBUlRfQ0FMTF9SLCBgdGhlICR7Y2FsbElkfSBjYWxsIGhhcyBiZWVuIGhhbmd1cGAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyB9O1xuICAgIH1cblxuICAgIGlmIChjYWxsVHlwZSA9PT0gUkNDYWxsUGx1c1R5cGUuTVVMVEkpIHtcbiAgICAgIGF3YWl0IHRoaXMuX3J0Y01vZHVsZS5zZXNzaW9uQ29ubmVjdGVkKGNhbGxJZCwgdHJhY2VJZCk7XG4gICAgfVxuXG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9TVEFSVF9DQUxMX1IsIEpTT04uc3RyaW5naWZ5KHsgZGF0YSwgY29kZSB9KSwgdHJhY2VJZCk7XG4gICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUywgY2FsbElkIH07XG4gIH1cblxuICAvKipcbiAgICog55u05o6l5Yqg5YWl6L+b6KGM5Lit55qE576k57uE6YCa6K+dXG4gICAqIEBwYXJhbSBjYWxsSWQg6YCa6K+dIGlkXG4gICAqL1xuICBhc3luYyBqb2luTXVsdGlDYWxsKGNhbGxJZDogc3RyaW5nKTogUHJvbWlzZTx7IGNvZGU6IG51bWJlciB9PiB7XG4gICAgY29uc3QgdHJhY2VJZCA9IHRoaXMuX2xvZ2dlci5jcmVhdGVUcmFjZUlkKCk7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9KT0lOX01VTFRJX0NBTExfVCwgYGNhbGxJZDogJHtjYWxsSWR9YCwgdHJhY2VJZCk7XG5cbiAgICBpZiAodGhpcy5fY29udGV4dC5nZXRDb25uZWN0aW9uU3RhdHVzKCkgIT09IFJDQ29ubmVjdGlvblN0YXR1cy5DT05ORUNURUQpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0pPSU5fTVVMVElfQ0FMTF9SLCBgY29kZTogJHtSQ0NhbGxQbHVzQ29kZS5TSUdOQUxfRElTQ09OTkVDVEVEfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU0lHTkFMX0RJU0NPTk5FQ1RFRCB9O1xuICAgIH1cblxuICAgIGNvbnN0IG5hdmlJbmZvID0gdGhpcy5fY29udGV4dC5nZXROYXZpSW5mbygpO1xuICAgIGlmICghbmF2aUluZm8gfHwgIWlzU3VwcG9ydE1lZGlhU2VydmVyKG5hdmlJbmZvKSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfSk9JTl9NVUxUSV9DQUxMX1IsIGBjb2RlOiAke1JDQ2FsbFBsdXNDb2RlLlJUQ19TRVJWSUNFX1VOQVZBSUxBQkxFfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuUlRDX1NFUlZJQ0VfVU5BVkFJTEFCTEUgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDlj4LmlbDmoKHpqoxcbiAgICAgKi9cbiAgICBpZiAoIW5vdEVtcHR5U3RyaW5nKGNhbGxJZCkpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0pPSU5fTVVMVElfQ0FMTF9SLCBgcGFyYW1zIGVyciwgY2FsbElkOiBub3QgZW1wdHkgc3RyaW5nLCB2YWx1ZTogJHtjYWxsSWR9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5QQVJBTV9FUlJPUiB9O1xuICAgIH1cblxuICAgIGNvbnN0IHsgY29kZTogZ2V0U2Vzc2lvbkNvZGUsIGRhdGEgfSA9IGF3YWl0IHRoaXMuX2NhbGxFbmdpbmUuZ2V0Q2FsbFNlc3Npb24oeyBjYWxsSWQgfSwgdHJhY2VJZCk7XG4gICAgaWYgKGdldFNlc3Npb25Db2RlICE9PSBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9KT0lOX01VTFRJX0NBTExfUiwgYGdldCBjYWxsIGRhdGEgZXJyb3IsIGNvZGU6ICR7Z2V0U2Vzc2lvbkNvZGV9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBnZXRTZXNzaW9uQ29kZSB9O1xuICAgIH1cblxuICAgIGNvbnN0IHsgbWVkaWFUeXBlIH0gPSBkYXRhITtcblxuICAgIGNvbnN0IG1haW5TZXNzaW9uID0gdGhpcy5fY2FsbEVuZ2luZS5nZXRMb2NhbE1haW5TZXNzaW9uKCk7XG4gICAgaWYgKG1haW5TZXNzaW9uICYmIG1haW5TZXNzaW9uLmdldENhbGxJZCgpICE9PSBjYWxsSWQpIHtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlNFU1NJT05fRVhJU1QgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDpn7Pop4bpopHpgJror53vvIzpnIDmj5DliY3ph4fpm4bpn7Pop4bpopHotYTmupBcbiAgICAgKi9cbiAgICBjb25zdCB7IGNvZGU6IGdldE1lZGlhVHJhY2tzQ29kZSB9ID0gYXdhaXQgdGhpcy5fcnRjTW9kdWxlLmNyZWF0ZUNhbGxNZWRpYVRyYWNrcyhtZWRpYVR5cGUsIHRyYWNlSWQpO1xuICAgIGlmIChnZXRNZWRpYVRyYWNrc0NvZGUgIT09IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0pPSU5fTVVMVElfQ0FMTF9SLCBgY3JlYXRlIG1laWRhIHRyYWNrcyBlcnJvciBjb2RlOiAke2dldE1lZGlhVHJhY2tzQ29kZX1gLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IGdldE1lZGlhVHJhY2tzQ29kZSB9O1xuICAgIH1cblxuICAgIGNvbnN0IHsgY29kZSB9ID0gYXdhaXQgdGhpcy5fY2FsbEVuZ2luZS5qb2luQ2FsbCh7XG4gICAgICBjYWxsSWQsXG4gICAgICBtZWRpYVR5cGUsXG4gICAgfSwgdHJhY2VJZCk7XG4gICAgaWYgKGNvZGUgIT09IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHRoaXMuX3J0Y01vZHVsZS5kZXN0cm95QWxsVHJhY2tzKHRyYWNlSWQpO1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfSk9JTl9NVUxUSV9DQUxMX1IsIGBzaWduYWwgZXJyb3IgY29kZTogJHtjb2RlfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZSB9O1xuICAgIH1cblxuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfSk9JTl9NVUxUSV9DQUxMX1IsIGBjb2RlOiAke1JDQ2FsbFBsdXNDb2RlLlNVQ0NFU1N9YCwgdHJhY2VJZCk7XG4gICAgYXdhaXQgdGhpcy5fcnRjTW9kdWxlLnNlc3Npb25Db25uZWN0ZWQoY2FsbElkLCB0cmFjZUlkKTtcbiAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTIH07XG4gIH1cblxuICAvKipcbiAgICog6YCa6K+d5Lit6YKA6K+35LuW5Lq6XG4gICAqIOWNleS6uumAmuivneS4remCgOivt+S7luS6uuS8muW8leWPkemAmuivneexu+Wei+WPmOabtFxuICAgKiBAcGFyYW0gdXNlcklkcyDooqvpgoDor7fkurrliJfooahcbiAgICogQHJldHVybnMgYnVzeVVzZXJzIOi/lOWbnuW/mee6v+S6uuWRmOWIl+ihqFxuICAgKi9cbiAgYXN5bmMgaW52aXRlKHVzZXJJZHM6IHN0cmluZ1tdKTogUHJvbWlzZTx7IGNvZGU6IG51bWJlciwgYnVzeVVzZXJzPzogUkNDYWxsUGx1c0NhbGxVc2VyW10gfT4ge1xuICAgIGNvbnN0IHRyYWNlSWQgPSB0aGlzLl9sb2dnZXIuY3JlYXRlVHJhY2VJZCgpO1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfSU5WSVRFX1QsIGBjYWxsSWQ6ICR7dXNlcklkcy5qb2luKCcsJyl9YCwgdHJhY2VJZCk7XG5cbiAgICAvKipcbiAgICAgKiDlj4LmlbDmoKHpqoxcbiAgICAgKi9cbiAgICBpZiAoIShcbiAgICAgIG5vdEVtcHR5QXJyYXkodXNlcklkcylcbiAgICAgICYmIHVzZXJJZHMuZXZlcnkoKHVzZXJJZCkgPT4gbm90RW1wdHlTdHJpbmcodXNlcklkKSlcbiAgICApKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9JTlZJVEVfUiwgYHBhcmFtcyBlcnIsIHVzZXJJZHM6IG5vdCBlbXB0eSBhcnJheSwgdXNlcklkOiBub3QgZW1wdHkgc3RyaW5nLCB2YWx1ZTogJHtKU09OLnN0cmluZ2lmeSh1c2VySWRzKX1gLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlBBUkFNX0VSUk9SIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog5Y+R6LW36YKA6K+3XG4gICAgICovXG4gICAgY29uc3QgeyBjb2RlLCBkYXRhIH0gPSBhd2FpdCB0aGlzLl9jYWxsRW5naW5lLmludml0ZSh7XG4gICAgICB0b1VzZXJzOiB1c2VySWRzLm1hcCgodXNlcklkKSA9PiAoe1xuICAgICAgICB1c2VySWQsXG4gICAgICB9KSksXG4gICAgfSwgdHJhY2VJZCk7XG5cbiAgICBpZiAoY29kZSAhPT0gUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUykge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfSU5WSVRFX1IsIGBzaWduYWwgZXJyb3IgY29kZTogJHtjb2RlfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZSB9O1xuICAgIH1cblxuICAgIGNvbnN0IGJ1c3lVc2VycyA9IFtdO1xuICAgIGlmIChkYXRhIS5idXN5bGluZVVzZXJzPy5sZW5ndGgpIHtcbiAgICAgIGJ1c3lVc2Vycy5wdXNoKC4uLmRhdGEhLmJ1c3lsaW5lVXNlcnMubWFwKCh1c2VyKSA9PiAoe1xuICAgICAgICB1c2VySWQ6IHVzZXIudXNlcklkLFxuICAgICAgICBzdGF0ZTogdXNlci5zZXNzaW9uU3RhdHVzLFxuICAgICAgfSkpKTtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0lOVklURV9SLCBgc3VjY2VzcyBidXN5VXNlcnM6ICR7SlNPTi5zdHJpbmdpZnkoYnVzeVVzZXJzKX1gLCB0cmFjZUlkKTtcbiAgICByZXR1cm4ge1xuICAgICAgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyxcbiAgICAgIGJ1c3lVc2VycyxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOaOpeWQrOmAmuivnVxuICAgKiBAcGFyYW0gY2FsbElkIOmAmuivnSBpZFxuICAgKi9cbiAgYXN5bmMgYWNjZXB0KGNhbGxJZDogc3RyaW5nKTogUHJvbWlzZTx7IGNvZGU6IG51bWJlciB9PiB7XG4gICAgY29uc3Qgc3RhcnRUaW1lID0gK25ldyBEYXRlKCk7XG4gICAgY29uc3QgdHJhY2VJZCA9IHRoaXMuX2xvZ2dlci5jcmVhdGVUcmFjZUlkKCk7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9BQ0NFUFRfVCwgYGNhbGxJZDogJHtjYWxsSWR9YCwgdHJhY2VJZCk7XG5cbiAgICBpZiAodGhpcy5fY29udGV4dC5nZXRDb25uZWN0aW9uU3RhdHVzKCkgIT09IFJDQ29ubmVjdGlvblN0YXR1cy5DT05ORUNURUQpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0FDQ0VQVF9SLCBgZXJyQ29kZTogJHtSQ0NhbGxQbHVzQ29kZS5TSUdOQUxfRElTQ09OTkVDVEVEfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU0lHTkFMX0RJU0NPTk5FQ1RFRCB9O1xuICAgIH1cblxuICAgIGNvbnN0IG5hdmlJbmZvID0gdGhpcy5fY29udGV4dC5nZXROYXZpSW5mbygpO1xuICAgIGlmICghbmF2aUluZm8gfHwgIWlzU3VwcG9ydE1lZGlhU2VydmVyKG5hdmlJbmZvKSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfQUNDRVBUX1IsIGBlcnJDb2RlOiAke1JDQ2FsbFBsdXNDb2RlLlJUQ19TRVJWSUNFX1VOQVZBSUxBQkxFfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuUlRDX1NFUlZJQ0VfVU5BVkFJTEFCTEUgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDlj4LmlbDmoKHpqoxcbiAgICAgKi9cbiAgICBpZiAoIW5vdEVtcHR5U3RyaW5nKGNhbGxJZCkpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0FDQ0VQVF9SLCBgcGFyYW1zIGVyciwgY2FsbElkOiBub3QgZW1wdHkgc3RyaW5nLCB2YWx1ZTogJHtjYWxsSWR9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5QQVJBTV9FUlJPUiB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIOaYr+WQpuWtmOWcqOmAmuivnVxuICAgICAqIOmcgOS7juW9k+WJjemAmuivneiOt+WPliBtZWlkYVR5cGVcbiAgICAgKi9cbiAgICBjb25zdCBtYWluU2Vzc2lvbiA9IHRoaXMuX2NhbGxFbmdpbmUuZ2V0TG9jYWxNYWluU2Vzc2lvbigpO1xuICAgIGNvbnN0IGhvbGRTZXNzaW9uID0gdGhpcy5fY2FsbEVuZ2luZS5nZXRIb2xkU2Vzc2lvbihjYWxsSWQpO1xuICAgIGlmICghbWFpblNlc3Npb24gJiYgIWhvbGRTZXNzaW9uKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9BQ0NFUFRfUiwgYGVyckNvZGUgOiAke1JDQ2FsbFBsdXNDb2RlLk5PVF9JTl9DQUxMfSwgc2Vzc2lvbiBub3QgZXhpc3RgLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLk5PVF9JTl9DQUxMIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog5Yy65YiG5o6l5ZCsIG1haW5TZXNzaW9uIOWSjCBob2xkU2Vzc2lvblxuICAgICAqIOWmguaenOaOpeWQrCBob2xkU2Vzc2lvbu+8jOmcgOWFiOaMguaWrSBtYWluU2Vzc2lvblxuICAgICAqL1xuICAgIGNvbnN0IGlzQWNjZXB0SG9sZFNlc3Npb24gPSBjYWxsSWQgPT09IGhvbGRTZXNzaW9uPy5nZXRDYWxsSWQoKTtcbiAgICBpZiAoaXNBY2NlcHRIb2xkU2Vzc2lvbikge1xuICAgICAgY29uc3QgeyBjb2RlOiBoYW5ndXBNYWluU2Vzc2lvbkNvZGUgfSA9IGF3YWl0IHRoaXMuaGFuZ3VwKG1haW5TZXNzaW9uIS5nZXRDYWxsSWQoKSk7XG4gICAgICBpZiAoaGFuZ3VwTWFpblNlc3Npb25Db2RlICE9PSBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTKSB7XG4gICAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0FDQ0VQVF9SLCBgaGFuZ3VwIG1haW5TZXNzaW9uIGVycm9yIGNvZGU6ICR7aGFuZ3VwTWFpblNlc3Npb25Db2RlfWAsIHRyYWNlSWQpO1xuICAgICAgICByZXR1cm4geyBjb2RlOiBoYW5ndXBNYWluU2Vzc2lvbkNvZGUgfTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2NhbGxFbmdpbmUudXBncmFkZU1haW5TZXNzaW9uKGNhbGxJZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog6Z+z6KeG6aKR6YCa6K+d77yM6ZyA5o+Q5YmN6YeH6ZuG6Z+z6KeG6aKR6LWE5rqQXG4gICAgICovXG4gICAgY29uc3QgbWVkaWFUeXBlID0gbWFpblNlc3Npb24hLmdldE1lZGlhVHlwZSgpO1xuICAgIGNvbnN0IHsgY29kZTogZ2V0TWVkaWFUcmFja3NDb2RlIH0gPSBhd2FpdCB0aGlzLl9ydGNNb2R1bGUuY3JlYXRlQ2FsbE1lZGlhVHJhY2tzKG1lZGlhVHlwZSwgdHJhY2VJZCk7XG4gICAgaWYgKGdldE1lZGlhVHJhY2tzQ29kZSAhPT0gUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUykge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfQUNDRVBUX1IsIGBjcmVhdGUgbWVpZGEgdHJhY2tzIGVycm9yIGNvZGU6ICR7Z2V0TWVkaWFUcmFja3NDb2RlfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZTogZ2V0TWVkaWFUcmFja3NDb2RlIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog5Y+R6LW35o6l5ZCsXG4gICAgICovXG4gICAgY29uc3QgeyBjb2RlIH0gPSBhd2FpdCB0aGlzLl9jYWxsRW5naW5lLmFjY2VwdCh7IGNhbGxJZCB9LCB0cmFjZUlkKTtcblxuICAgIHRoaXMuX2NhbGxQbHVzU3RhdGlzdGljcy5yZXBvcnRTdGF0aXN0aWNzRGF0YShSQ0NhbGxQbHVzU3RhdGlzdGljc1RhZy5MX1FTX0FDQ0VQVF9DQUxMX1MsIGNvZGUsIHN0YXJ0VGltZSwgbWFpblNlc3Npb24hKTtcblxuICAgIGlmIChjb2RlICE9PSBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0aGlzLl9ydGNNb2R1bGUuZGVzdHJveUFsbFRyYWNrcyh0cmFjZUlkKTtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0FDQ0VQVF9SLCBgc2lnbmFsIGVycm9yIGNvZGU6ICR7Y29kZX1gLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0FDQ0VQVF9SLCAnc3VjY2VzcycsIHRyYWNlSWQpO1xuICAgIHRoaXMuX3J0Y01vZHVsZS5zZXNzaW9uQ29ubmVjdGVkKGNhbGxJZCwgdHJhY2VJZCk7XG4gICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBfX2lubmVySGFuZ3VwKG9wdHM6IElIYW5ndXBGb3JCdXN5T3B0cywgdHJhY2VJZDogc3RyaW5nKSB7XG4gICAgY29uc3QgeyBjYWxsSWQgfSA9IG9wdHM7XG5cbiAgICB0aGlzLl9jYWxsRW5naW5lLnNldElzTG9jYWxDbGllbnRIYW5ndXAodHJ1ZSk7XG4gICAgdGhpcy5fY2FsbEVuZ2luZS5jbGVhckFsbFRpbWVyKGNhbGxJZCwgdHJhY2VJZCk7XG5cbiAgICBjb25zdCB7IGNvZGUgfSA9IGF3YWl0IHRoaXMuX2NhbGxFbmdpbmUuaGFuZ3VwKG9wdHMsIHRyYWNlSWQpO1xuXG4gICAgaWYgKGNvZGUgPT09IENhbGxTZXJ2ZXJFcnJvckNvZGUuQ0FMTF9OT1RfRVhJU1QpIHtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MgfTtcbiAgICB9XG5cbiAgICBpZiAoY29kZSA9PT0gUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyAmJiBjYWxsSWQgPT09IHRoaXMuX2NhbGxFbmdpbmUuZ2V0TG9jYWxNYWluU2Vzc2lvbigpPy5nZXRDYWxsSWQoKSkge1xuICAgICAgYXdhaXQgdGhpcy5fcnRjTW9kdWxlLnNlc3Npb25DbG9zZShjYWxsSWQsIHRyYWNlSWQpO1xuICAgIH1cblxuICAgIHJldHVybiB7IGNvZGUgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDmjILmlq3pgJror51cbiAgICogQHBhcmFtIGNhbGxJZCDkuLrlj6/pgInlj4LmlbDvvIzkuI3kvKDml7bvvIzmjILmlq3mraPlnKjov5vooYznmoTkuLsgc2Vzc2lvbu+8jOS8oOWFpeaXtuWPr+aMh+WumuaMguaWreS4u+mAmuivneaIluaaguacquW7uueri+i/nuaOpeeahOmAmuivnVxuICAgKiDmmoLmnKrlu7rnq4vov57mjqXnmoTpgJror53vvJrmjIflt7LlnKjpgJror53kuK3ml7bvvIzmlLbliLDlkbzlj6vkvYbmmoLmnKrmjqXlkKznmoTpgJror51cbiAgICovXG4gIGFzeW5jIGhhbmd1cChjYWxsSWQ/OiBzdHJpbmcpOiBQcm9taXNlPHsgY29kZTogbnVtYmVyIH0+IHtcbiAgICBjb25zdCBzdGFydFRpbWUgPSArbmV3IERhdGUoKTtcbiAgICBjb25zdCB0cmFjZUlkID0gdGhpcy5fbG9nZ2VyLmNyZWF0ZVRyYWNlSWQoKTtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0hBTkdVUF9ULCBgY2FsbElkOiAke2NhbGxJZH1gLCB0cmFjZUlkKTtcblxuICAgIGNvbnN0IG1haW5TZXNzaW9uID0gdGhpcy5fY2FsbEVuZ2luZS5nZXRMb2NhbE1haW5TZXNzaW9uKCk7XG4gICAgaWYgKCFtYWluU2Vzc2lvbikge1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuTk9UX0lOX0NBTEwgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDlj4LmlbDnsbvlnovmoKHpqoxcbiAgICAgKi9cbiAgICBpZiAoY2FsbElkICYmICFpc1N0cmluZyhjYWxsSWQpKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9IQU5HVVBfUiwgYHBhcmFtcyBlcnIsIGNhbGxJZDogdHlwZSBpcyBzdHJpbmcsIHZhbHVlOiAke2NhbGxJZH1gLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlBBUkFNX0VSUk9SIH07XG4gICAgfVxuXG4gICAgY29uc3QgbWFpblNlc3Npb25DYWxsSWQgPSBtYWluU2Vzc2lvbi5nZXRDYWxsSWQoKTtcblxuICAgIC8qKlxuICAgICAqIOagoemqjOS8oOWFpeeahCBjYWxsSWQg5piv5ZCm5q2j56GuXG4gICAgICovXG4gICAgaWYgKGNhbGxJZCAmJiBjYWxsSWQgIT09IG1haW5TZXNzaW9uQ2FsbElkICYmICF0aGlzLl9jYWxsRW5naW5lLmdldEhvbGRTZXNzaW9uKGNhbGxJZCkpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0hBTkdVUF9SLCBgcGFyYW1zIGVyciwgY2FsbElkIGlzIGludmFsaWQsIHZhbHVlOiAke2NhbGxJZH1gLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLkNBTExfSURfSU5WQUxJRCB9O1xuICAgIH1cblxuICAgIHRoaXMuX2lzTGF1bmNoSGFuZ3VwID0gdHJ1ZTtcblxuICAgIHRoaXMuX25lZWRIYW5ndXBDYWxsSWQgPSBjYWxsSWQgfHwgbWFpblNlc3Npb25DYWxsSWQ7XG4gICAgY29uc3QgaG9sZFNlc3Npb24gPSB0aGlzLl9jYWxsRW5naW5lLmdldEhvbGRTZXNzaW9uKHRoaXMuX25lZWRIYW5ndXBDYWxsSWQpO1xuICAgIGNvbnN0IGhhbmd1cFNlc3Npb24gPSBob2xkU2Vzc2lvbiB8fCBtYWluU2Vzc2lvbjtcblxuICAgIC8qKlxuICAgICAqIOiOt+WPluaMguaWreaXtueahOS6uuWRmOezu+e7n+eKtuaAgVxuICAgICAqL1xuICAgIGNvbnN0IGN1cnJlbnRVc2VySWQgPSB0aGlzLl9jb250ZXh0LmdldEN1cnJlbnRJZCgpO1xuICAgIGNvbnN0IHVzZXJTdGF0ZSA9IG1haW5TZXNzaW9uLmdldFVzZXJMaXN0KCkuZmlsdGVyKCh1c2VySW5mbykgPT4gdXNlckluZm8udXNlcklkID09PSBjdXJyZW50VXNlcklkKVswXS5zdGF0ZTtcbiAgICBjb25zdCBpc0NhbGxlZSA9IFttYWluU2Vzc2lvbi5nZXRDcmVhdG9yVXNlcklkKCksIG1haW5TZXNzaW9uLmdldEludml0ZXJVc2VySWQoKV0uaW5jbHVkZXMoY3VycmVudFVzZXJJZCk7XG4gICAgY29uc3Qgc3lzdGVtU3RhdGUgPSBnZXRIYW5ndXBTeXN0ZW1TdGF0ZSh1c2VyU3RhdGUsIGlzQ2FsbGVlKTtcblxuICAgIGNvbnN0IHsgY29kZSB9ID0gYXdhaXQgdGhpcy5fX2lubmVySGFuZ3VwKHsgY2FsbElkOiB0aGlzLl9uZWVkSGFuZ3VwQ2FsbElkLCBzeXN0ZW1TdGF0ZSB9LCB0cmFjZUlkKTtcblxuICAgIC8qKlxuICAgICAqIOS4iuaKpeaMguaWreWfi+eCueaVsOaNrlxuICAgICAqL1xuICAgIHRoaXMuX2NhbGxQbHVzU3RhdGlzdGljcy5yZXBvcnRTdGF0aXN0aWNzRGF0YShSQ0NhbGxQbHVzU3RhdGlzdGljc1RhZy5MX1FTX0hBTkdVUF9DQUxMX1MsIGNvZGUsIHN0YXJ0VGltZSwgaGFuZ3VwU2Vzc2lvbiEsIHRoaXMuX2NsaWVudENhbGxJZCk7XG5cbiAgICBpZiAoY29kZSAhPT0gUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUykge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfSEFOR1VQX1IsIGBzaWduYWwgZXJyb3IgY29kZSA6ICR7Y29kZX1gLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICB9XG5cbiAgICB0aGlzLl9uZWVkSGFuZ3VwQ2FsbElkID0gbnVsbDtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0hBTkdVUF9SLCAnc3VjY2VzcycsIHRyYWNlSWQpO1xuICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDpgJror53kuK3lj5HotbflqpLkvZPnsbvlnovlj5jmm7Tor7fmsYJcbiAgICogQHBhcmFtIG1lZGlhVHlwZSDlqpLkvZPnsbvlnotcbiAgICogQHJldHVybnMgdHJhbnNhY3Rpb25JZCDlrqLmiLfnq6/lkozmnI3liqHnq6/kuqTkupLnmoTkuovliqEgaWTvvIzlnKjlj5bmtojmiJblupTnrZTlqpLkvZPnsbvlnovliIfmjaLml7bkvKDlhaVcbiAgICovXG4gIGFzeW5jIHJlcXVlc3RDaGFuZ2VNZWRpYVR5cGUobWVkaWFUeXBlOiBSQ0NhbGxQbHVzTWVkaWFUeXBlKTogUHJvbWlzZTx7IGNvZGU6IG51bWJlciwgdHJhbnNhY3Rpb25JZD86IHN0cmluZyB9PiB7XG4gICAgY29uc3QgdHJhY2VJZCA9IHRoaXMuX2xvZ2dlci5jcmVhdGVUcmFjZUlkKCk7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9SRVFVRVNUX0NIQU5HRV9NRURJQV9UWVBFX1QsIGBtZWRpYVR5cGU6ICR7bWVkaWFUeXBlfWAsIHRyYWNlSWQpO1xuXG4gICAgaWYgKGlzVW5kZWZpbmVkKFJDQ2FsbFBsdXNNZWRpYVR5cGVbbWVkaWFUeXBlXSkpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1JFUVVFU1RfQ0hBTkdFX01FRElBX1RZUEVfUiwgYHBhcmFtcyBlcnIsIG1lZGlhVHlwZSBpcyBpbGxlZ2FsLCB2YWx1ZTogJHttZWRpYVR5cGV9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5QQVJBTV9FUlJPUiB9O1xuICAgIH1cblxuICAgIGNvbnN0IG1haW5TZXNzaW9uID0gdGhpcy5nZXRDdXJyZW50Q2FsbFNlc3Npb24oKTtcbiAgICBjb25zdCBvbGRNZWRpYVR5cGUgPSBtYWluU2Vzc2lvbj8uZ2V0TWVkaWFUeXBlKCk7XG5cbiAgICBpZiAobWVkaWFUeXBlID09PSBvbGRNZWRpYVR5cGUpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1JFUVVFU1RfQ0hBTkdFX01FRElBX1RZUEVfUiwgYGVycm9yIGNvZGU6ICR7UkNDYWxsUGx1c0NvZGUuTUVESUFUWVBFX0lOVkFMSUR9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5NRURJQVRZUEVfSU5WQUxJRCB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIOWIpOaWreaYr+WQpuWcqOmAmuivneS4rVxuICAgICAqL1xuICAgIGlmICghdGhpcy5fY2FsbEVuZ2luZS5nZXRMb2NhbE1haW5TZXNzaW9uKCkpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1JFUVVFU1RfQ0hBTkdFX01FRElBX1RZUEVfUiwgYGVycm9yIGNvZGUgOiAke1JDQ2FsbFBsdXNDb2RlLk5PVF9JTl9DQUxMfSwgc2Vzc2lvbiBub3QgZXhpc3RgLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLk5PVF9JTl9DQUxMIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog5Y+R6LW35aqS5L2T57G75Z6L5YiH5o2iXG4gICAgICovXG4gICAgY29uc3QgdG9Vc2VySWRzID0gbWFpblNlc3Npb24/LmdldFVzZXJMaXN0KCkuZmlsdGVyKCh1c2VyKSA9PiB1c2VyLnVzZXJJZCAhPT0gdGhpcy5fY29udGV4dC5nZXRDdXJyZW50SWQoKSkubWFwKCh1c2VyKSA9PiB1c2VyLnVzZXJJZCk7XG4gICAgY29uc3QgeyBjb2RlLCBkYXRhIH0gPSBhd2FpdCB0aGlzLl9jYWxsRW5naW5lLnJlcXVlc3RDaGFuZ2VNZWRpYVR5cGUoeyBtZWRpYVR5cGUsIHRvVXNlcklkczogdG9Vc2VySWRzIHx8IFtdIH0sIHRyYWNlSWQpO1xuICAgIGlmIChjb2RlICE9PSBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9SRVFVRVNUX0NIQU5HRV9NRURJQV9UWVBFX1IsIGBzaWduYWwgZXJyb3IgY29kZTogJHtjb2RlfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZSB9O1xuICAgIH1cblxuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfUkVRVUVTVF9DSEFOR0VfTUVESUFfVFlQRV9SLCBgc3VjY2VzcyB0cmFuc2FjdGlvbklkOiAke2RhdGEhLnRyYW5zYWN0aW9uSWR9YCwgdHJhY2VJZCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MsXG4gICAgICB0cmFuc2FjdGlvbklkOiBkYXRhIS50cmFuc2FjdGlvbklkLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICog5Y+W5raI5YiH5o2i5aqS5L2T57G75Z6L5Y+Y5pu06K+35rGCXG4gICAqIEBwYXJhbSB0cmFuc2FjdGlvbklkIOWuouaIt+err+WSjOacjeWKoeerr+S6pOS6kueahOS6i+WKoSBpZO+8jOS4uuWPkei1t+WqkuS9k+exu+Wei+WPmOabtOivt+axgui/lOWbnueahCB0cmFuc2FjdGlvbklkXG4gICAqL1xuICBhc3luYyBjYW5jZWxDaGFuZ2VNZWRpYVR5cGUodHJhbnNhY3Rpb25JZDogc3RyaW5nKTogUHJvbWlzZTx7IGNvZGU6IG51bWJlciB9PiB7XG4gICAgY29uc3QgdHJhY2VJZCA9IHRoaXMuX2xvZ2dlci5jcmVhdGVUcmFjZUlkKCk7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9DQU5DRUxfQ0hBTkdFX01FRElBX1RZUEVfVCwgYHRyYW5zYWN0aW9uSWQ6ICR7dHJhbnNhY3Rpb25JZH1gLCB0cmFjZUlkKTtcblxuICAgIC8qKlxuICAgICAqIOWPguaVsOagoemqjFxuICAgICAqL1xuICAgIGlmICghbm90RW1wdHlTdHJpbmcodHJhbnNhY3Rpb25JZCkpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0NBTkNFTF9DSEFOR0VfTUVESUFfVFlQRV9SLCBgcGFyYW0gZXJyb3IsIHRyYW5zYWN0aW9uSWQ6IG5vdCBlbXB0eSBzdHJpbmcsIHZhbHVlOiAke3RyYW5zYWN0aW9uSWR9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5QQVJBTV9FUlJPUiB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIOWIpOaWreaYr+WQpuWcqOmAmuivneS4rVxuICAgICAqL1xuICAgIGlmICghdGhpcy5fY2FsbEVuZ2luZS5nZXRMb2NhbE1haW5TZXNzaW9uKCkpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0NBTkNFTF9DSEFOR0VfTUVESUFfVFlQRV9SLCBgZXJyb3IgY29kZSA6ICR7UkNDYWxsUGx1c0NvZGUuTk9UX0lOX0NBTEx9LCBzZXNzaW9uIG5vdCBleGlzdGAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuTk9UX0lOX0NBTEwgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDlj5bmtojlqpLkvZPnsbvlnovliIfmjaJcbiAgICAgKi9cbiAgICBjb25zdCB7IGNvZGUgfSA9IGF3YWl0IHRoaXMuX2NhbGxFbmdpbmUuY2FuY2VsQ2hhbmdlTWVkaWFUeXBlKHsgdHJhbnNhY3Rpb25JZCB9LCB0cmFjZUlkKTtcbiAgICBpZiAoY29kZSAhPT0gUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUykge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfQ0FOQ0VMX0NIQU5HRV9NRURJQV9UWVBFX1IsIGBzaWduYWwgZXJyb3IgY29kZTogJHtjb2RlfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZSB9O1xuICAgIH1cblxuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfQ0FOQ0VMX0NIQU5HRV9NRURJQV9UWVBFX1IsICdzdWNjZXNzJywgdHJhY2VJZCk7XG4gICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOWqkuS9k+exu+Wei+WPmOabtOW6lOetlFxuICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25JZCDlrqLmiLfnq6/lkozmnI3liqHnq6/kuqTkupLnmoTkuovliqEgaWTvvIzkuLogb25SZWNlaXZlZENoYW5nZVRvVmlkZW8g55uR5ZCs5pS25YiwIHRyYW5zYWN0aW9uSWQg5Y+C5pWw5YC8XG4gICAqL1xuICBhc3luYyByZXBseUNoYW5nZU1lZGlhVHlwZSh0cmFuc2FjdGlvbklkOiBzdHJpbmcsIGlzQWdyZWU6IGJvb2xlYW4pOiBQcm9taXNlPHsgY29kZTogbnVtYmVyIH0+IHtcbiAgICBjb25zdCB0cmFjZUlkID0gdGhpcy5fbG9nZ2VyLmNyZWF0ZVRyYWNlSWQoKTtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1JFUExZX0NIQU5HRV9NRURJQV9UWVBFX1QsIGB0cmFuc2FjdGlvbklkOiAke3RyYW5zYWN0aW9uSWR9YCwgdHJhY2VJZCk7XG5cbiAgICAvKipcbiAgICAgKiDlj4LmlbDmoKHpqoxcbiAgICAgKi9cbiAgICBpZiAoIW5vdEVtcHR5U3RyaW5nKHRyYW5zYWN0aW9uSWQpKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9SRVBMWV9DSEFOR0VfTUVESUFfVFlQRV9SLCBgcGFyYW0gZXJyb3IsIHRyYW5zYWN0aW9uSWQ6IG5vdCBlbXB0eSBzdHJpbmcsIHZhbHVlOiAke3RyYW5zYWN0aW9uSWR9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5QQVJBTV9FUlJPUiB9O1xuICAgIH1cbiAgICBpZiAoIWlzQm9vbGVhbihpc0FncmVlKSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfUkVQTFlfQ0hBTkdFX01FRElBX1RZUEVfUiwgYHBhcmFtIGVycm9yLCBpc0FncmVlOiB0eXBlIGlzIGJvb2xlYW4sIHZhbHVlOiAke2lzQWdyZWV9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5QQVJBTV9FUlJPUiB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIOWIpOaWreaYr+WQpuWcqOmAmuivneS4rVxuICAgICAqL1xuICAgIGlmICghdGhpcy5fY2FsbEVuZ2luZS5nZXRMb2NhbE1haW5TZXNzaW9uKCkpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1JFUExZX0NIQU5HRV9NRURJQV9UWVBFX1IsIGBlcnJvciBjb2RlIDogJHtSQ0NhbGxQbHVzQ29kZS5OT1RfSU5fQ0FMTH0sIHNlc3Npb24gbm90IGV4aXN0YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5OT1RfSU5fQ0FMTCB9O1xuICAgIH1cblxuICAgIGNvbnN0IHsgY29kZSB9ID0gYXdhaXQgdGhpcy5fY2FsbEVuZ2luZS5yZXNwb25zZUNoYW5nZU1lZGlhVHlwZSh7XG4gICAgICB0cmFuc2FjdGlvbklkLFxuICAgICAgYWdyZWU6IGlzQWdyZWUsXG4gICAgfSwgdHJhY2VJZCk7XG4gICAgaWYgKGNvZGUgIT09IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1JFUExZX0NIQU5HRV9NRURJQV9UWVBFX1IsIGBzaWduYWwgZXJyb3I6ICR7Y29kZX1gLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1JFUExZX0NIQU5HRV9NRURJQV9UWVBFX1IsICdzdWNjZXNzJywgdHJhY2VJZCk7XG4gICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPluW9k+WJjei/m+ihjOS4reeahOmAmuivnVxuICAgKiBAcmV0dXJucyBSQ0NhbGxQbHVzU2Vzc2lvbiDlr7nosaHmiJYgbnVsbCDkuLrlvZPliY3mraPlnKjov5vooYznmoTpgJror53lr7nosaFcbiAgICovXG4gIGdldEN1cnJlbnRDYWxsU2Vzc2lvbigpOiBSQ0NhbGxQbHVzU2Vzc2lvbiB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9jYWxsRW5naW5lLmdldExvY2FsTWFpblNlc3Npb24oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDku47mnI3liqHlmajojrflj5bmnKrnu5PmnZ/nmoTpgJror53orrDlvZVcbiAgICogQHJldHVybnMgcmVjb3JkcyDkuIDnu4TmnKrnu5PmnZ/nmoTpgJror53orrDlvZVcbiAgICovXG4gIGFzeW5jIGdldEF2YWlsYWJsZUNhbGxSZWNvcmRzRnJvbVNlcnZlcigpOiBQcm9taXNlPHsgY29kZTogbnVtYmVyLCByZWNvcmRzPzogSVJDQ2FsbFBsdXNDYWxsUmVjb3JkW10gfT4ge1xuICAgIGNvbnN0IHRyYWNlSWQgPSB0aGlzLl9sb2dnZXIuY3JlYXRlVHJhY2VJZCgpO1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfR0VUX0FWQUlMQUJMRV9DQUxMX1JFQ09SRFNfRlJPTV9TRVJWRVJfVCwgJycsIHRyYWNlSWQpO1xuXG4gICAgY29uc3QgeyBjb2RlLCBkYXRhIH0gPSBhd2FpdCB0aGlzLl9jYWxsRW5naW5lLmdldE9wZW5DYWxsTGlzdCh0cmFjZUlkKTtcbiAgICBpZiAoY29kZSAhPT0gUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUykge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfR0VUX0FWQUlMQUJMRV9DQUxMX1JFQ09SRFNfRlJPTV9TRVJWRVJfUiwgYHNpZ25hbCBlcnJvciBjb2RlOiAke2NvZGV9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlIH07XG4gICAgfVxuXG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9HRVRfQVZBSUxBQkxFX0NBTExfUkVDT1JEU19GUk9NX1NFUlZFUl9SLCBgc3VjY2VzcywgZGF0YTogJHtKU09OLnN0cmluZ2lmeShkYXRhKX1gLCB0cmFjZUlkKTtcbiAgICByZXR1cm4ge1xuICAgICAgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyxcbiAgICAgIHJlY29yZHM6IGRhdGEsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDliIbpobXmn6Xmib7lvZPliY3nlKjmiLfnmoTlhajpg6jpgJror53orrDlvZVcbiAgICogQHBhcmFtIHN0YXJ0VGltZXN0YW1wIOi1t+Wni+aXtumXtOaIs++8jOi/lOWbnuWkp+S6juatpOaXtumXtOaIs+eahOmAmuivneiusOW9lVxuICAgKiBAcGFyYW0gY291bnQg5q+P5qyh6I635Y+W55qE5pWw6YePXG4gICAqIEByZXR1cm5zIHJlc3VsdC5oYXNNb3JlIOaYr+WQpuacieabtOWkmumAmuivneiusOW9lVxuICAgKiBAcmV0dXJucyByZXN1bHQubGlzdCDpgJror53orrDlvZXliJfooajvvIznsbvlnovkuLogSVJDQ2FsbFBsdXNDYWxsUmVjb3JkW13vvIzlj6/pgJrov4cgYXBpRG9jIOafpeeci+WFt+S9k+WMheWQq+Wtl+autVxuICAgKiBAcmV0dXJucyByZXN1bHQubWF4VGltZSDliJfooajkuK3mnIDlpKfml7bpl7TmiLPvvIzlpoLmnpwgaGFzTW9yZSDkuLogdHJ1Ze+8jOe7p+e7reiOt+WPluaXtu+8jOS8oOWFpeatpOaXtumXtOaIs1xuICAgKi9cbiAgYXN5bmMgZ2V0Q2FsbFJlY29yZHMoc3RhcnRUaW1lc3RhbXA6IG51bWJlciwgY291bnQ6IG51bWJlcik6IFByb21pc2U8eyBjb2RlOiBudW1iZXIsIHJlc3VsdD86IElSQ0NhbGxQbHVzR2V0Q2FsbFJlY29yZFJlcyB9PiB7XG4gICAgY29uc3QgdHJhY2VJZCA9IHRoaXMuX2xvZ2dlci5jcmVhdGVUcmFjZUlkKCk7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9HRVRfQ0FMTF9SRUNPUkRTX1QsIGBzdGFydFRpbWVzdGFtcDogJHtzdGFydFRpbWVzdGFtcH0sIGNvdW50OiAke2NvdW50fWAsIHRyYWNlSWQpO1xuXG4gICAgaWYgKCEoaXNOdW1iZXIoc3RhcnRUaW1lc3RhbXApICYmIHN0YXJ0VGltZXN0YW1wID49IDApKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9HRVRfQ0FMTF9SRUNPUkRTX1IsIGBwYXJhbXMgZXJyb3IsIHN0YXJ0VGltZXN0YW1wOiBpcyBhIG51bWJlciA+PSAwLCB2YWx1ZTogJHtzdGFydFRpbWVzdGFtcH1gLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlBBUkFNX0VSUk9SIH07XG4gICAgfVxuXG4gICAgaWYgKCEoaXNOdW1iZXIoY291bnQpICYmIGNvdW50ID4gMCkpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0dFVF9DQUxMX1JFQ09SRFNfUiwgYHBhcmFtcyBlcnJvciwgY291bnQ6IGlzIGEgbnVtYmVyID49IDAsIHZhbHVlOiAke2NvdW50fWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuUEFSQU1fRVJST1IgfTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGNvZGUsIGRhdGEgfSA9IGF3YWl0IHRoaXMuX2NhbGxFbmdpbmUuZ2V0Q2FsbExvZ0xpc3Qoe1xuICAgICAgdGltZXN0YW1wOiBzdGFydFRpbWVzdGFtcCxcbiAgICAgIGNvdW50LFxuICAgIH0sIHRyYWNlSWQpO1xuICAgIGlmIChjb2RlICE9PSBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9HRVRfQ0FMTF9SRUNPUkRTX1IsIGBzaWduYWwgZXJyb3IgY29kZTogJHtjb2RlfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZSB9O1xuICAgIH1cblxuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfR0VUX0NBTExfUkVDT1JEU19SLCAnc3VjY2VzcycsIHRyYWNlSWQpO1xuICAgIHJldHVybiB7XG4gICAgICBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTLFxuICAgICAgcmVzdWx0OiBkYXRhISxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOagueaNriBjYWxsSWQg6ZuG5ZCI5om56YeP5Yig6Zmk6YCa6K+d6K6w5b2VXG4gICAqIEBwYXJhbSBjYWxsSWRzIGNhbGxJZCDliJfooahcbiAgICovXG4gIGFzeW5jIGRlbGV0ZUNhbGxSZWNvcmRzRnJvbVNlcnZlcihjYWxsSWRzOiBzdHJpbmdbXSk6IFByb21pc2U8eyBjb2RlOiBudW1iZXIgfT4ge1xuICAgIGNvbnN0IHRyYWNlSWQgPSB0aGlzLl9sb2dnZXIuY3JlYXRlVHJhY2VJZCgpO1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfREVMRVRFX0NBTExfUkVDT1JEU19CWV9DQUxMSURfVCwgYGNhbGxJZHM6ICR7Y2FsbElkcy5qb2luKCcsJyl9YCwgdHJhY2VJZCk7XG5cbiAgICBpZiAoIShcbiAgICAgIG5vdEVtcHR5QXJyYXkoY2FsbElkcylcbiAgICAgICYmIGNhbGxJZHMuZXZlcnkoKGNhbGxJZCkgPT4gbm90RW1wdHlTdHJpbmcoY2FsbElkKSlcbiAgICApKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9ERUxFVEVfQ0FMTF9SRUNPUkRTX0JZX0NBTExJRF9SLCBgcGFyYW1zIGVyciwgY2FsbElkczogbm90IGVtcHR5IGFycmF5LCBjYWxsSWQ6IG5vdCBlbXB0eSBzdHJpbmcsIGNhbGxJZHM6ICR7SlNPTi5zdHJpbmdpZnkoY2FsbElkcyl9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5QQVJBTV9FUlJPUiB9O1xuICAgIH1cblxuICAgIGNvbnN0IHsgY29kZSB9ID0gYXdhaXQgdGhpcy5fY2FsbEVuZ2luZS5kZWxldGVDYWxsTG9nKGNhbGxJZHMsIHRyYWNlSWQpO1xuICAgIGlmIChjb2RlICE9PSBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9ERUxFVEVfQ0FMTF9SRUNPUkRTX0JZX0NBTExJRF9SLCBgc2lnbmFsIGVycm9yIGNvZGU6ICR7Y29kZX1gLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0RFTEVURV9DQUxMX1JFQ09SRFNfQllfQ0FMTElEX1IsICdzdWNjZXNzJywgdHJhY2VJZCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDmuIXnqbrmiYDmnInpgJror53orrDlvZVcbiAgICovXG4gIGFzeW5jIGRlbGV0ZUFsbENhbGxSZWNvcmRzRnJvbVNlcnZlcigpOiBQcm9taXNlPHsgY29kZTogbnVtYmVyIH0+IHtcbiAgICBjb25zdCB0cmFjZUlkID0gdGhpcy5fbG9nZ2VyLmNyZWF0ZVRyYWNlSWQoKTtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0RFTEVURV9BTExfQ0FMTF9SRUNPUkRTX0ZST01fU0VSVkVSX1QsICcnLCB0cmFjZUlkKTtcblxuICAgIGNvbnN0IHsgY29kZSB9ID0gYXdhaXQgdGhpcy5fY2FsbEVuZ2luZS5yZW1vdmVBbGxDYWxsTG9nKHRyYWNlSWQpO1xuICAgIGlmIChjb2RlICE9PSBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9ERUxFVEVfQUxMX0NBTExfUkVDT1JEU19GUk9NX1NFUlZFUl9SLCBgc2lnbmFsIGVycm9yIGNvZGU6ICR7Y29kZX1gLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX0RFTEVURV9BTExfQ0FMTF9SRUNPUkRTX0ZST01fU0VSVkVSX1IsICdzdWNjZXNzJywgdHJhY2VJZCk7XG4gICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOW8gOWQr+aRhOWDj+WktFxuICAgKiBAZGVzY3JpcHRpb24g6YCa6K+d6L+H56iL5Lit5omT5byA5pGE5YOP5aS077yM5aaC5p6c5omp5pWj6LWE5rqQ5aSx6LSl77yM5Y2z5a+55pa55rKh5pS25Yiw5pys56uv5omT5byA5pGE5YOP5aS055qE6YCa55+l5pe277yM5q2k5qyh6KGM5Li65aSx6LSlXG4gICAqIEByZXR1cm5zIHRyYWNrIOaRhOWDj+WktOinhumikei1hOa6kFxuICAgKi9cbiAgYXN5bmMgc3RhcnRDYW1lcmEoKTogUHJvbWlzZTx7IGNvZGU6IG51bWJlciB9PiB7XG4gICAgY29uc3QgdHJhY2VJZCA9IHRoaXMuX2xvZ2dlci5jcmVhdGVUcmFjZUlkKCk7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9TVEFSVF9DQU1FUkFfVCwgJycsIHRyYWNlSWQpO1xuXG4gICAgLyoqXG4gICAgICog6I635Y+W5pGE5YOP5aS06LWE5rqQXG4gICAgICovXG4gICAgY29uc3QgeyBjb2RlLCB0cmFjayB9ID0gYXdhaXQgdGhpcy5fcnRjTW9kdWxlLmdldENhbWVyYVZpZGVvVHJhY2sodHJhY2VJZCk7XG4gICAgaWYgKGNvZGUgIT09IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1NUQVJUX0NBTUVSQV9SLCBgY3JlYXRlIHZpZGVvIHRyYWNrIGVycm9yIGNvZGU6ICR7Y29kZX1gLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICB9XG5cbiAgICB0aGlzLl9jYWxsRW5naW5lLnNldFVzZXJEZXZpY2VFbmFibGUodGhpcy5fY29udGV4dC5nZXRDdXJyZW50SWQoKSwgUkNDYWxsUGx1c01lZGlhVHlwZS5WSURFTywgdHJ1ZSwgdHJhY2VJZCk7XG5cbiAgICBpZiAoIXRyYWNrPy5pc1B1Ymxpc2hlZCgpICYmIHRoaXMuX2NhbGxFbmdpbmUuZ2V0TG9jYWxNYWluU2Vzc2lvbigpPy5nZXRTdGF0ZSgpID09PSBSQ0NhbGxQbHVzQ2FsbFN0YXRlLk9OQ0FMTCkge1xuICAgICAgY29uc3QgeyBjb2RlIH0gPSBhd2FpdCB0aGlzLl9ydGNNb2R1bGUucHVibGlzaFZpZGVvVHJhY2soKTtcbiAgICAgIGlmIChjb2RlICE9PSBSQ1JUQ0NvZGUuU1VDQ0VTUykge1xuICAgICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9TVEFSVF9DQU1FUkFfUiwgYHB1Ymxpc2ggZXJyb3IgY29kZTogJHtjb2RlfWAsIHRyYWNlSWQpO1xuICAgICAgICByZXR1cm4geyBjb2RlIH07XG4gICAgICB9XG4gICAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1NUQVJUX0NBTUVSQV9SLCAnc3VjY2VzcycsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIOWQr+eUqOi1hOa6kFxuICAgICAqIOaJqeaVo+WQr+eUqOi1hOa6kOa2iOaBr++8jOWmguaenOWksei0pe+8jOWImSBzdGFydENhbWVyYSDooYzkuLrlpLHotKVcbiAgICAgKi9cbiAgICBjb25zdCB7IGNvZGU6IHVubXV0ZUNvZGUgfSA9IGF3YWl0IHRoaXMuX3J0Y01vZHVsZS5lbmFibGVWaWRlb1RyYWNrKHRyYWNlSWQpO1xuICAgIGlmICh1bm11dGVDb2RlICE9PSBSQ1JUQ0NvZGUuU1VDQ0VTUyAmJiB1bm11dGVDb2RlICE9PSBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9TVEFSVF9DQU1FUkFfUiwgYHNpZ25hbCBlcnJvciBjb2RlOiAke3VubXV0ZUNvZGV9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiB1bm11dGVDb2RlIH07XG4gICAgfVxuXG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9TVEFSVF9DQU1FUkFfUiwgJ3N1Y2Nlc3MnLCB0cmFjZUlkKTtcbiAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTIH07XG4gIH1cblxuICAvKipcbiAgICog5YWz6Zet5pGE5YOP5aS0XG4gICAqL1xuICBhc3luYyBzdG9wQ2FtZXJhKCk6IFByb21pc2U8eyBjb2RlOiBudW1iZXIgfT4ge1xuICAgIGNvbnN0IHRyYWNlSWQgPSB0aGlzLl9sb2dnZXIuY3JlYXRlVHJhY2VJZCgpO1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfU1RPUF9DQU1FUkFfVCwgJycsIHRyYWNlSWQpO1xuXG4gICAgY29uc3QgeyBjb2RlLCB0cmFjayB9ID0gYXdhaXQgdGhpcy5fcnRjTW9kdWxlLmRpc2FibGVWaWRlb1RyYWNrKCk7XG5cbiAgICBpZiAoY29kZSAhPT0gUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyAmJiBjb2RlICE9PSBSQ1JUQ0NvZGUuU1VDQ0VTUykge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfU1RPUF9DQU1FUkFfUiwgYGVycm9yIGNvZGU6ICR7Y29kZX1gLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICB9XG5cbiAgICB0aGlzLl9ydGNNb2R1bGUuZGVzdHJveVRyYWNrKHRyYWNrISk7XG4gICAgdGhpcy5fY2FsbEVuZ2luZS5zZXRVc2VyRGV2aWNlRW5hYmxlKHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudElkKCksIFJDQ2FsbFBsdXNNZWRpYVR5cGUuVklERU8sIGZhbHNlLCB0cmFjZUlkKTtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1NUT1BfQ0FNRVJBX1IsICdzdWNjZXNzJywgdHJhY2VJZCk7XG4gICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOWIh+aNouaRhOWDj+WktFxuICAgKiDliIfmjaLmiJDlip/lkI4gYElDYWxsUGx1c0V2ZW50TGlzdGVuZXJgIOebkeWQrOWZqOeahCBgb25Vc2VyTWVkaWFBdmFpbGFibGVgIOS4reS8muaUtuWIsOaWsOWIh+aNoueahOaRhOWDj+WktOi1hOa6kOWPr+aSreaUvu+8jOatpOaXtuiwg+eUqCBgY2FsbFBsdXNDbGllbnQucGxheU1lZGlhKClgIOWPr+aYvuekuuaWsOaRhOWDj+WktOeahOeUu+mdolxuICAgKiBAcGFyYW0gY2FtZXJhSWQg5rWP6KeI5Zmo5Lit5Y+W5b6X55qE5pGE5YOP5aS06K6+5aSHIGlk77yM5Y+v6LCDIHBsdWdpbi1ydGMg55qEIGdldENhbWVyYXMg5pa55rOV5Y+W5b6XXG4gICAqIEBkZXNjcmlwdGlvbiDpgJror53liY3lkozpgJror53kuK3pg73lj6/osIPnlKhcbiAgICovXG4gIGFzeW5jIHN3aXRjaENhbWVyYShjYW1lcmFJZDogc3RyaW5nKTogUHJvbWlzZTx7IGNvZGU6IG51bWJlcn0+IHtcbiAgICBjb25zdCB0cmFjZUlkID0gdGhpcy5fbG9nZ2VyLmNyZWF0ZVRyYWNlSWQoKTtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1NXSVRDSF9DQU1FUkFfVCwgYGNhbWVyYUlkOiAke2NhbWVyYUlkfWAsIHRyYWNlSWQpO1xuXG4gICAgaWYgKCFub3RFbXB0eVN0cmluZyhjYW1lcmFJZCkpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1NXSVRDSF9DQU1FUkFfUiwgYHBhcmFtIGVycm9yLCBjYW1lcmFJZDogbm90IGVtcHR5IHN0cmluZywgdmFsdWU6ICR7Y2FtZXJhSWR9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5QQVJBTV9FUlJPUiB9O1xuICAgIH1cblxuICAgIGNvbnN0IHNlc3Npb24gPSB0aGlzLl9jYWxsRW5naW5lLmdldExvY2FsTWFpblNlc3Npb24oKTtcbiAgICBpZiAoIXNlc3Npb24pIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1NXSVRDSF9DQU1FUkFfUiwgYGVyckNvZGU6ICR7UkNDYWxsUGx1c0NvZGUuTk9UX0lOX0NBTEx9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5OT1RfSU5fQ0FMTCB9O1xuICAgIH1cblxuICAgIGlmIChzZXNzaW9uLmdldE1lZGlhVHlwZSgpID09PSBSQ0NhbGxQbHVzTWVkaWFUeXBlLkFVRElPKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9TV0lUQ0hfQ0FNRVJBX1IsIGBlcnJDb2RlOiAke1JDQ2FsbFBsdXNDb2RlLk5PVF9WSURFT19DQUxMfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuTk9UX1ZJREVPX0NBTEwgfTtcbiAgICB9XG5cbiAgICB0aGlzLl92aWRlb0NvbmZpZy5jYW1lcmFJZCA9IGNhbWVyYUlkO1xuICAgIHRoaXMuX3J0Y01vZHVsZS5zZXRWaWRlb0NvbmZpZyh0aGlzLl92aWRlb0NvbmZpZyk7XG5cbiAgICBjb25zdCB7IGNvZGUgfSA9IGF3YWl0IHRoaXMuX3J0Y01vZHVsZS5jaGFuZ2VWaWRlb0RldmljZSh0cmFjZUlkKTtcbiAgICBpZiAoY29kZSAhPT0gUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUykge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfU1dJVENIX0NBTUVSQV9SLCBgY2FsbCBjbGllbnQgY2hhbmdlVmlkZW9EZXZpY2UgZXJyb3IgY29kZTogJHtjb2RlfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZSB9O1xuICAgIH1cbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1NXSVRDSF9DQU1FUkFfUiwgJ3N1Y2Nlc3MnLCB0cmFjZUlkKTtcbiAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTIH07XG4gIH1cblxuICAvKipcbiAgICog5byA5ZCv6bqm5YWL6aOOXG4gICAqIEBkZXNjcmlwdGlvbiDpgJror53ov4fnqIvkuK3miZPlvIDpuqblhYvpo47vvIzlpoLmnpzmianmlaPotYTmupDlpLHotKXvvIzljbPlr7nmlrnmsqHmlLbliLDmnKznq6/miZPlvIDpuqblhYvpo47nmoTpgJrnn6Xml7bvvIzmraTmrKHooYzkuLrlpLHotKVcbiAgICovXG4gIGFzeW5jIHN0YXJ0TWljcm9waG9uZSgpOiBQcm9taXNlPHsgY29kZTogbnVtYmVyIH0+IHtcbiAgICBjb25zdCB0cmFjZUlkID0gdGhpcy5fbG9nZ2VyLmNyZWF0ZVRyYWNlSWQoKTtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbyhSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1NUQVJUX01JQ1JPUEhPTkVfVCwgJycsIHRyYWNlSWQpO1xuXG4gICAgY29uc3QgeyBjb2RlLCB0cmFjayB9ID0gYXdhaXQgdGhpcy5fcnRjTW9kdWxlLmdldE1pY3JvcGhvbmVBdWRpb1RyYWNrKHRyYWNlSWQpO1xuICAgIGlmIChjb2RlICE9PSBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9TVEFSVF9NSUNST1BIT05FX1IsIGBjcmVhdGUgbWljcm9waG9uZSBhdWRpbyB0cmFjayBlcnJvciBjb2RlOiAke2NvZGV9YCwgdHJhY2VJZCk7XG4gICAgICByZXR1cm4geyBjb2RlIH07XG4gICAgfVxuXG4gICAgdGhpcy5fY2FsbEVuZ2luZS5zZXRVc2VyRGV2aWNlRW5hYmxlKHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudElkKCksIFJDQ2FsbFBsdXNNZWRpYVR5cGUuQVVESU8sIHRydWUsIHRyYWNlSWQpO1xuXG4gICAgaWYgKCF0cmFjayEuaXNPd25lck11dGVkKCkpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5pbmZvKFJDQ2FsbFBsdXNMb2dnZXJUYWcuTF9DQUxMUExVU19DTElFTlRfU1RBUlRfTUlDUk9QSE9ORV9SLCAnc3VjY2VzcycsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsUGx1c0NvZGUuU1VDQ0VTUyB9O1xuICAgIH1cblxuICAgIGNvbnN0IHVubXV0ZUNvZGUgPSBhd2FpdCB0cmFjayEudW5tdXRlKCk7XG4gICAgaWYgKHVubXV0ZUNvZGUgIT09IFJDUlRDQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9TVEFSVF9NSUNST1BIT05FX1IsIGBzaWduYWwgZXJyb3IgY29kZTogJHtjb2RlfWAsIHRyYWNlSWQpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29kZTogdW5tdXRlQ29kZSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9TVEFSVF9NSUNST1BIT05FX1IsICdzdWNjZXNzJywgdHJhY2VJZCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvZGU6IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDlhbPpl63puqblhYvpo45cbiAgICogQGRlc2NyaXB0aW9uIOmAmuivnei/h+eoi+S4reWFs+mXrem6puWFi+mjju+8jOWmguaenOaJqeaVo+i1hOa6kOWksei0pe+8jOWNs+WvueaWueayoeaUtuWIsOacrOerr+WFs+mXrem6puWFi+mjjueahOmAmuefpeaXtu+8jOatpOasoeihjOS4uuWksei0pVxuICAgKi9cbiAgYXN5bmMgc3RvcE1pY3JvcGhvbmUoKTogUHJvbWlzZTx7IGNvZGU6IG51bWJlciB9PiB7XG4gICAgY29uc3QgdHJhY2VJZCA9IHRoaXMuX2xvZ2dlci5jcmVhdGVUcmFjZUlkKCk7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9TVE9QX01JQ1JPUEhPTkVfVCwgJycsIHRyYWNlSWQpO1xuXG4gICAgY29uc3QgeyBjb2RlLCB0cmFjayB9ID0gYXdhaXQgdGhpcy5fcnRjTW9kdWxlLmRpc2FibGVBdWRpb1RyYWNrKCk7XG4gICAgaWYgKGNvZGUgIT09IFJDQ2FsbFBsdXNDb2RlLlNVQ0NFU1MgJiYgY29kZSAhPT0gUkNSVENDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfQ0FMTFBMVVNfQ0xJRU5UX1NUT1BfTUlDUk9QSE9ORV9SLCBgc2lnbmFsIGVycm9yIGNvZGU6ICR7Y29kZX1gLCB0cmFjZUlkKTtcbiAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICB9XG5cbiAgICB0aGlzLl9jYWxsRW5naW5lLnNldFVzZXJEZXZpY2VFbmFibGUodGhpcy5fY29udGV4dC5nZXRDdXJyZW50SWQoKSwgUkNDYWxsUGx1c01lZGlhVHlwZS5BVURJTywgZmFsc2UsIHRyYWNlSWQpO1xuXG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oUkNDYWxsUGx1c0xvZ2dlclRhZy5MX0NBTExQTFVTX0NMSUVOVF9TVE9QX01JQ1JPUEhPTkVfUiwgJ3N1Y2Nlc3MnLCB0cmFjZUlkKTtcbiAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxQbHVzQ29kZS5TVUNDRVNTIH07XG4gIH1cblxuICAvKipcbiAgICog6bqm5YWL6aOO5piv5ZCm5byA5ZCvXG4gICAqL1xuICBpc01pY3JvcGhvbmVFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHRyYWNrID0gdGhpcy5fcnRjTW9kdWxlLmdldExvY2FsQXVkaW9UcmFjaygpO1xuICAgIHJldHVybiAhIXRyYWNrICYmICF0cmFjay5pc093bmVyTXV0ZWQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDorr7nva7miYDmnInov5znq6/pn7PpopHmtYHmmK/lkKblj6/nlKhcbiAgICogQHBhcmFtIGVuYWJsZSDkuLogdHJ1ZSDml7bvvIzpnZnpn7PmiYDmnInov5znq6/pn7PpopHmtYHvvJvkuLogZmFsc2Ug5pe277yM5ZCv55So5omA5pyJ6L+c56uv6Z+z6aKR5rWBXG4gICAqL1xuICBhc3luYyBzZXRBbGxSZW1vdGVBdWRpb0VuYWJsZShlbmFibGU6IGJvb2xlYW4pOiBQcm9taXNlPHsgY29kZTogbnVtYmVyIH0+IHtcbiAgICBjb25zdCB0cmFjZUlkID0gdGhpcy5fbG9nZ2VyLmNyZWF0ZVRyYWNlSWQoKTtcbiAgICByZXR1cm4gdGhpcy5fcnRjTW9kdWxlLnNldEFsbFJlbW90ZUF1ZGlvRW5hYmxlKGVuYWJsZSwgdHJhY2VJZCk7XG4gIH1cblxuICAvKipcbiAgICog6I635Y+WIFNESyDniYjmnKzkv6Hmga9cbiAgICogQHJldHVybnMgU0RLIOeJiOacrOWPt1xuICAgKi9cbiAgZ2V0VmVyc2lvbigpOiBzdHJpbmcge1xuICAgIHJldHVybiBfX1ZFUlNJT05fXztcbiAgfVxuXG4gIC8qKlxuICAgKiDojrflj5bmkYTlg4/lpLTliJfooahcbiAgICovXG4gIGFzeW5jIGdldENhbWVyYXMoKSB7XG4gICAgY29uc3QgY2FtZXJhcyA9IGF3YWl0IGRldmljZS5nZXRDYW1lcmFzKCk7XG4gICAgcmV0dXJuIGNhbWVyYXM7XG4gIH1cblxuICAvKipcbiAgICog6I635Y+W6bqm5YWL6aOO5YiX6KGoXG4gICAqL1xuICBhc3luYyBnZXRNaWNyb3Bob25lcygpIHtcbiAgICBjb25zdCBtaWNyb3Bob25lcyA9IGF3YWl0IGRldmljZS5nZXRNaWNyb3Bob25lcygpO1xuICAgIHJldHVybiBtaWNyb3Bob25lcztcbiAgfVxufVxuIiwiaW1wb3J0IHtcbiAgaXNGdW5jdGlvbiwgaXNPYmplY3QsIGlzVW5kZWZpbmVkLCBMb2dMZXZlbCxcbn0gZnJvbSAnQHJvbmdjbG91ZC9lbmdpbmUnO1xuaW1wb3J0IHsgSVJDQ2FsbEluaXRPcHRpb25zIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9JSW5kZXgnO1xuaW1wb3J0IHsgSVZhbGlkYXRlUmVzIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9JVmFsaWRhdGlvbic7XG5pbXBvcnQgeyBJQ2FsbFBsdXNFdmVudExpc3RlbmVyLCBSQ0NhbGxQbHVzQ29kZSB9IGZyb20gJy4uL2FwaS9pbnRlcmZhY2UnO1xuXG4vKipcbiAqIOWIneWni+WMluWPguaVsOagoemqjFxuICovXG5leHBvcnQgY29uc3QgdmFsaWRhdGVJbml0T3B0cyA9IChvcHRzOiBJUkNDYWxsSW5pdE9wdGlvbnMpOiBJVmFsaWRhdGVSZXMgPT4ge1xuICBpZiAoIW9wdHMpIHtcbiAgICByZXR1cm4geyBpc0xlZ2FsOiBmYWxzZSwgbXNnOiAnSW5pdGlhbGl6YXRpb24gbWlzc2luZyBwYXJhbWV0ZXIgLT4gb3B0aW9ucycgfTtcbiAgfVxuICBpZiAoIWlzT2JqZWN0KG9wdHMpKSB7XG4gICAgcmV0dXJuIHsgaXNMZWdhbDogZmFsc2UsIG1zZzogJ0luaXRpYWxpemF0aW9uIG9wdGlvbnMgbXVzdCBiZSBhbiBvYmplY3QnIH07XG4gIH1cblxuICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMob3B0cyk7XG4gIC8vIOW/heS8oOWPguaVsOmqjOivgVxuICBpZiAoIWtleXMuaW5jbHVkZXMoJ3J0Y0NsaWVudCcpKSB7XG4gICAgcmV0dXJuIHsgaXNMZWdhbDogZmFsc2UsIGNvZGU6IFJDQ2FsbFBsdXNDb2RlLk5PVF9JTlNUQUxMX1JUQ19QTFVHSU4gfTtcbiAgfVxuICBpZiAoIWlzT2JqZWN0KG9wdHMucnRjQ2xpZW50KSkge1xuICAgIHJldHVybiB7IGlzTGVnYWw6IGZhbHNlLCBtc2c6ICdJbml0aWFsaXphdGlvbiBcXCdydGNDbGllbnRcXCcgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBcXCdvYmplY3RcXCcnIH07XG4gIH1cblxuICAvLyDlpoLmnpzkvKDkuoYgbG9nU3Rkb3V0IOS9huS4jeaYryBmdW5jdGlvbiDnsbvlnotcbiAgaWYgKCFpc1VuZGVmaW5lZChvcHRzLmxvZ1N0ZG91dCkgJiYgIWlzRnVuY3Rpb24ob3B0cy5sb2dTdGRvdXQpKSB7XG4gICAgcmV0dXJuIHsgaXNMZWdhbDogZmFsc2UsIG1zZzogJ0luaXRpYWxpemF0aW9uIFxcJ2xvZ1N0ZG91dFxcJyBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIFxcJ2Z1bmN0aW9uXFwnJyB9O1xuICB9XG5cbiAgcmV0dXJuIHsgaXNMZWdhbDogdHJ1ZSB9O1xufTtcblxuLyoqXG4gKiByZWdpc3RlckNhbGxFdmVudExpc3RlbmVyIOWPguaVsOagoemqjFxuICovXG5leHBvcnQgY29uc3QgdmFsaWRhdGVMaXN0ZW5lciA9IChsaXN0ZW5lcjogSUNhbGxQbHVzRXZlbnRMaXN0ZW5lcik6IElWYWxpZGF0ZVJlcyA9PiB7XG4gIGlmICghbGlzdGVuZXIpIHtcbiAgICByZXR1cm4geyBpc0xlZ2FsOiBmYWxzZSwgbXNnOiAnbWlzc2luZyBwYXJhbWV0ZXIgLT4gbGlzdGVuZXInIH07XG4gIH1cblxuICAvLyDmoKHpqozmmK/lkKbnvLrlsJHlv4XopoHnm5HlkKzlm57osIPms6jlhoxcbiAgY29uc3QgcmVxdWlyZWRLZXlzID0gWydvbkludml0ZScsICdvblNlc3Npb25DbG9zZScsICdvblJlbW90ZVRyYWNrUmVhZHknXTtcbiAgY29uc3Qga2V5czogc3RyaW5nW10gPSBPYmplY3Qua2V5cyhsaXN0ZW5lcik7XG4gIGNvbnN0IG1pc3NpbmdLZXlzOiBzdHJpbmdbXSA9IFtdO1xuICByZXF1aXJlZEtleXMuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgaWYgKCFrZXlzLmluY2x1ZGVzKGtleSkpIHtcbiAgICAgIG1pc3NpbmdLZXlzLnB1c2goa2V5KTtcbiAgICB9XG4gIH0pO1xuICBpZiAobWlzc2luZ0tleXMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHsgaXNMZWdhbDogZmFsc2UsIG1zZzogYG1pc3NpbmcgcGFyYW1ldGVyIC0+IFwiJHttaXNzaW5nS2V5cy5qb2luKCcsJyl9XCJgIH07XG4gIH1cblxuICBsZXQgcmVzOiBJVmFsaWRhdGVSZXMgPSB7IGlzTGVnYWw6IHRydWUgfTtcblxuICAvLyDmoKHpqozlv4XopoHnm5HlkKzmmK/lkKbmmK8gZnVuY3Rpb24g57G75Z6LXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmVxdWlyZWRLZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qga2V5ID0gcmVxdWlyZWRLZXlzW2ldO1xuICAgIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcls8a2V5b2YgSUNhbGxQbHVzRXZlbnRMaXN0ZW5lcj5rZXldKSkge1xuICAgICAgcmVzID0geyBpc0xlZ2FsOiBmYWxzZSwgbXNnOiBgJyR7a2V5fScgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSAnZnVuY3Rpb24nYCB9O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlcztcbn07XG4iLCJpbXBvcnQge1xuICBJUGx1Z2luR2VuZXJhdG9yLCBJUnVudGltZSwgaXNVbmRlZmluZWQsIExvZ0wsIFBsdWdpbkNvbnRleHQsXG59IGZyb20gJ0Byb25nY2xvdWQvZW5naW5lJztcbmltcG9ydCB7IFJDQ2FsbFBsdXNDbGllbnQgfSBmcm9tICcuL2NvcmUvYXBpL1JDQ2FsbFBsdXNDbGllbnQnO1xuaW1wb3J0IHsgUkNDYWxsUGx1c1Nlc3Npb24gfSBmcm9tICcuL2NvcmUvbW9kdWxlcy9SQ0NhbGxQbHVzU2Vzc2lvbic7XG5pbXBvcnQgeyB2YWxpZGF0ZUluaXRPcHRzIH0gZnJvbSAnLi9jb3JlL3V0aWxzL3ZhbGlkYXRpb24nO1xuaW1wb3J0IHsgSUNhbGxQbHVzSW5pdE9wdHMgfSBmcm9tICcuL2NvcmUvYXBpL2ludGVyZmFjZSc7XG5pbXBvcnQgUkNBdWRpb0NvbmZpZ0J1aWxkZXIgZnJvbSAnLi9jb3JlL2FwaS9SQ0F1ZGlvQ29uZmlnQnVpbGRlcic7XG5pbXBvcnQgUkNWaWRlb0NvbmZpZ0J1aWxkZXIgZnJvbSAnLi9jb3JlL2FwaS9SQ1ZpZGVvQ29uZmlnQnVpbGRlcic7XG5pbXBvcnQgeyBSQ0NhbGxQbHVzTG9nZ2VyVGFnIH0gZnJvbSAnLi9jb3JlL2FwaS9lbnVtcy9SQ0NhbGxQbHVzTG9nZ2VyVGFnJztcblxuY29uc3QgaW5zdGFsbGVyOiBJUGx1Z2luR2VuZXJhdG9yPFJDQ2FsbFBsdXNDbGllbnQsIElDYWxsUGx1c0luaXRPcHRzPiA9IHtcbiAgdGFnOiAnUkNDYWxsUGx1cycsXG4gIHZlcmlmeShydW50aW1lOiBJUnVudGltZSkge1xuICAgIHJldHVybiBydW50aW1lLnRhZyA9PT0gJ2Jyb3dzZXInO1xuICB9LFxuICBzZXR1cChjb250ZXh0OiBQbHVnaW5Db250ZXh0LCBydW50aW1lOiBJUnVudGltZSwgb3B0aW9uczogSUNhbGxQbHVzSW5pdE9wdHMpOiBSQ0NhbGxQbHVzQ2xpZW50IHtcbiAgICAvLyDliJ3lp4vljJblj4LmlbDmoKHpqoxcbiAgICBjb25zdCB2YWxpZGF0ZVJlcyA9IHZhbGlkYXRlSW5pdE9wdHMob3B0aW9ucyk7XG4gICAgaWYgKCF2YWxpZGF0ZVJlcy5pc0xlZ2FsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFtSQ0NhbGxMaWIgaW5zdGFsbGVyIHN0ZXVwXSR7dmFsaWRhdGVSZXMubXNnfWApO1xuICAgIH1cblxuICAgIC8vIOWIm+W7uiBlbmdpbmUgbG9nZ2VyXG4gICAgY29uc3QgZW5naW5lTG9nZ2VyID0gY29udGV4dC5jcmVhdGVMb2dnZXIoJ0NhbGxQbHVzTGliJywgJ1JUQycpO1xuICAgIC8vIOiuvue9riDovpPlh7rnuqfliKtcbiAgICBjb25zdCBvdXRwdXRMZXZlbCA9IGlzVW5kZWZpbmVkKG9wdGlvbnMubG9nT3V0cHV0TGV2ZWwpID8gTG9nTC5XQVJOIDogb3B0aW9ucy5sb2dPdXRwdXRMZXZlbDtcbiAgICBlbmdpbmVMb2dnZXIuc2V0T3V0cHV0TGV2ZWwob3V0cHV0TGV2ZWwhKTtcbiAgICBlbmdpbmVMb2dnZXIud2FybihSQ0NhbGxQbHVzTG9nZ2VyVGFnLkxfSU5ERVhfSU5TVEFMTF9DQUxMX1BMVVNfUExVR0lOX08sIGBDYWxsUGx1cyBWZXJzaW9uOiAke19fVkVSU0lPTl9ffSwgQ29tbWl0OiAke19fQ09NTUlUX0lEX199YCk7XG5cbiAgICByZXR1cm4gbmV3IFJDQ2FsbFBsdXNDbGllbnQoY29udGV4dCwgZW5naW5lTG9nZ2VyLCBydW50aW1lLCBvcHRpb25zKTtcbiAgfSxcbn07XG5cbmV4cG9ydCB7XG4gIGluc3RhbGxlcixcbiAgLyogY2xhc3MgKi9cbiAgUkNDYWxsUGx1c0NsaWVudCxcbiAgUkNDYWxsUGx1c1Nlc3Npb24sXG4gIFJDQXVkaW9Db25maWdCdWlsZGVyLFxuICBSQ1ZpZGVvQ29uZmlnQnVpbGRlcixcbn07XG4vKipcbiAqIOWvvOWHuuaemuS4vuWSjOaOpeWPo+WumuS5iVxuICovXG5leHBvcnQgKiBmcm9tICcuL2NvcmUvYXBpL2ludGVyZmFjZSc7XG4iXSwibmFtZXMiOlsiUkNDYWxsUGx1c0NvZGUiLCJSQ0NhbGxQbHVzTG9nZ2VyVGFnIiwiUkNDYWxsUGx1c1Nlc3Npb24iLCJfc2Vzc2lvbiIsIl9jYWxsRW5naW5lIiwiX2xvZ2dlciIsIl9fcHVibGljRmllbGQiLCJ1c2VyIiwidXNlcklkIiwidXNlclN0YXRlIiwiY2FtZXJhRW5hYmxlIiwibWljcm9waG9uZUVuYWJsZSIsInRyYWNlSWQiLCJjb2RlIiwiY2xpZW50U3RhcnRUaW1lIiwiZGF0YSIsIlJDQ2FsbFBsdXNUeXBlIiwiUkNDYWxsUGx1c1R5cGUyIiwiUkNDYWxsUGx1c1Nlc3Npb25Vc2VyU3RhdGUiLCJSQ0NhbGxQbHVzTWVkaWFUeXBlIiwiUkNDYWxsUGx1c01lZGlhVHlwZTIiLCJSQ0NhbGxQbHVzQ2FsbFN0YXRlIiwiUkNDYWxsUGx1c01lZGlhVHlwZUNoYW5nZVJlc3VsdCIsIlJDQ2FsbFBsdXNSZWFzb24iLCJSQ0F1ZGlvQ29uZmlnQnVpbGRlciIsIm1pY3JvcGhvbmVJZCIsIm1pbiIsIm1heCIsImlzTnVtYmVyIiwic2FtcGxlUmF0ZSIsIlJDVmlkZW9Db25maWdCdWlsZGVyIiwiUkNDYWxsUGx1c1Jlc29sdXRpb24iLCJSQ0NhbGxQbHVzRnJhbWVSYXRlIiwiZnBzIiwicmVzb2x1dGlvbiIsImNhbWVyYUlkIiwidHJhbjJDYWxsTG9nIiwiY2FsbExvZ0xpc3QiLCJjYWxsSWQiLCJjYWxsVHlwZSIsImNhbGxEaXIiLCJtZWRpYVR5cGUiLCJjYWxsaW5nVXNlcklkIiwiY2FsbFVzZXJJZHMiLCJjYWxsU3RhdHVzIiwic2Vzc2lvblN0YXR1cyIsInN0YXJ0VGltZSIsImVuZFRpbWUiLCJkdXJhdGlvbiIsInNlY3JldENoYXQiLCJzeW5jVGltZSIsInN5c1N0YXR1cyIsImNydFRpbWUiLCJwYXJzZVN0YXR1c0RhdGEiLCJyaW5naW5nRGF0YSIsImhhbmd1cERhdGEiLCJhY2NlcHREYXRhIiwib3RoZXJJbnZpdGVkRGF0YSIsIml0ZW0iLCJ2YWxpZGF0ZVZpZGVvTm9kZU5hbWUiLCJlbGVtZW50IiwidmFsaWRhdGVTeXNTdGF0ZSIsImNydFN0YXRlIiwibmV3U3RhdGUiLCJpc0luVmFsaWQiLCJpbnZhbGlkU3RhdGVzIiwidmFsaWRhdGVVc2VyU3RhdGUiLCJnZXRIYW5ndXBTeXN0ZW1TdGF0ZSIsImlzQ2FsbGVlIiwic3lzdGVtU3RhdGUiLCJpc1N1cHBvcnRNZWRpYVNlcnZlciIsIm5hdmlJbmZvIiwidm9pcENhbGxJbmZvIiwic3RyYXRlZ3kiLCJ2YWxpZGF0ZUJpdHJhdGUiLCJtaW5CaXRyYXRlIiwibWF4Qml0cmF0ZSIsIlJDQ2FsbFBsdXNTdGF0aXN0aWNzVGFnIiwiUkNDYWxsUEx1c1N0YXRpc3RpY3MiLCJfY29udGV4dCIsInRhZyIsInNlc3Npb24iLCJjbGllbnRDYWxsSWQiLCJpbnZpdGVTb3VyY2UiLCJleHRyYSIsIm5vd1RpbWUiLCJjb21tb25EYXRhIiwiRGlhbG9nQWN0aW9uIiwiRGlhbG9nVHlwZSIsIlNlY3JldENhbGxUeXBlIiwiU2VjcmV0Q2FsbFR5cGUyIiwiQ2FsbFRpbWVyRXZlbnRUeXBlIiwiUkNDYWxsSW5uZXJTZXNzaW9uIiwiRXZlbnRFbWl0dGVyIiwiX2NhbGxJZCIsIl9zdGF0ZSIsIl9jYWxsVHlwZSIsIl9tZWRpYVR5cGUiLCJfc3RhcnRDYWxsZXJJZCIsIl9jYWxsZXJJZCIsIl9jYWxsVXNlcnMiLCJlbmFibGUiLCJ1c2VycyIsImNoYW5nZWRVc2VycyIsIm5ld1VzZXJTdGF0ZSIsIm5ld1N0YXRlVGltZSIsIm5ld1N5c1N0YXRlIiwiaGFzVXNlciIsImkiLCJvbGRTdGF0ZVRpbWUiLCJvbGRTeXN0ZW1TdGF0ZSIsIm9sZFVzZXJTdGF0ZSIsImlzSW52YWxpZFN5c1N0YXRlIiwiaXNJbnZhbGlkVXNlclN0YXRlIiwiaXNJbnZhbGlkT25waG9uZUVuZCIsImVyciIsInN0YXRlIiwidHlwZSIsInRpbWVySWQiLCJpc0xvY2FsQ2xpZW50SGFuZ3VwIiwiQ2FsbFNlcnZlckFjdGlvbiIsInRpbWVyU2V0VGltZW91dCIsImZ1bmMiLCJ0aW1lb3V0Iiwic2xlZXAiLCJtaWxsaXNlY29uZCIsInJlc29sdmUiLCJuZWVkUmV0cnlDb2RlIiwiRXJyb3JDb2RlIiwiUkNSVENDb2RlIiwicmV0cnlBc3luY0ZuIiwiYXN5bmNGbiIsImZuQXJncyIsImN1cnJlbnRSZXRyeVRpbWUiLCJtYXhEdXJhdGlvbiIsImludGVydmFscyIsImluZGV4Iiwib25FcnJvciIsInJlcyIsIml0diIsIkNhbGxIb29rc1R5cGUiLCJQdWJJbnZpdGVDYWxsTWlzc1JlYXNvbiIsIlB1Ykludml0ZUNhbGxNaXNzUmVmZXIiLCJTaWduYWxUcmFuc3BvcnRlciIsIl9ydW50aW1lIiwiX2luaXRPcHRzIiwiX3RpbWVDb3JyZWN0aW9uZXIiLCJnZXRVVUlEMjIiLCJsaXN0ZW5lciIsIm1zZyIsInRvVXNlcnMiLCJ0YXJnZXRUeXBlIiwidGFyZ2V0SWQiLCJuaWNrTmFtZSIsIm9sZFJvb21JZCIsImNhbGxJZHMiLCJvcHRzIiwiUkNDb25uZWN0aW9uU3RhdHVzIiwia2V5Iiwib3B0aW9ucyIsInZhbHVlIiwicmVzdWx0Iiwic2VydmVyS2V5Iiwic2VydmVyVmFsIiwicGFyc2VkRGF0YSIsImluZm8iLCJkZXZpY2VJZCIsImlzTnVsbCIsImlzU3RyaW5nIiwiaXNEaXJlY3RseSIsImN1cnJlbnRVSWQiLCJjdXJyZW50VXNlciIsImRpYWxvZ1R5cGUiLCJhY3Rpb24iLCJleHRyYUtleVZhbCIsImNhbGxTZXNzaW9uVXNlcnMiLCJ0b0RldmljZUlkIiwiY2FsbERpYWxvZ0VudGl0eXMiLCJzdHJpbmcxMHRvNjQiLCJudW1iZXIiLCJjaGFycyIsInJhZGl4IiwicXV0aWVudCIsImFyciIsIm1vZCIsImdldFVVSUQiLCJjIiwiciIsInV1aWQiLCJDQUxMX0RCX05BTUUiLCJEQl9WRVJTSU9OIiwibG9nZ2VyIiwiX1JDQ2FsbEluZGV4REIiLCJyZXEiLCJldiIsIm9iak5hbWUiLCJfYSIsInZhbCIsInJlamVjdCIsIlJDQ2FsbEluZGV4REIiLCJBYm5vcm1hbENhbGwiLCJvYmpTdG9yZSIsInVzZXJBYm5vcm1hbENhbGxJZHMiLCJpZCIsIkNhbGxTZXJ2ZXJFdmVudFR5cGUiLCJSQ0NhbGxQbHVzSW5uZXJDb2RlIiwiVGltZUNvcnJlY3Rpb25lciIsIl9zaW5nbGVDYWxsRHVyYXRpb25FdiIsInNlcnZlclN0YXJ0VGltZSIsImN1cnJlbnRSVFQiLCJjbGllbnRGaXJzdEZyYW1lVGltZSIsIkZvcndhcmRUeXBlIiwiUkNDYWxsUGx1c0ludml0ZVNvdXJjZSIsIlJDQ2FsbERpcmVjdGlvbiIsIkNBTExfVElNRV9PVVQiLCJfUkNDYWxsRW5naW5lIiwiX3JlcG9ydEFwcEV2ZW50TW9kdWxlIiwiY3VycmVudFVzZXJJZCIsImJ1c3lsaW5lVXNlcnMiLCJpbnZpdGVyVGltZXJJZCIsInNlbGZTdGF0ZSIsImludml0ZWVzU3RhdGUiLCJidXN5VXNlcnNTdGF0ZSIsImJ1c3lVc2VySWQiLCJpbnZpdGVkVXNlcnNTdGF0ZSIsImJ1c3lsaW5lVXNlcnNTdGF0ZSIsInRyYW5zYWN0aW9uSWQiLCJyZXFNZWRpYVR5cGUiLCJjYWxsTG9nIiwicmVzRGF0YSIsImxpc3QiLCJ1c2VyU2Vzc2lvblN0YXR1cyIsImNhbGxEaXJlY3Rpb24iLCJzZXNzaW9uVXNlcnMiLCJpbm5lclNlc3Npb24iLCJuZXdVc2VycyIsImlzSWRsZSIsIm5vdyIsImRlbGF5VGltZSIsInN0cmVhbVJlYWR5VGltZSIsImN1cnJlbnRVc2VyU3lzdGVtU3RhdGUiLCJob2xkQ2FsbElkIiwic3RhdGVUaW1lIiwiaW52aXRlVXNlcklkIiwiaW52aXRlZVRpbWVySWQiLCJjYWxsUGx1c1Nlc3Npb24iLCJvdGhlcnNTdGF0ZSIsInN0YXR1c1RpbWUiLCJvdGhlckludml0ZWRNZW1iZXIiLCJfYiIsIl9jIiwiaW52aXRlZE1lbWJlciIsInVzZXJzU3RhdGUiLCJjYWxsU2Vzc2lvbmFTdGF0dXMiLCJzZXNzaW9uU3RhdGUiLCJ1bk5lZWRVcFN0YXRlIiwic3RhcnRDYWxsZXJJZCIsIl9kIiwic2VsZkVuZCIsInN0YXRlcyIsImlzTWFpblNlc3Npb24iLCJjdXJyZW50VXNlclNhdGUiLCJldmVudFRpbWUiLCJldmVudEFyZ3MiLCJldmVudFR5cGUiLCJmcm9tVXNlcklkIiwiZmlyc3RGcmFtZVRpbWUiLCJwcm9tb3RlcklkIiwicmVhc29uIiwiY3VycmVudENhbGxJZCIsIm9sZFRyYW5zSWQiLCJvbGRBY3Rpb24iLCJPbGRNZWRpYVR5cGUiLCJjaGFuZ2VNZWRpYVR5cGVSZXN1bHQiLCJfZSIsImlzU2VsZkhhbmd1cCIsImNsb3NlZFNlc3Npb24iLCJjcnRVc2VyRGF0YSIsImhhbmd1cFJlYXNvbiIsImlzTmVlZFVwIiwiaW52aXRlclVzZXJJZCIsIlJDQ2FsbEVuZ2luZSIsIlJUQ1Jlc291cmNlVGFnIiwiX1JUQ01vZHVsZSIsImRlZmF1bHRWaWRlb1RyYWNrIiwidHJhY2siLCJkZWZhdWx0QXVkaW9UcmFjayIsInZpZGVvQ29uZmlnIiwiYXVkaW9Db25maWciLCJpc0Jvb2xlYW4iLCJsb2NhbFRyYWNrIiwicm9vbSIsInJvb21Vc2Vyc0lkIiwiZXJyb3IiLCJwdWJQYXJhbXMiLCJjdXJyZW50Um9vbUlkIiwicmVjZW50VHJhY2tzIiwibG9jYWxUcmFja3MiLCJuZWVkRGVzdHJveVRyYWNrIiwibmV3VHJhY2siLCJ0cmFja3MiLCJSVENNb2RlIiwic3ViVGlueSIsImJ5U2VydmVyIiwidXNlcklkcyIsInZpZGVvVHJhY2siLCJhdWRpb1RyYWNrIiwiYXVkaW9MZXZlbFJlcG9ydExpc3QiLCJyb29tSWQiLCJraWNrRXh0cmEiLCJSQ0tpY2tSZWFzb24iLCJuZWVkU3ViVHJhY2tzIiwiaXNUaW55IiwicmVwb3J0Iiwic2VuZGVycyIsInJlY2VpdmVycyIsImtpbmQiLCJwYWNrZXRzTG9zdFJhdGUiLCJydHQiLCJ0cmFja0lkIiwiYml0cmF0ZSIsImhlbHBlciIsImxvY2FsVmlkZW9UcmFjayIsImxvY2FsQXVkaW9UcmFjayIsIlJDTG9jYWxUcmFjayIsInZpZGVvRWxlbWVudCIsInN1YlBhcmFtcyIsInVuc3ViVHJhY2tzIiwidmlkZW9WaWV3IiwiUlRDTW9kdWxlIiwiUkNDYWxsUGx1c1JlcG9ydE1vZHVsZSIsImV2ZW50TmFtZSIsImF0dHJzIiwiaGFuZGxlIiwiaW52aXRlZVVzZXJMaXN0IiwicmVjb3JkIiwiY2FsbEZpcnN0RnJhbWVUaW1lIiwiYXVkaW9MZXZlbCIsIkNhbGxTZXJ2ZXJFcnJvckNvZGUiLCJSQ0NhbGxQbHVzQ2xpZW50IiwibmV3U2Vzc2lvbiIsIm1haW5TZXNzaW9uIiwibm90RW1wdHlBcnJheSIsIm5vdEVtcHR5U3RyaW5nIiwiaXNVbmRlZmluZWQiLCJjZmciLCJmcmFtZVJhdGUiLCJlcnJvck1zZyIsImdldE1lZGlhVHJhY2tzQ29kZSIsImdldFNlc3Npb25Db2RlIiwiYnVzeVVzZXJzIiwiaG9sZFNlc3Npb24iLCJoYW5ndXBNYWluU2Vzc2lvbkNvZGUiLCJtYWluU2Vzc2lvbkNhbGxJZCIsImhhbmd1cFNlc3Npb24iLCJ1c2VySW5mbyIsIm9sZE1lZGlhVHlwZSIsInRvVXNlcklkcyIsImlzQWdyZWUiLCJzdGFydFRpbWVzdGFtcCIsImNvdW50IiwidW5tdXRlQ29kZSIsImRldmljZSIsInZhbGlkYXRlSW5pdE9wdHMiLCJpc09iamVjdCIsImlzRnVuY3Rpb24iLCJpbnN0YWxsZXIiLCJydW50aW1lIiwiY29udGV4dCIsInZhbGlkYXRlUmVzIiwiZW5naW5lTG9nZ2VyIiwib3V0cHV0TGV2ZWwiLCJMb2dMIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFHTyxNQUFNQSxJQUFpQjtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBSTVCLFNBQVM7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUlULGFBQWE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUliLGVBQWU7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUlmLGFBQWE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUliLG1CQUFtQjtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBSW5CLGdCQUFnQjtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBSWhCLHlCQUF5QjtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBSXpCLG1CQUFtQjtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBSW5CLGlCQUFpQjtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBSWpCLHdCQUF3QjtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBSXhCLGlCQUFpQjtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBSWpCLHNDQUFzQztBQUFBO0FBQUE7QUFBQTtBQUFBLEVBSXRDLHFCQUFxQjtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBSXJCLGVBQWU7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUlmLG1CQUFtQjtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBSW5CLHlCQUF5QjtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBSXpCLHdCQUF3QjtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBSXhCLG1CQUFtQjtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBSW5CLG9CQUFvQjtBQUN0QjtBQ2hGWSxJQUFBQyxzQkFBQUEsT0FDVkEsRUFBQSxxQ0FBcUMsc0NBSXJDQSxFQUFBLHlDQUF5QywwQ0FJekNBLEVBQUEsMENBQTBDLDJDQUkxQ0EsRUFBQSxpREFBaUQsa0RBQ2pEQSxFQUFBLGtEQUFrRCxtREFJbERBLEVBQUEsdUNBQXVDLHdDQUN2Q0EsRUFBQSx1Q0FBdUMsd0NBQ3ZD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
|