1 | diff --git .gitignore .gitignore |
---|
2 | index 769dc445e..c4f380218 100644 |
---|
3 | --- .gitignore |
---|
4 | +++ .gitignore |
---|
5 | @@ -14,8 +14,8 @@ lib-cov |
---|
6 | pids |
---|
7 | logs |
---|
8 | results |
---|
9 | -src/vendor |
---|
10 | -vendor |
---|
11 | +#src/vendor |
---|
12 | +#vendor |
---|
13 | |
---|
14 | node_modules |
---|
15 | npm-debug.log |
---|
16 | diff --git src/bp-activity/bp-activity-cssjs.php src/bp-activity/bp-activity-cssjs.php |
---|
17 | index ec14cd416..945a0ad75 100644 |
---|
18 | --- src/bp-activity/bp-activity-cssjs.php |
---|
19 | +++ src/bp-activity/bp-activity-cssjs.php |
---|
20 | @@ -33,7 +33,7 @@ function bp_activity_mentions_script() { |
---|
21 | |
---|
22 | $min = bp_core_get_minified_asset_suffix(); |
---|
23 | |
---|
24 | - wp_enqueue_script( 'bp-mentions', buddypress()->plugin_url . "bp-activity/js/mentions{$min}.js", array( 'jquery', 'jquery-atwho' ), bp_get_version(), true ); |
---|
25 | + wp_enqueue_script( 'bp-mentions', buddypress()->plugin_url . "bp-activity/js/mentions{$min}.js", array( 'zurb-tribute' ), bp_get_version(), true ); |
---|
26 | wp_enqueue_style( 'bp-mentions-css', buddypress()->plugin_url . "bp-activity/css/mentions{$min}.css", array(), bp_get_version() ); |
---|
27 | |
---|
28 | wp_style_add_data( 'bp-mentions-css', 'rtl', true ); |
---|
29 | diff --git src/bp-activity/css/mentions.css src/bp-activity/css/mentions.css |
---|
30 | index 7773c75ec..f7bc47d12 100644 |
---|
31 | --- src/bp-activity/css/mentions.css |
---|
32 | +++ src/bp-activity/css/mentions.css |
---|
33 | @@ -1,107 +1,41 @@ |
---|
34 | -.atwho-view { |
---|
35 | - background: rgba(204, 204, 204, 0.8); |
---|
36 | - border-radius: 2px; |
---|
37 | - border: 1px solid rgb(204, 204, 204); |
---|
38 | - box-shadow: 0 0 5px rgba(204, 204, 204, 0.25), 0 0 1px #fff; |
---|
39 | - color: #d84800; |
---|
40 | - display: none; |
---|
41 | - font-family: sans-serif; |
---|
42 | - margin-top: 18px; |
---|
43 | +.tribute-container { |
---|
44 | position: absolute; |
---|
45 | top: 0; |
---|
46 | - z-index: 1000; /* >999 for wp-admin */ |
---|
47 | -} |
---|
48 | - |
---|
49 | -/* rtl:ignore */ |
---|
50 | -.atwho-view { |
---|
51 | left: 0; |
---|
52 | + height: auto; |
---|
53 | + max-height: 300px; |
---|
54 | + max-width: 500px; |
---|
55 | + overflow: auto; |
---|
56 | + display: block; |
---|
57 | + z-index: 999999; |
---|
58 | } |
---|
59 | - |
---|
60 | -.atwho-view ul { |
---|
61 | - background: #fff; |
---|
62 | - list-style: none; |
---|
63 | - margin: auto; |
---|
64 | +.tribute-container ul { |
---|
65 | + margin: 0; |
---|
66 | + margin-top: 2px; |
---|
67 | padding: 0; |
---|
68 | + list-style: none; |
---|
69 | + background: #efefef; |
---|
70 | } |
---|
71 | - |
---|
72 | -.atwho-view ul li { |
---|
73 | - border-bottom: 1px solid #efefef; |
---|
74 | - box-sizing: content-box; |
---|
75 | +.tribute-container li { |
---|
76 | + padding: 5px 5px; |
---|
77 | cursor: pointer; |
---|
78 | - display: block; |
---|
79 | - font-size: 14px; |
---|
80 | - height: 20px; |
---|
81 | - line-height: 20px; |
---|
82 | - margin: 0; |
---|
83 | - overflow: hidden; |
---|
84 | - padding: 5px 10px; |
---|
85 | -} |
---|
86 | - |
---|
87 | -.atwho-view img { |
---|
88 | - border-radius: 2px; |
---|
89 | - float: right; |
---|
90 | - height: 20px; |
---|
91 | - margin-top: 0; |
---|
92 | - width: 20px; |
---|
93 | } |
---|
94 | - |
---|
95 | -.atwho-view strong { |
---|
96 | - background: #efefef; |
---|
97 | - font-weight: 700; |
---|
98 | +.tribute-container li.highlight, .tribute-container li:hover { |
---|
99 | + background: #ddd; |
---|
100 | } |
---|
101 | - |
---|
102 | -.atwho-view .username strong { |
---|
103 | - color: #d54e21; |
---|
104 | +.tribute-container li span { |
---|
105 | + font-weight: bold; |
---|
106 | } |
---|
107 | - |
---|
108 | -.atwho-view small { |
---|
109 | - color: #aaa; |
---|
110 | - float: right; |
---|
111 | - font-size: smaller; |
---|
112 | - font-weight: 400; |
---|
113 | - margin: 0 10px 0 40px; |
---|
114 | +.tribute-container li.no-match { |
---|
115 | + cursor: default; |
---|
116 | } |
---|
117 | - |
---|
118 | -.atwho-view .cur { |
---|
119 | - background: rgba(239, 239, 239, 0.5); |
---|
120 | +.tribute-container .menu-highlighted { |
---|
121 | + font-weight: bold; |
---|
122 | } |
---|
123 | - |
---|
124 | -@media (max-width: 900px) { |
---|
125 | - |
---|
126 | - .atwho-view img { |
---|
127 | - float: left; |
---|
128 | - margin: 0 10px 0 0; |
---|
129 | - } |
---|
130 | -} |
---|
131 | - |
---|
132 | -@media (max-width: 400px) { |
---|
133 | - |
---|
134 | - .atwho-view ul li { |
---|
135 | - font-size: 16px; |
---|
136 | - line-height: 23px; |
---|
137 | - padding: 13px; |
---|
138 | - } |
---|
139 | - |
---|
140 | - .atwho-view ul li img { |
---|
141 | - height: 30px; |
---|
142 | - margin-top: -5px; |
---|
143 | - width: 30px; |
---|
144 | - } |
---|
145 | - |
---|
146 | - .atwho-view { |
---|
147 | - border-radius: 0; |
---|
148 | - left: 0 !important; |
---|
149 | - width: 100%; |
---|
150 | - } |
---|
151 | - |
---|
152 | - .atwho-view ul li .username { |
---|
153 | - display: inline-block; |
---|
154 | - margin: -10px 0 0 0; |
---|
155 | - padding: 10px 0; |
---|
156 | - } |
---|
157 | - |
---|
158 | - .atwho-view ul li small { |
---|
159 | - display: inline-block; |
---|
160 | - margin-left: 20px; |
---|
161 | - } |
---|
162 | +.tribute-container li img { |
---|
163 | + border-radius: 2px; |
---|
164 | + float: right; |
---|
165 | + height: 20px; |
---|
166 | + /*margin-top: 0;*/ |
---|
167 | + width: 20px; |
---|
168 | } |
---|
169 | diff --git src/bp-activity/js/mentions.js src/bp-activity/js/mentions.js |
---|
170 | index 2d0afa3ef..882f3690d 100644 |
---|
171 | --- src/bp-activity/js/mentions.js |
---|
172 | +++ src/bp-activity/js/mentions.js |
---|
173 | @@ -16,241 +16,107 @@ window.bp = window.bp || {}; |
---|
174 | /** |
---|
175 | * Adds BuddyPress @mentions to form inputs. |
---|
176 | * |
---|
177 | - * @param {array|object} options If array, becomes the suggestions' data source. If object, passed as config to $.atwho(). |
---|
178 | + * @param {array} defaultList If array, becomes the suggestions' default data source. |
---|
179 | * @since 2.1.0 |
---|
180 | */ |
---|
181 | - $.fn.bp_mentions = function( options ) { |
---|
182 | - if ( $.isArray( options ) ) { |
---|
183 | - options = { data: options }; |
---|
184 | - } |
---|
185 | - |
---|
186 | - /** |
---|
187 | - * Default options for at.js; see https://github.com/ichord/At.js/. |
---|
188 | - */ |
---|
189 | - var suggestionsDefaults = { |
---|
190 | - delay: 200, |
---|
191 | - hideWithoutSuffix: true, |
---|
192 | - insertTpl: '@${ID}', |
---|
193 | - limit: 10, |
---|
194 | - startWithSpace: false, |
---|
195 | - suffix: '', |
---|
196 | - |
---|
197 | - callbacks: { |
---|
198 | - /** |
---|
199 | - * Custom filter to only match the start of spaced words. |
---|
200 | - * Based on the core/default one. |
---|
201 | - * |
---|
202 | - * @param {string} query |
---|
203 | - * @param {array} data |
---|
204 | - * @param {string} search_key |
---|
205 | - * @return {array} |
---|
206 | - * @since 2.1.0 |
---|
207 | - */ |
---|
208 | - filter: function( query, data, search_key ) { |
---|
209 | - var item, _i, _len, _results = [], |
---|
210 | - regxp = new RegExp( '^' + query + '| ' + query, 'ig' ); // start of string, or preceded by a space. |
---|
211 | - |
---|
212 | - for ( _i = 0, _len = data.length; _i < _len; _i++ ) { |
---|
213 | - item = data[ _i ]; |
---|
214 | - if ( item[ search_key ].toLowerCase().match( regxp ) ) { |
---|
215 | - _results.push( item ); |
---|
216 | - } |
---|
217 | - } |
---|
218 | - |
---|
219 | - return _results; |
---|
220 | - }, |
---|
221 | - |
---|
222 | - /** |
---|
223 | - * Removes some spaces around highlighted string and tweaks regex to allow spaces |
---|
224 | - * (to match display_name). Based on the core default. |
---|
225 | - * |
---|
226 | - * @param {unknown} li |
---|
227 | - * @param {string} query |
---|
228 | - * @return {string} |
---|
229 | - * @since 2.1.0 |
---|
230 | - */ |
---|
231 | - highlighter: function( li, query ) { |
---|
232 | - if ( ! query ) { |
---|
233 | - return li; |
---|
234 | - } |
---|
235 | - |
---|
236 | - var regexp = new RegExp( '>(\\s*|[\\w\\s]*)(' + this.at.replace( '+', '\\+') + '?' + query.replace( '+', '\\+' ) + ')([\\w ]*)\\s*<', 'ig' ); |
---|
237 | - return li.replace( regexp, function( str, $1, $2, $3 ) { |
---|
238 | - return '>' + $1 + '<strong>' + $2 + '</strong>' + $3 + '<'; |
---|
239 | - }); |
---|
240 | - }, |
---|
241 | - |
---|
242 | - /** |
---|
243 | - * Reposition the suggestion list dynamically. |
---|
244 | - * |
---|
245 | - * @param {unknown} offset |
---|
246 | - * @since 2.1.0 |
---|
247 | - */ |
---|
248 | - before_reposition: function( offset ) { |
---|
249 | - // get the iframe, if any, already applied with atwho |
---|
250 | - var caret, |
---|
251 | - line, |
---|
252 | - iframeOffset, |
---|
253 | - move, |
---|
254 | - $view = $( '#atwho-ground-' + this.id + ' .atwho-view' ), |
---|
255 | - $body = $( 'body' ), |
---|
256 | - atwhoDataValue = this.$inputor.data( 'atwho' ); |
---|
257 | - |
---|
258 | - if ( 'undefined' !== atwhoDataValue && 'undefined' !== atwhoDataValue.iframe && null !== atwhoDataValue.iframe ) { |
---|
259 | - caret = this.$inputor.caret( 'offset', { iframe: atwhoDataValue.iframe } ); |
---|
260 | - // Caret.js no longer calculates iframe caret position from the window (it's now just within the iframe). |
---|
261 | - // We need to get the iframe offset from the window and merge that into our object. |
---|
262 | - iframeOffset = $( atwhoDataValue.iframe ).offset(); |
---|
263 | - if ( 'undefined' !== iframeOffset ) { |
---|
264 | - caret.left += iframeOffset.left; |
---|
265 | - caret.top += iframeOffset.top; |
---|
266 | - } |
---|
267 | - } else { |
---|
268 | - caret = this.$inputor.caret( 'offset' ); |
---|
269 | - } |
---|
270 | - |
---|
271 | - // If the caret is past horizontal half, then flip it, yo |
---|
272 | - if ( caret.left > ( $body.width() / 2 ) ) { |
---|
273 | - $view.addClass( 'right' ); |
---|
274 | - move = caret.left - offset.left - this.view.$el.width(); |
---|
275 | - } else { |
---|
276 | - $view.removeClass( 'right' ); |
---|
277 | - move = caret.left - offset.left + 1; |
---|
278 | - } |
---|
279 | - |
---|
280 | - // If we're on a small screen, scroll to caret |
---|
281 | - if ( $body.width() <= 400 ) { |
---|
282 | - $( document ).scrollTop( caret.top - 6 ); |
---|
283 | - } |
---|
284 | + $.fn.bp_mentions = function( defaultList ) { |
---|
285 | + var debouncer = function(func, wait) { |
---|
286 | + let timeout; |
---|
287 | + |
---|
288 | + return function() { |
---|
289 | + var context = this; |
---|
290 | + var args = arguments; |
---|
291 | + |
---|
292 | + var callFunction = function() { |
---|
293 | + func.apply(context, args) |
---|
294 | + }; |
---|
295 | + |
---|
296 | + clearTimeout(timeout); |
---|
297 | + timeout = setTimeout(callFunction, wait); |
---|
298 | + } |
---|
299 | + }; |
---|
300 | + |
---|
301 | + var remoteSearch = function(text, cb) { |
---|
302 | + /** |
---|
303 | + * Immediately show the pre-created friends list, if it's populated, |
---|
304 | + * and the user has hesitated after hitting @ (no search text provided). |
---|
305 | + */ |
---|
306 | + if ( text.length === 0 && $.isArray( defaultList ) && defaultList.length > 0) { |
---|
307 | + cb(defaultList); |
---|
308 | + return; |
---|
309 | + } |
---|
310 | |
---|
311 | - // New position is under the caret (never above) and positioned to follow |
---|
312 | - // Dynamic sizing based on the input area (remove 'px' from end) |
---|
313 | - line = parseInt( this.$inputor.css( 'line-height' ).substr( 0, this.$inputor.css( 'line-height' ).length - 2 ), 10 ); |
---|
314 | - if ( !line || line < 5 ) { // sanity check, and catch no line-height |
---|
315 | - line = 19; |
---|
316 | - } |
---|
317 | + mentionsItem = mentionsQueryCache[ text ]; |
---|
318 | + if ( typeof mentionsItem === 'object' ) { |
---|
319 | + cb(mentionsItem); |
---|
320 | + return; |
---|
321 | + } |
---|
322 | |
---|
323 | - offset.top = caret.top + line; |
---|
324 | - offset.left += move; |
---|
325 | - }, |
---|
326 | + var params = { 'action': 'bp_get_suggestions', 'term': text, 'type': 'members' }; |
---|
327 | |
---|
328 | - /** |
---|
329 | - * Override default behaviour which inserts junk tags in the WordPress Visual editor. |
---|
330 | - * |
---|
331 | - * @param {unknown} $inputor Element which we're inserting content into. |
---|
332 | - * @param {string) content The content that will be inserted. |
---|
333 | - * @param {string) suffix Applied to the end of the content string. |
---|
334 | - * @return {string} |
---|
335 | - * @since 2.1.0 |
---|
336 | - */ |
---|
337 | - inserting_wrapper: function( $inputor, content, suffix ) { |
---|
338 | - return '' + content + suffix; |
---|
339 | - } |
---|
340 | + // Add the group ID to the request if group ID data is attached to the input. |
---|
341 | + if ( ".wp-editor-area" === $( this ).selector |
---|
342 | + && typeof document.activeElement !== undefined |
---|
343 | + && typeof document.activeElement.dataset !== undefined |
---|
344 | + && document.activeElement.dataset.suggestionsGroupId !== undefined |
---|
345 | + && $.isNumeric( document.activeElement.dataset.suggestionsGroupId ) ) { |
---|
346 | + params['group-id'] = parseInt( document.activeElement.dataset.suggestionsGroupId, 10 ); |
---|
347 | } |
---|
348 | - }, |
---|
349 | |
---|
350 | - /** |
---|
351 | - * Default options for our @mentions; see https://github.com/ichord/At.js/. |
---|
352 | - */ |
---|
353 | - mentionsDefaults = { |
---|
354 | - callbacks: { |
---|
355 | + return $.getJSON( ajaxurl, params ) |
---|
356 | /** |
---|
357 | - * If there are no matches for the query in this.data, then query BuddyPress. |
---|
358 | + * Success callback for the @suggestions lookup. |
---|
359 | * |
---|
360 | - * @param {string} query Partial @mention to search for. |
---|
361 | - * @param {function} render_view Render page callback function. |
---|
362 | + * @param {object} response Details of users matching the query. |
---|
363 | * @since 2.1.0 |
---|
364 | - * @since 3.0.0. Renamed from "remote_filter" for at.js v1.5.4 support. |
---|
365 | */ |
---|
366 | - remoteFilter: function( query, render_view ) { |
---|
367 | - var self = $( this ), |
---|
368 | - params = {}; |
---|
369 | - |
---|
370 | - mentionsItem = mentionsQueryCache[ query ]; |
---|
371 | - if ( typeof mentionsItem === 'object' ) { |
---|
372 | - render_view( mentionsItem ); |
---|
373 | + .done(function( response ) { |
---|
374 | + if ( ! response.success ) { |
---|
375 | + cb([]); |
---|
376 | return; |
---|
377 | } |
---|
378 | |
---|
379 | - if ( self.xhr ) { |
---|
380 | - self.xhr.abort(); |
---|
381 | - } |
---|
382 | - |
---|
383 | - params = { 'action': 'bp_get_suggestions', 'term': query, 'type': 'members' }; |
---|
384 | - |
---|
385 | - if ( $.isNumeric( this.$inputor.data( 'suggestions-group-id' ) ) ) { |
---|
386 | - params['group-id'] = parseInt( this.$inputor.data( 'suggestions-group-id' ), 10 ); |
---|
387 | - } |
---|
388 | - |
---|
389 | - self.xhr = $.getJSON( ajaxurl, params ) |
---|
390 | + var data = $.map( response.data, |
---|
391 | /** |
---|
392 | - * Success callback for the @suggestions lookup. |
---|
393 | + * Create a composite index to determine ordering of results; |
---|
394 | + * nicename matches will appear on top. |
---|
395 | * |
---|
396 | - * @param {object} response Details of users matching the query. |
---|
397 | + * @param {array} suggestion A suggestion's original data. |
---|
398 | + * @return {array} A suggestion's new data. |
---|
399 | * @since 2.1.0 |
---|
400 | */ |
---|
401 | - .done(function( response ) { |
---|
402 | - if ( ! response.success ) { |
---|
403 | - return; |
---|
404 | - } |
---|
405 | + function( suggestion ) { |
---|
406 | + suggestion.search = suggestion.search || suggestion.ID + ' ' + suggestion.name; |
---|
407 | + return suggestion; |
---|
408 | + } |
---|
409 | + ); |
---|
410 | |
---|
411 | - var data = $.map( response.data, |
---|
412 | - /** |
---|
413 | - * Create a composite index to determine ordering of results; |
---|
414 | - * nicename matches will appear on top. |
---|
415 | - * |
---|
416 | - * @param {array} suggestion A suggestion's original data. |
---|
417 | - * @return {array} A suggestion's new data. |
---|
418 | - * @since 2.1.0 |
---|
419 | - */ |
---|
420 | - function( suggestion ) { |
---|
421 | - suggestion.search = suggestion.search || suggestion.ID + ' ' + suggestion.name; |
---|
422 | - return suggestion; |
---|
423 | - } |
---|
424 | - ); |
---|
425 | + mentionsQueryCache[ text ] = data; |
---|
426 | + cb(data); |
---|
427 | + }); |
---|
428 | + } |
---|
429 | |
---|
430 | - mentionsQueryCache[ query ] = data; |
---|
431 | - render_view( data ); |
---|
432 | - }); |
---|
433 | - } |
---|
434 | + var tributeParams = { |
---|
435 | + values: debouncer( function (text, cb) { |
---|
436 | + remoteSearch(text, users => cb(users)); |
---|
437 | + }, 250), |
---|
438 | + lookup: 'search', |
---|
439 | + fillAttr: 'ID', |
---|
440 | + menuItemTemplate: function (item) { |
---|
441 | + return '<img src="' + item.original.image + '" alt="Profile picture of ' + item.original.name + '"> @' + item.string; |
---|
442 | }, |
---|
443 | + }; |
---|
444 | |
---|
445 | - data: $.map( options.data, |
---|
446 | - /** |
---|
447 | - * Create a composite index to search against of nicename + display name. |
---|
448 | - * This will also determine ordering of results, so nicename matches will appear on top. |
---|
449 | - * |
---|
450 | - * @param {array} suggestion A suggestion's original data. |
---|
451 | - * @return {array} A suggestion's new data. |
---|
452 | - * @since 2.1.0 |
---|
453 | - */ |
---|
454 | - function( suggestion ) { |
---|
455 | - suggestion.search = suggestion.search || suggestion.ID + ' ' + suggestion.name; |
---|
456 | - return suggestion; |
---|
457 | - } |
---|
458 | - ), |
---|
459 | + var tribute = new Tribute( tributeParams ); |
---|
460 | |
---|
461 | - at: '@', |
---|
462 | - searchKey: 'search', |
---|
463 | - displayTpl: '<li data-value="@${ID}"><img src="${image}" /><span class="username">@${ID}</span><small>${name}</small></li>' |
---|
464 | - }, |
---|
465 | - |
---|
466 | - opts = $.extend( true, {}, suggestionsDefaults, mentionsDefaults, options ); |
---|
467 | - return $.fn.atwho.call( this, opts ); |
---|
468 | + $( this ).each( function() { |
---|
469 | + tribute.attach( document.getElementById( $(this).attr("id") ) ); |
---|
470 | + }); |
---|
471 | }; |
---|
472 | |
---|
473 | $( document ).ready(function() { |
---|
474 | // Activity/reply, post comments, dashboard post 'text' editor. |
---|
475 | - $( '.bp-suggestions, #comments form textarea, .wp-editor-area' ).bp_mentions( bp.mentions.users ); |
---|
476 | + $( '.bp-suggestions, #comments form textarea' ).bp_mentions( bp.mentions.users ); |
---|
477 | }); |
---|
478 | |
---|
479 | - bp.mentions.tinyMCEinit = function() { |
---|
480 | - if ( typeof window.tinyMCE === 'undefined' || window.tinyMCE.activeEditor === null || typeof window.tinyMCE.activeEditor === 'undefined' ) { |
---|
481 | - return; |
---|
482 | - } else { |
---|
483 | - $( window.tinyMCE.activeEditor.contentDocument.activeElement ) |
---|
484 | - .atwho( 'setIframe', $( '.wp-editor-wrap iframe' )[0] ) |
---|
485 | - .bp_mentions( bp.mentions.users ); |
---|
486 | - } |
---|
487 | - }; |
---|
488 | })( bp, jQuery ); |
---|
489 | diff --git src/bp-core/bp-core-cssjs.php src/bp-core/bp-core-cssjs.php |
---|
490 | index 987deb642..4d9eff26a 100644 |
---|
491 | --- src/bp-core/bp-core-cssjs.php |
---|
492 | +++ src/bp-core/bp-core-cssjs.php |
---|
493 | @@ -54,10 +54,6 @@ function bp_core_register_common_scripts() { |
---|
494 | 'bp-jquery-cookie' => array( 'file' => "{$url}vendor/jquery-cookie{$min}.js", 'dependencies' => array( 'jquery' ), 'footer' => false ), |
---|
495 | 'bp-jquery-scroll-to' => array( 'file' => "{$url}vendor/jquery-scroll-to{$min}.js", 'dependencies' => array( 'jquery' ), 'footer' => false ), |
---|
496 | |
---|
497 | - // Version 2.1. |
---|
498 | - 'jquery-caret' => array( 'file' => "{$url}vendor/jquery.caret{$min}.js", 'dependencies' => array( 'jquery' ), 'footer' => true ), |
---|
499 | - 'jquery-atwho' => array( 'file' => "{$url}vendor/jquery.atwho{$min}.js", 'dependencies' => array( 'jquery', 'jquery-caret' ), 'footer' => true ), |
---|
500 | - |
---|
501 | // Version 2.3. |
---|
502 | 'bp-plupload' => array( 'file' => "{$url}bp-plupload{$min}.js", 'dependencies' => array( 'plupload', 'jquery', 'json2', 'wp-backbone' ), 'footer' => true ), |
---|
503 | 'bp-avatar' => array( 'file' => "{$url}avatar{$min}.js", 'dependencies' => array( 'jcrop' ), 'footer' => true ), |
---|
504 | @@ -69,6 +65,9 @@ function bp_core_register_common_scripts() { |
---|
505 | // Version 2.7. |
---|
506 | 'bp-moment' => array( 'file' => "{$url}vendor/moment-js/moment{$min}.js", 'dependencies' => array(), 'footer' => true ), |
---|
507 | 'bp-livestamp' => array( 'file' => "{$url}vendor/livestamp{$min}.js", 'dependencies' => array( 'jquery', 'bp-moment' ), 'footer' => true ), |
---|
508 | + |
---|
509 | + // Version 5 |
---|
510 | + 'zurb-tribute' => array( 'file' => "{$url}vendor/tribute{$min}.js", 'dependencies' => array(), 'footer' => true ), |
---|
511 | ); |
---|
512 | |
---|
513 | // Version 2.7 - Add Moment.js locale to our $scripts array if we found one. |
---|
514 | diff --git src/bp-core/js/vendor/jquery.atwho.js src/bp-core/js/vendor/jquery.atwho.js |
---|
515 | deleted file mode 100755 |
---|
516 | index 795b6c67d..000000000 |
---|
517 | --- src/bp-core/js/vendor/jquery.atwho.js |
---|
518 | +++ /dev/null |
---|
519 | @@ -1,1212 +0,0 @@ |
---|
520 | -/** |
---|
521 | - * at.js - 1.5.4 |
---|
522 | - * Copyright (c) 2017 chord.luo <chord.luo@gmail.com>; |
---|
523 | - * Homepage: http://ichord.github.com/At.js |
---|
524 | - * License: MIT |
---|
525 | - */ |
---|
526 | -(function (root, factory) { |
---|
527 | - if (typeof define === 'function' && define.amd) { |
---|
528 | - // AMD. Register as an anonymous module unless amdModuleId is set |
---|
529 | - define(["jquery"], function (a0) { |
---|
530 | - return (factory(a0)); |
---|
531 | - }); |
---|
532 | - } else if (typeof exports === 'object') { |
---|
533 | - // Node. Does not work with strict CommonJS, but |
---|
534 | - // only CommonJS-like environments that support module.exports, |
---|
535 | - // like Node. |
---|
536 | - module.exports = factory(require("jquery")); |
---|
537 | - } else { |
---|
538 | - factory(jQuery); |
---|
539 | - } |
---|
540 | -}(this, function ($) { |
---|
541 | -var DEFAULT_CALLBACKS, KEY_CODE; |
---|
542 | - |
---|
543 | -KEY_CODE = { |
---|
544 | - ESC: 27, |
---|
545 | - TAB: 9, |
---|
546 | - ENTER: 13, |
---|
547 | - CTRL: 17, |
---|
548 | - A: 65, |
---|
549 | - P: 80, |
---|
550 | - N: 78, |
---|
551 | - LEFT: 37, |
---|
552 | - UP: 38, |
---|
553 | - RIGHT: 39, |
---|
554 | - DOWN: 40, |
---|
555 | - BACKSPACE: 8, |
---|
556 | - SPACE: 32 |
---|
557 | -}; |
---|
558 | - |
---|
559 | -DEFAULT_CALLBACKS = { |
---|
560 | - beforeSave: function(data) { |
---|
561 | - return Controller.arrayToDefaultHash(data); |
---|
562 | - }, |
---|
563 | - matcher: function(flag, subtext, should_startWithSpace, acceptSpaceBar) { |
---|
564 | - var _a, _y, match, regexp, space; |
---|
565 | - flag = flag.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); |
---|
566 | - if (should_startWithSpace) { |
---|
567 | - flag = '(?:^|\\s)' + flag; |
---|
568 | - } |
---|
569 | - _a = decodeURI("%C3%80"); |
---|
570 | - _y = decodeURI("%C3%BF"); |
---|
571 | - space = acceptSpaceBar ? "\ " : ""; |
---|
572 | - regexp = new RegExp(flag + "([A-Za-z" + _a + "-" + _y + "0-9_" + space + "\'\.\+\-]*)$|" + flag + "([^\\x00-\\xff]*)$", 'gi'); |
---|
573 | - match = regexp.exec(subtext); |
---|
574 | - if (match) { |
---|
575 | - return match[2] || match[1]; |
---|
576 | - } else { |
---|
577 | - return null; |
---|
578 | - } |
---|
579 | - }, |
---|
580 | - filter: function(query, data, searchKey) { |
---|
581 | - var _results, i, item, len; |
---|
582 | - _results = []; |
---|
583 | - for (i = 0, len = data.length; i < len; i++) { |
---|
584 | - item = data[i]; |
---|
585 | - if (~new String(item[searchKey]).toLowerCase().indexOf(query.toLowerCase())) { |
---|
586 | - _results.push(item); |
---|
587 | - } |
---|
588 | - } |
---|
589 | - return _results; |
---|
590 | - }, |
---|
591 | - remoteFilter: null, |
---|
592 | - sorter: function(query, items, searchKey) { |
---|
593 | - var _results, i, item, len; |
---|
594 | - if (!query) { |
---|
595 | - return items; |
---|
596 | - } |
---|
597 | - _results = []; |
---|
598 | - for (i = 0, len = items.length; i < len; i++) { |
---|
599 | - item = items[i]; |
---|
600 | - item.atwho_order = new String(item[searchKey]).toLowerCase().indexOf(query.toLowerCase()); |
---|
601 | - if (item.atwho_order > -1) { |
---|
602 | - _results.push(item); |
---|
603 | - } |
---|
604 | - } |
---|
605 | - return _results.sort(function(a, b) { |
---|
606 | - return a.atwho_order - b.atwho_order; |
---|
607 | - }); |
---|
608 | - }, |
---|
609 | - tplEval: function(tpl, map) { |
---|
610 | - var error, error1, template; |
---|
611 | - template = tpl; |
---|
612 | - try { |
---|
613 | - if (typeof tpl !== 'string') { |
---|
614 | - template = tpl(map); |
---|
615 | - } |
---|
616 | - return template.replace(/\$\{([^\}]*)\}/g, function(tag, key, pos) { |
---|
617 | - return map[key]; |
---|
618 | - }); |
---|
619 | - } catch (error1) { |
---|
620 | - error = error1; |
---|
621 | - return ""; |
---|
622 | - } |
---|
623 | - }, |
---|
624 | - highlighter: function(li, query) { |
---|
625 | - var regexp; |
---|
626 | - if (!query) { |
---|
627 | - return li; |
---|
628 | - } |
---|
629 | - regexp = new RegExp(">\\s*([^\<]*?)(" + query.replace("+", "\\+") + ")([^\<]*)\\s*<", 'ig'); |
---|
630 | - return li.replace(regexp, function(str, $1, $2, $3) { |
---|
631 | - return '> ' + $1 + '<strong>' + $2 + '</strong>' + $3 + ' <'; |
---|
632 | - }); |
---|
633 | - }, |
---|
634 | - beforeInsert: function(value, $li, e) { |
---|
635 | - return value; |
---|
636 | - }, |
---|
637 | - beforeReposition: function(offset) { |
---|
638 | - return offset; |
---|
639 | - }, |
---|
640 | - afterMatchFailed: function(at, el) {} |
---|
641 | -}; |
---|
642 | - |
---|
643 | -var App; |
---|
644 | - |
---|
645 | -App = (function() { |
---|
646 | - function App(inputor) { |
---|
647 | - this.currentFlag = null; |
---|
648 | - this.controllers = {}; |
---|
649 | - this.aliasMaps = {}; |
---|
650 | - this.$inputor = $(inputor); |
---|
651 | - this.setupRootElement(); |
---|
652 | - this.listen(); |
---|
653 | - } |
---|
654 | - |
---|
655 | - App.prototype.createContainer = function(doc) { |
---|
656 | - var ref; |
---|
657 | - if ((ref = this.$el) != null) { |
---|
658 | - ref.remove(); |
---|
659 | - } |
---|
660 | - return $(doc.body).append(this.$el = $("<div class='atwho-container'></div>")); |
---|
661 | - }; |
---|
662 | - |
---|
663 | - App.prototype.setupRootElement = function(iframe, asRoot) { |
---|
664 | - var error, error1; |
---|
665 | - if (asRoot == null) { |
---|
666 | - asRoot = false; |
---|
667 | - } |
---|
668 | - if (iframe) { |
---|
669 | - this.window = iframe.contentWindow; |
---|
670 | - this.document = iframe.contentDocument || this.window.document; |
---|
671 | - this.iframe = iframe; |
---|
672 | - } else { |
---|
673 | - this.document = this.$inputor[0].ownerDocument; |
---|
674 | - this.window = this.document.defaultView || this.document.parentWindow; |
---|
675 | - try { |
---|
676 | - this.iframe = this.window.frameElement; |
---|
677 | - } catch (error1) { |
---|
678 | - error = error1; |
---|
679 | - this.iframe = null; |
---|
680 | - if ($.fn.atwho.debug) { |
---|
681 | - throw new Error("iframe auto-discovery is failed.\nPlease use `setIframe` to set the target iframe manually.\n" + error); |
---|
682 | - } |
---|
683 | - } |
---|
684 | - } |
---|
685 | - return this.createContainer((this.iframeAsRoot = asRoot) ? this.document : document); |
---|
686 | - }; |
---|
687 | - |
---|
688 | - App.prototype.controller = function(at) { |
---|
689 | - var c, current, currentFlag, ref; |
---|
690 | - if (this.aliasMaps[at]) { |
---|
691 | - current = this.controllers[this.aliasMaps[at]]; |
---|
692 | - } else { |
---|
693 | - ref = this.controllers; |
---|
694 | - for (currentFlag in ref) { |
---|
695 | - c = ref[currentFlag]; |
---|
696 | - if (currentFlag === at) { |
---|
697 | - current = c; |
---|
698 | - break; |
---|
699 | - } |
---|
700 | - } |
---|
701 | - } |
---|
702 | - if (current) { |
---|
703 | - return current; |
---|
704 | - } else { |
---|
705 | - return this.controllers[this.currentFlag]; |
---|
706 | - } |
---|
707 | - }; |
---|
708 | - |
---|
709 | - App.prototype.setContextFor = function(at) { |
---|
710 | - this.currentFlag = at; |
---|
711 | - return this; |
---|
712 | - }; |
---|
713 | - |
---|
714 | - App.prototype.reg = function(flag, setting) { |
---|
715 | - var base, controller; |
---|
716 | - controller = (base = this.controllers)[flag] || (base[flag] = this.$inputor.is('[contentEditable]') ? new EditableController(this, flag) : new TextareaController(this, flag)); |
---|
717 | - if (setting.alias) { |
---|
718 | - this.aliasMaps[setting.alias] = flag; |
---|
719 | - } |
---|
720 | - controller.init(setting); |
---|
721 | - return this; |
---|
722 | - }; |
---|
723 | - |
---|
724 | - App.prototype.listen = function() { |
---|
725 | - return this.$inputor.on('compositionstart', (function(_this) { |
---|
726 | - return function(e) { |
---|
727 | - var ref; |
---|
728 | - if ((ref = _this.controller()) != null) { |
---|
729 | - ref.view.hide(); |
---|
730 | - } |
---|
731 | - _this.isComposing = true; |
---|
732 | - return null; |
---|
733 | - }; |
---|
734 | - })(this)).on('compositionend', (function(_this) { |
---|
735 | - return function(e) { |
---|
736 | - _this.isComposing = false; |
---|
737 | - setTimeout(function(e) { |
---|
738 | - return _this.dispatch(e); |
---|
739 | - }); |
---|
740 | - return null; |
---|
741 | - }; |
---|
742 | - })(this)).on('keyup.atwhoInner', (function(_this) { |
---|
743 | - return function(e) { |
---|
744 | - return _this.onKeyup(e); |
---|
745 | - }; |
---|
746 | - })(this)).on('keydown.atwhoInner', (function(_this) { |
---|
747 | - return function(e) { |
---|
748 | - return _this.onKeydown(e); |
---|
749 | - }; |
---|
750 | - })(this)).on('blur.atwhoInner', (function(_this) { |
---|
751 | - return function(e) { |
---|
752 | - var c; |
---|
753 | - if (c = _this.controller()) { |
---|
754 | - c.expectedQueryCBId = null; |
---|
755 | - return c.view.hide(e, c.getOpt("displayTimeout")); |
---|
756 | - } |
---|
757 | - }; |
---|
758 | - })(this)).on('click.atwhoInner', (function(_this) { |
---|
759 | - return function(e) { |
---|
760 | - return _this.dispatch(e); |
---|
761 | - }; |
---|
762 | - })(this)).on('scroll.atwhoInner', (function(_this) { |
---|
763 | - return function() { |
---|
764 | - var lastScrollTop; |
---|
765 | - lastScrollTop = _this.$inputor.scrollTop(); |
---|
766 | - return function(e) { |
---|
767 | - var currentScrollTop, ref; |
---|
768 | - currentScrollTop = e.target.scrollTop; |
---|
769 | - if (lastScrollTop !== currentScrollTop) { |
---|
770 | - if ((ref = _this.controller()) != null) { |
---|
771 | - ref.view.hide(e); |
---|
772 | - } |
---|
773 | - } |
---|
774 | - lastScrollTop = currentScrollTop; |
---|
775 | - return true; |
---|
776 | - }; |
---|
777 | - }; |
---|
778 | - })(this)()); |
---|
779 | - }; |
---|
780 | - |
---|
781 | - App.prototype.shutdown = function() { |
---|
782 | - var _, c, ref; |
---|
783 | - ref = this.controllers; |
---|
784 | - for (_ in ref) { |
---|
785 | - c = ref[_]; |
---|
786 | - c.destroy(); |
---|
787 | - delete this.controllers[_]; |
---|
788 | - } |
---|
789 | - this.$inputor.off('.atwhoInner'); |
---|
790 | - return this.$el.remove(); |
---|
791 | - }; |
---|
792 | - |
---|
793 | - App.prototype.dispatch = function(e) { |
---|
794 | - var _, c, ref, results; |
---|
795 | - ref = this.controllers; |
---|
796 | - results = []; |
---|
797 | - for (_ in ref) { |
---|
798 | - c = ref[_]; |
---|
799 | - results.push(c.lookUp(e)); |
---|
800 | - } |
---|
801 | - return results; |
---|
802 | - }; |
---|
803 | - |
---|
804 | - App.prototype.onKeyup = function(e) { |
---|
805 | - var ref; |
---|
806 | - switch (e.keyCode) { |
---|
807 | - case KEY_CODE.ESC: |
---|
808 | - e.preventDefault(); |
---|
809 | - if ((ref = this.controller()) != null) { |
---|
810 | - ref.view.hide(); |
---|
811 | - } |
---|
812 | - break; |
---|
813 | - case KEY_CODE.DOWN: |
---|
814 | - case KEY_CODE.UP: |
---|
815 | - case KEY_CODE.CTRL: |
---|
816 | - case KEY_CODE.ENTER: |
---|
817 | - $.noop(); |
---|
818 | - break; |
---|
819 | - case KEY_CODE.P: |
---|
820 | - case KEY_CODE.N: |
---|
821 | - if (!e.ctrlKey) { |
---|
822 | - this.dispatch(e); |
---|
823 | - } |
---|
824 | - break; |
---|
825 | - default: |
---|
826 | - this.dispatch(e); |
---|
827 | - } |
---|
828 | - }; |
---|
829 | - |
---|
830 | - App.prototype.onKeydown = function(e) { |
---|
831 | - var ref, view; |
---|
832 | - view = (ref = this.controller()) != null ? ref.view : void 0; |
---|
833 | - if (!(view && view.visible())) { |
---|
834 | - return; |
---|
835 | - } |
---|
836 | - switch (e.keyCode) { |
---|
837 | - case KEY_CODE.ESC: |
---|
838 | - e.preventDefault(); |
---|
839 | - view.hide(e); |
---|
840 | - break; |
---|
841 | - case KEY_CODE.UP: |
---|
842 | - e.preventDefault(); |
---|
843 | - view.prev(); |
---|
844 | - break; |
---|
845 | - case KEY_CODE.DOWN: |
---|
846 | - e.preventDefault(); |
---|
847 | - view.next(); |
---|
848 | - break; |
---|
849 | - case KEY_CODE.P: |
---|
850 | - if (!e.ctrlKey) { |
---|
851 | - return; |
---|
852 | - } |
---|
853 | - e.preventDefault(); |
---|
854 | - view.prev(); |
---|
855 | - break; |
---|
856 | - case KEY_CODE.N: |
---|
857 | - if (!e.ctrlKey) { |
---|
858 | - return; |
---|
859 | - } |
---|
860 | - e.preventDefault(); |
---|
861 | - view.next(); |
---|
862 | - break; |
---|
863 | - case KEY_CODE.TAB: |
---|
864 | - case KEY_CODE.ENTER: |
---|
865 | - case KEY_CODE.SPACE: |
---|
866 | - if (!view.visible()) { |
---|
867 | - return; |
---|
868 | - } |
---|
869 | - if (!this.controller().getOpt('spaceSelectsMatch') && e.keyCode === KEY_CODE.SPACE) { |
---|
870 | - return; |
---|
871 | - } |
---|
872 | - if (!this.controller().getOpt('tabSelectsMatch') && e.keyCode === KEY_CODE.TAB) { |
---|
873 | - return; |
---|
874 | - } |
---|
875 | - if (view.highlighted()) { |
---|
876 | - e.preventDefault(); |
---|
877 | - view.choose(e); |
---|
878 | - } else { |
---|
879 | - view.hide(e); |
---|
880 | - } |
---|
881 | - break; |
---|
882 | - default: |
---|
883 | - $.noop(); |
---|
884 | - } |
---|
885 | - }; |
---|
886 | - |
---|
887 | - return App; |
---|
888 | - |
---|
889 | -})(); |
---|
890 | - |
---|
891 | -var Controller, |
---|
892 | - slice = [].slice; |
---|
893 | - |
---|
894 | -Controller = (function() { |
---|
895 | - Controller.prototype.uid = function() { |
---|
896 | - return (Math.random().toString(16) + "000000000").substr(2, 8) + (new Date().getTime()); |
---|
897 | - }; |
---|
898 | - |
---|
899 | - function Controller(app, at1) { |
---|
900 | - this.app = app; |
---|
901 | - this.at = at1; |
---|
902 | - this.$inputor = this.app.$inputor; |
---|
903 | - this.id = this.$inputor[0].id || this.uid(); |
---|
904 | - this.expectedQueryCBId = null; |
---|
905 | - this.setting = null; |
---|
906 | - this.query = null; |
---|
907 | - this.pos = 0; |
---|
908 | - this.range = null; |
---|
909 | - if ((this.$el = $("#atwho-ground-" + this.id, this.app.$el)).length === 0) { |
---|
910 | - this.app.$el.append(this.$el = $("<div id='atwho-ground-" + this.id + "'></div>")); |
---|
911 | - } |
---|
912 | - this.model = new Model(this); |
---|
913 | - this.view = new View(this); |
---|
914 | - } |
---|
915 | - |
---|
916 | - Controller.prototype.init = function(setting) { |
---|
917 | - this.setting = $.extend({}, this.setting || $.fn.atwho["default"], setting); |
---|
918 | - this.view.init(); |
---|
919 | - return this.model.reload(this.setting.data); |
---|
920 | - }; |
---|
921 | - |
---|
922 | - Controller.prototype.destroy = function() { |
---|
923 | - this.trigger('beforeDestroy'); |
---|
924 | - this.model.destroy(); |
---|
925 | - this.view.destroy(); |
---|
926 | - return this.$el.remove(); |
---|
927 | - }; |
---|
928 | - |
---|
929 | - Controller.prototype.callDefault = function() { |
---|
930 | - var args, error, error1, funcName; |
---|
931 | - funcName = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; |
---|
932 | - try { |
---|
933 | - return DEFAULT_CALLBACKS[funcName].apply(this, args); |
---|
934 | - } catch (error1) { |
---|
935 | - error = error1; |
---|
936 | - return $.error(error + " Or maybe At.js doesn't have function " + funcName); |
---|
937 | - } |
---|
938 | - }; |
---|
939 | - |
---|
940 | - Controller.prototype.trigger = function(name, data) { |
---|
941 | - var alias, eventName; |
---|
942 | - if (data == null) { |
---|
943 | - data = []; |
---|
944 | - } |
---|
945 | - data.push(this); |
---|
946 | - alias = this.getOpt('alias'); |
---|
947 | - eventName = alias ? name + "-" + alias + ".atwho" : name + ".atwho"; |
---|
948 | - return this.$inputor.trigger(eventName, data); |
---|
949 | - }; |
---|
950 | - |
---|
951 | - Controller.prototype.callbacks = function(funcName) { |
---|
952 | - return this.getOpt("callbacks")[funcName] || DEFAULT_CALLBACKS[funcName]; |
---|
953 | - }; |
---|
954 | - |
---|
955 | - Controller.prototype.getOpt = function(at, default_value) { |
---|
956 | - var e, error1; |
---|
957 | - try { |
---|
958 | - return this.setting[at]; |
---|
959 | - } catch (error1) { |
---|
960 | - e = error1; |
---|
961 | - return null; |
---|
962 | - } |
---|
963 | - }; |
---|
964 | - |
---|
965 | - Controller.prototype.insertContentFor = function($li) { |
---|
966 | - var data, tpl; |
---|
967 | - tpl = this.getOpt('insertTpl'); |
---|
968 | - data = $.extend({}, $li.data('item-data'), { |
---|
969 | - 'atwho-at': this.at |
---|
970 | - }); |
---|
971 | - return this.callbacks("tplEval").call(this, tpl, data, "onInsert"); |
---|
972 | - }; |
---|
973 | - |
---|
974 | - Controller.prototype.renderView = function(data) { |
---|
975 | - var searchKey; |
---|
976 | - searchKey = this.getOpt("searchKey"); |
---|
977 | - data = this.callbacks("sorter").call(this, this.query.text, data.slice(0, 1001), searchKey); |
---|
978 | - return this.view.render(data.slice(0, this.getOpt('limit'))); |
---|
979 | - }; |
---|
980 | - |
---|
981 | - Controller.arrayToDefaultHash = function(data) { |
---|
982 | - var i, item, len, results; |
---|
983 | - if (!$.isArray(data)) { |
---|
984 | - return data; |
---|
985 | - } |
---|
986 | - results = []; |
---|
987 | - for (i = 0, len = data.length; i < len; i++) { |
---|
988 | - item = data[i]; |
---|
989 | - if ($.isPlainObject(item)) { |
---|
990 | - results.push(item); |
---|
991 | - } else { |
---|
992 | - results.push({ |
---|
993 | - name: item |
---|
994 | - }); |
---|
995 | - } |
---|
996 | - } |
---|
997 | - return results; |
---|
998 | - }; |
---|
999 | - |
---|
1000 | - Controller.prototype.lookUp = function(e) { |
---|
1001 | - var query, wait; |
---|
1002 | - if (e && e.type === 'click' && !this.getOpt('lookUpOnClick')) { |
---|
1003 | - return; |
---|
1004 | - } |
---|
1005 | - if (this.getOpt('suspendOnComposing') && this.app.isComposing) { |
---|
1006 | - return; |
---|
1007 | - } |
---|
1008 | - query = this.catchQuery(e); |
---|
1009 | - if (!query) { |
---|
1010 | - this.expectedQueryCBId = null; |
---|
1011 | - return query; |
---|
1012 | - } |
---|
1013 | - this.app.setContextFor(this.at); |
---|
1014 | - if (wait = this.getOpt('delay')) { |
---|
1015 | - this._delayLookUp(query, wait); |
---|
1016 | - } else { |
---|
1017 | - this._lookUp(query); |
---|
1018 | - } |
---|
1019 | - return query; |
---|
1020 | - }; |
---|
1021 | - |
---|
1022 | - Controller.prototype._delayLookUp = function(query, wait) { |
---|
1023 | - var now, remaining; |
---|
1024 | - now = Date.now ? Date.now() : new Date().getTime(); |
---|
1025 | - this.previousCallTime || (this.previousCallTime = now); |
---|
1026 | - remaining = wait - (now - this.previousCallTime); |
---|
1027 | - if ((0 < remaining && remaining < wait)) { |
---|
1028 | - this.previousCallTime = now; |
---|
1029 | - this._stopDelayedCall(); |
---|
1030 | - return this.delayedCallTimeout = setTimeout((function(_this) { |
---|
1031 | - return function() { |
---|
1032 | - _this.previousCallTime = 0; |
---|
1033 | - _this.delayedCallTimeout = null; |
---|
1034 | - return _this._lookUp(query); |
---|
1035 | - }; |
---|
1036 | - })(this), wait); |
---|
1037 | - } else { |
---|
1038 | - this._stopDelayedCall(); |
---|
1039 | - if (this.previousCallTime !== now) { |
---|
1040 | - this.previousCallTime = 0; |
---|
1041 | - } |
---|
1042 | - return this._lookUp(query); |
---|
1043 | - } |
---|
1044 | - }; |
---|
1045 | - |
---|
1046 | - Controller.prototype._stopDelayedCall = function() { |
---|
1047 | - if (this.delayedCallTimeout) { |
---|
1048 | - clearTimeout(this.delayedCallTimeout); |
---|
1049 | - return this.delayedCallTimeout = null; |
---|
1050 | - } |
---|
1051 | - }; |
---|
1052 | - |
---|
1053 | - Controller.prototype._generateQueryCBId = function() { |
---|
1054 | - return {}; |
---|
1055 | - }; |
---|
1056 | - |
---|
1057 | - Controller.prototype._lookUp = function(query) { |
---|
1058 | - var _callback; |
---|
1059 | - _callback = function(queryCBId, data) { |
---|
1060 | - if (queryCBId !== this.expectedQueryCBId) { |
---|
1061 | - return; |
---|
1062 | - } |
---|
1063 | - if (data && data.length > 0) { |
---|
1064 | - return this.renderView(this.constructor.arrayToDefaultHash(data)); |
---|
1065 | - } else { |
---|
1066 | - return this.view.hide(); |
---|
1067 | - } |
---|
1068 | - }; |
---|
1069 | - this.expectedQueryCBId = this._generateQueryCBId(); |
---|
1070 | - return this.model.query(query.text, $.proxy(_callback, this, this.expectedQueryCBId)); |
---|
1071 | - }; |
---|
1072 | - |
---|
1073 | - return Controller; |
---|
1074 | - |
---|
1075 | -})(); |
---|
1076 | - |
---|
1077 | -var TextareaController, |
---|
1078 | - extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, |
---|
1079 | - hasProp = {}.hasOwnProperty; |
---|
1080 | - |
---|
1081 | -TextareaController = (function(superClass) { |
---|
1082 | - extend(TextareaController, superClass); |
---|
1083 | - |
---|
1084 | - function TextareaController() { |
---|
1085 | - return TextareaController.__super__.constructor.apply(this, arguments); |
---|
1086 | - } |
---|
1087 | - |
---|
1088 | - TextareaController.prototype.catchQuery = function() { |
---|
1089 | - var caretPos, content, end, isString, query, start, subtext; |
---|
1090 | - content = this.$inputor.val(); |
---|
1091 | - caretPos = this.$inputor.caret('pos', { |
---|
1092 | - iframe: this.app.iframe |
---|
1093 | - }); |
---|
1094 | - subtext = content.slice(0, caretPos); |
---|
1095 | - query = this.callbacks("matcher").call(this, this.at, subtext, this.getOpt('startWithSpace'), this.getOpt("acceptSpaceBar")); |
---|
1096 | - isString = typeof query === 'string'; |
---|
1097 | - if (isString && query.length < this.getOpt('minLen', 0)) { |
---|
1098 | - return; |
---|
1099 | - } |
---|
1100 | - if (isString && query.length <= this.getOpt('maxLen', 20)) { |
---|
1101 | - start = caretPos - query.length; |
---|
1102 | - end = start + query.length; |
---|
1103 | - this.pos = start; |
---|
1104 | - query = { |
---|
1105 | - 'text': query, |
---|
1106 | - 'headPos': start, |
---|
1107 | - 'endPos': end |
---|
1108 | - }; |
---|
1109 | - this.trigger("matched", [this.at, query.text]); |
---|
1110 | - } else { |
---|
1111 | - query = null; |
---|
1112 | - this.view.hide(); |
---|
1113 | - } |
---|
1114 | - return this.query = query; |
---|
1115 | - }; |
---|
1116 | - |
---|
1117 | - TextareaController.prototype.rect = function() { |
---|
1118 | - var c, iframeOffset, scaleBottom; |
---|
1119 | - if (!(c = this.$inputor.caret('offset', this.pos - 1, { |
---|
1120 | - iframe: this.app.iframe |
---|
1121 | - }))) { |
---|
1122 | - return; |
---|
1123 | - } |
---|
1124 | - if (this.app.iframe && !this.app.iframeAsRoot) { |
---|
1125 | - iframeOffset = $(this.app.iframe).offset(); |
---|
1126 | - c.left += iframeOffset.left; |
---|
1127 | - c.top += iframeOffset.top; |
---|
1128 | - } |
---|
1129 | - scaleBottom = this.app.document.selection ? 0 : 2; |
---|
1130 | - return { |
---|
1131 | - left: c.left, |
---|
1132 | - top: c.top, |
---|
1133 | - bottom: c.top + c.height + scaleBottom |
---|
1134 | - }; |
---|
1135 | - }; |
---|
1136 | - |
---|
1137 | - TextareaController.prototype.insert = function(content, $li) { |
---|
1138 | - var $inputor, source, startStr, suffix, text; |
---|
1139 | - $inputor = this.$inputor; |
---|
1140 | - source = $inputor.val(); |
---|
1141 | - startStr = source.slice(0, Math.max(this.query.headPos - this.at.length, 0)); |
---|
1142 | - suffix = (suffix = this.getOpt('suffix')) === "" ? suffix : suffix || " "; |
---|
1143 | - content += suffix; |
---|
1144 | - text = "" + startStr + content + (source.slice(this.query['endPos'] || 0)); |
---|
1145 | - $inputor.val(text); |
---|
1146 | - $inputor.caret('pos', startStr.length + content.length, { |
---|
1147 | - iframe: this.app.iframe |
---|
1148 | - }); |
---|
1149 | - if (!$inputor.is(':focus')) { |
---|
1150 | - $inputor.focus(); |
---|
1151 | - } |
---|
1152 | - return $inputor.change(); |
---|
1153 | - }; |
---|
1154 | - |
---|
1155 | - return TextareaController; |
---|
1156 | - |
---|
1157 | -})(Controller); |
---|
1158 | - |
---|
1159 | -var EditableController, |
---|
1160 | - extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, |
---|
1161 | - hasProp = {}.hasOwnProperty; |
---|
1162 | - |
---|
1163 | -EditableController = (function(superClass) { |
---|
1164 | - extend(EditableController, superClass); |
---|
1165 | - |
---|
1166 | - function EditableController() { |
---|
1167 | - return EditableController.__super__.constructor.apply(this, arguments); |
---|
1168 | - } |
---|
1169 | - |
---|
1170 | - EditableController.prototype._getRange = function() { |
---|
1171 | - var sel; |
---|
1172 | - sel = this.app.window.getSelection(); |
---|
1173 | - if (sel.rangeCount > 0) { |
---|
1174 | - return sel.getRangeAt(0); |
---|
1175 | - } |
---|
1176 | - }; |
---|
1177 | - |
---|
1178 | - EditableController.prototype._setRange = function(position, node, range) { |
---|
1179 | - if (range == null) { |
---|
1180 | - range = this._getRange(); |
---|
1181 | - } |
---|
1182 | - if (!(range && node)) { |
---|
1183 | - return; |
---|
1184 | - } |
---|
1185 | - node = $(node)[0]; |
---|
1186 | - if (position === 'after') { |
---|
1187 | - range.setEndAfter(node); |
---|
1188 | - range.setStartAfter(node); |
---|
1189 | - } else { |
---|
1190 | - range.setEndBefore(node); |
---|
1191 | - range.setStartBefore(node); |
---|
1192 | - } |
---|
1193 | - range.collapse(false); |
---|
1194 | - return this._clearRange(range); |
---|
1195 | - }; |
---|
1196 | - |
---|
1197 | - EditableController.prototype._clearRange = function(range) { |
---|
1198 | - var sel; |
---|
1199 | - if (range == null) { |
---|
1200 | - range = this._getRange(); |
---|
1201 | - } |
---|
1202 | - sel = this.app.window.getSelection(); |
---|
1203 | - if (this.ctrl_a_pressed == null) { |
---|
1204 | - sel.removeAllRanges(); |
---|
1205 | - return sel.addRange(range); |
---|
1206 | - } |
---|
1207 | - }; |
---|
1208 | - |
---|
1209 | - EditableController.prototype._movingEvent = function(e) { |
---|
1210 | - var ref; |
---|
1211 | - return e.type === 'click' || ((ref = e.which) === KEY_CODE.RIGHT || ref === KEY_CODE.LEFT || ref === KEY_CODE.UP || ref === KEY_CODE.DOWN); |
---|
1212 | - }; |
---|
1213 | - |
---|
1214 | - EditableController.prototype._unwrap = function(node) { |
---|
1215 | - var next; |
---|
1216 | - node = $(node).unwrap().get(0); |
---|
1217 | - if ((next = node.nextSibling) && next.nodeValue) { |
---|
1218 | - node.nodeValue += next.nodeValue; |
---|
1219 | - $(next).remove(); |
---|
1220 | - } |
---|
1221 | - return node; |
---|
1222 | - }; |
---|
1223 | - |
---|
1224 | - EditableController.prototype.catchQuery = function(e) { |
---|
1225 | - var $inserted, $query, _range, index, inserted, isString, lastNode, matched, offset, query, query_content, range; |
---|
1226 | - if (!(range = this._getRange())) { |
---|
1227 | - return; |
---|
1228 | - } |
---|
1229 | - if (!range.collapsed) { |
---|
1230 | - return; |
---|
1231 | - } |
---|
1232 | - if (e.which === KEY_CODE.ENTER) { |
---|
1233 | - ($query = $(range.startContainer).closest('.atwho-query')).contents().unwrap(); |
---|
1234 | - if ($query.is(':empty')) { |
---|
1235 | - $query.remove(); |
---|
1236 | - } |
---|
1237 | - ($query = $(".atwho-query", this.app.document)).text($query.text()).contents().last().unwrap(); |
---|
1238 | - this._clearRange(); |
---|
1239 | - return; |
---|
1240 | - } |
---|
1241 | - if (/firefox/i.test(navigator.userAgent)) { |
---|
1242 | - if ($(range.startContainer).is(this.$inputor)) { |
---|
1243 | - this._clearRange(); |
---|
1244 | - return; |
---|
1245 | - } |
---|
1246 | - if (e.which === KEY_CODE.BACKSPACE && range.startContainer.nodeType === document.ELEMENT_NODE && (offset = range.startOffset - 1) >= 0) { |
---|
1247 | - _range = range.cloneRange(); |
---|
1248 | - _range.setStart(range.startContainer, offset); |
---|
1249 | - if ($(_range.cloneContents()).contents().last().is('.atwho-inserted')) { |
---|
1250 | - inserted = $(range.startContainer).contents().get(offset); |
---|
1251 | - this._setRange('after', $(inserted).contents().last()); |
---|
1252 | - } |
---|
1253 | - } else if (e.which === KEY_CODE.LEFT && range.startContainer.nodeType === document.TEXT_NODE) { |
---|
1254 | - $inserted = $(range.startContainer.previousSibling); |
---|
1255 | - if ($inserted.is('.atwho-inserted') && range.startOffset === 0) { |
---|
1256 | - this._setRange('after', $inserted.contents().last()); |
---|
1257 | - } |
---|
1258 | - } |
---|
1259 | - } |
---|
1260 | - $(range.startContainer).closest('.atwho-inserted').addClass('atwho-query').siblings().removeClass('atwho-query'); |
---|
1261 | - if (($query = $(".atwho-query", this.app.document)).length > 0 && $query.is(':empty') && $query.text().length === 0) { |
---|
1262 | - $query.remove(); |
---|
1263 | - } |
---|
1264 | - if (!this._movingEvent(e)) { |
---|
1265 | - $query.removeClass('atwho-inserted'); |
---|
1266 | - } |
---|
1267 | - if ($query.length > 0) { |
---|
1268 | - switch (e.which) { |
---|
1269 | - case KEY_CODE.LEFT: |
---|
1270 | - this._setRange('before', $query.get(0), range); |
---|
1271 | - $query.removeClass('atwho-query'); |
---|
1272 | - return; |
---|
1273 | - case KEY_CODE.RIGHT: |
---|
1274 | - this._setRange('after', $query.get(0).nextSibling, range); |
---|
1275 | - $query.removeClass('atwho-query'); |
---|
1276 | - return; |
---|
1277 | - } |
---|
1278 | - } |
---|
1279 | - if ($query.length > 0 && (query_content = $query.attr('data-atwho-at-query'))) { |
---|
1280 | - $query.empty().html(query_content).attr('data-atwho-at-query', null); |
---|
1281 | - this._setRange('after', $query.get(0), range); |
---|
1282 | - } |
---|
1283 | - _range = range.cloneRange(); |
---|
1284 | - _range.setStart(range.startContainer, 0); |
---|
1285 | - matched = this.callbacks("matcher").call(this, this.at, _range.toString(), this.getOpt('startWithSpace'), this.getOpt("acceptSpaceBar")); |
---|
1286 | - isString = typeof matched === 'string'; |
---|
1287 | - if ($query.length === 0 && isString && (index = range.startOffset - this.at.length - matched.length) >= 0) { |
---|
1288 | - range.setStart(range.startContainer, index); |
---|
1289 | - $query = $('<span/>', this.app.document).attr(this.getOpt("editableAtwhoQueryAttrs")).addClass('atwho-query'); |
---|
1290 | - range.surroundContents($query.get(0)); |
---|
1291 | - lastNode = $query.contents().last().get(0); |
---|
1292 | - if (lastNode) { |
---|
1293 | - if (/firefox/i.test(navigator.userAgent)) { |
---|
1294 | - range.setStart(lastNode, lastNode.length); |
---|
1295 | - range.setEnd(lastNode, lastNode.length); |
---|
1296 | - this._clearRange(range); |
---|
1297 | - } else { |
---|
1298 | - this._setRange('after', lastNode, range); |
---|
1299 | - } |
---|
1300 | - } |
---|
1301 | - } |
---|
1302 | - if (isString && matched.length < this.getOpt('minLen', 0)) { |
---|
1303 | - return; |
---|
1304 | - } |
---|
1305 | - if (isString && matched.length <= this.getOpt('maxLen', 20)) { |
---|
1306 | - query = { |
---|
1307 | - text: matched, |
---|
1308 | - el: $query |
---|
1309 | - }; |
---|
1310 | - this.trigger("matched", [this.at, query.text]); |
---|
1311 | - return this.query = query; |
---|
1312 | - } else { |
---|
1313 | - this.view.hide(); |
---|
1314 | - this.query = { |
---|
1315 | - el: $query |
---|
1316 | - }; |
---|
1317 | - if ($query.text().indexOf(this.at) >= 0) { |
---|
1318 | - if (this._movingEvent(e) && $query.hasClass('atwho-inserted')) { |
---|
1319 | - $query.removeClass('atwho-query'); |
---|
1320 | - } else if (false !== this.callbacks('afterMatchFailed').call(this, this.at, $query)) { |
---|
1321 | - this._setRange("after", this._unwrap($query.text($query.text()).contents().first())); |
---|
1322 | - } |
---|
1323 | - } |
---|
1324 | - return null; |
---|
1325 | - } |
---|
1326 | - }; |
---|
1327 | - |
---|
1328 | - EditableController.prototype.rect = function() { |
---|
1329 | - var $iframe, iframeOffset, rect; |
---|
1330 | - rect = this.query.el.offset(); |
---|
1331 | - if (!(rect && this.query.el[0].getClientRects().length)) { |
---|
1332 | - return; |
---|
1333 | - } |
---|
1334 | - if (this.app.iframe && !this.app.iframeAsRoot) { |
---|
1335 | - iframeOffset = ($iframe = $(this.app.iframe)).offset(); |
---|
1336 | - rect.left += iframeOffset.left - this.$inputor.scrollLeft(); |
---|
1337 | - rect.top += iframeOffset.top - this.$inputor.scrollTop(); |
---|
1338 | - } |
---|
1339 | - rect.bottom = rect.top + this.query.el.height(); |
---|
1340 | - return rect; |
---|
1341 | - }; |
---|
1342 | - |
---|
1343 | - EditableController.prototype.insert = function(content, $li) { |
---|
1344 | - var data, overrides, range, suffix, suffixNode; |
---|
1345 | - if (!this.$inputor.is(':focus')) { |
---|
1346 | - this.$inputor.focus(); |
---|
1347 | - } |
---|
1348 | - overrides = this.getOpt('functionOverrides'); |
---|
1349 | - if (overrides.insert) { |
---|
1350 | - return overrides.insert.call(this, content, $li); |
---|
1351 | - } |
---|
1352 | - suffix = (suffix = this.getOpt('suffix')) === "" ? suffix : suffix || "\u00A0"; |
---|
1353 | - data = $li.data('item-data'); |
---|
1354 | - this.query.el.removeClass('atwho-query').addClass('atwho-inserted').html(content).attr('data-atwho-at-query', "" + data['atwho-at'] + this.query.text).attr('contenteditable', "false"); |
---|
1355 | - if (range = this._getRange()) { |
---|
1356 | - if (this.query.el.length) { |
---|
1357 | - range.setEndAfter(this.query.el[0]); |
---|
1358 | - } |
---|
1359 | - range.collapse(false); |
---|
1360 | - range.insertNode(suffixNode = this.app.document.createTextNode("" + suffix)); |
---|
1361 | - this._setRange('after', suffixNode, range); |
---|
1362 | - } |
---|
1363 | - if (!this.$inputor.is(':focus')) { |
---|
1364 | - this.$inputor.focus(); |
---|
1365 | - } |
---|
1366 | - return this.$inputor.change(); |
---|
1367 | - }; |
---|
1368 | - |
---|
1369 | - return EditableController; |
---|
1370 | - |
---|
1371 | -})(Controller); |
---|
1372 | - |
---|
1373 | -var Model; |
---|
1374 | - |
---|
1375 | -Model = (function() { |
---|
1376 | - function Model(context) { |
---|
1377 | - this.context = context; |
---|
1378 | - this.at = this.context.at; |
---|
1379 | - this.storage = this.context.$inputor; |
---|
1380 | - } |
---|
1381 | - |
---|
1382 | - Model.prototype.destroy = function() { |
---|
1383 | - return this.storage.data(this.at, null); |
---|
1384 | - }; |
---|
1385 | - |
---|
1386 | - Model.prototype.saved = function() { |
---|
1387 | - return this.fetch() > 0; |
---|
1388 | - }; |
---|
1389 | - |
---|
1390 | - Model.prototype.query = function(query, callback) { |
---|
1391 | - var _remoteFilter, data, searchKey; |
---|
1392 | - data = this.fetch(); |
---|
1393 | - searchKey = this.context.getOpt("searchKey"); |
---|
1394 | - data = this.context.callbacks('filter').call(this.context, query, data, searchKey) || []; |
---|
1395 | - _remoteFilter = this.context.callbacks('remoteFilter'); |
---|
1396 | - if (data.length > 0 || (!_remoteFilter && data.length === 0)) { |
---|
1397 | - return callback(data); |
---|
1398 | - } else { |
---|
1399 | - return _remoteFilter.call(this.context, query, callback); |
---|
1400 | - } |
---|
1401 | - }; |
---|
1402 | - |
---|
1403 | - Model.prototype.fetch = function() { |
---|
1404 | - return this.storage.data(this.at) || []; |
---|
1405 | - }; |
---|
1406 | - |
---|
1407 | - Model.prototype.save = function(data) { |
---|
1408 | - return this.storage.data(this.at, this.context.callbacks("beforeSave").call(this.context, data || [])); |
---|
1409 | - }; |
---|
1410 | - |
---|
1411 | - Model.prototype.load = function(data) { |
---|
1412 | - if (!(this.saved() || !data)) { |
---|
1413 | - return this._load(data); |
---|
1414 | - } |
---|
1415 | - }; |
---|
1416 | - |
---|
1417 | - Model.prototype.reload = function(data) { |
---|
1418 | - return this._load(data); |
---|
1419 | - }; |
---|
1420 | - |
---|
1421 | - Model.prototype._load = function(data) { |
---|
1422 | - if (typeof data === "string") { |
---|
1423 | - return $.ajax(data, { |
---|
1424 | - dataType: "json" |
---|
1425 | - }).done((function(_this) { |
---|
1426 | - return function(data) { |
---|
1427 | - return _this.save(data); |
---|
1428 | - }; |
---|
1429 | - })(this)); |
---|
1430 | - } else { |
---|
1431 | - return this.save(data); |
---|
1432 | - } |
---|
1433 | - }; |
---|
1434 | - |
---|
1435 | - return Model; |
---|
1436 | - |
---|
1437 | -})(); |
---|
1438 | - |
---|
1439 | -var View; |
---|
1440 | - |
---|
1441 | -View = (function() { |
---|
1442 | - function View(context) { |
---|
1443 | - this.context = context; |
---|
1444 | - this.$el = $("<div class='atwho-view'><ul class='atwho-view-ul'></ul></div>"); |
---|
1445 | - this.$elUl = this.$el.children(); |
---|
1446 | - this.timeoutID = null; |
---|
1447 | - this.context.$el.append(this.$el); |
---|
1448 | - this.bindEvent(); |
---|
1449 | - } |
---|
1450 | - |
---|
1451 | - View.prototype.init = function() { |
---|
1452 | - var header_tpl, id; |
---|
1453 | - id = this.context.getOpt("alias") || this.context.at.charCodeAt(0); |
---|
1454 | - header_tpl = this.context.getOpt("headerTpl"); |
---|
1455 | - if (header_tpl && this.$el.children().length === 1) { |
---|
1456 | - this.$el.prepend(header_tpl); |
---|
1457 | - } |
---|
1458 | - return this.$el.attr({ |
---|
1459 | - 'id': "at-view-" + id |
---|
1460 | - }); |
---|
1461 | - }; |
---|
1462 | - |
---|
1463 | - View.prototype.destroy = function() { |
---|
1464 | - return this.$el.remove(); |
---|
1465 | - }; |
---|
1466 | - |
---|
1467 | - View.prototype.bindEvent = function() { |
---|
1468 | - var $menu, lastCoordX, lastCoordY; |
---|
1469 | - $menu = this.$el.find('ul'); |
---|
1470 | - lastCoordX = 0; |
---|
1471 | - lastCoordY = 0; |
---|
1472 | - return $menu.on('mousemove.atwho-view', 'li', (function(_this) { |
---|
1473 | - return function(e) { |
---|
1474 | - var $cur; |
---|
1475 | - if (lastCoordX === e.clientX && lastCoordY === e.clientY) { |
---|
1476 | - return; |
---|
1477 | - } |
---|
1478 | - lastCoordX = e.clientX; |
---|
1479 | - lastCoordY = e.clientY; |
---|
1480 | - $cur = $(e.currentTarget); |
---|
1481 | - if ($cur.hasClass('cur')) { |
---|
1482 | - return; |
---|
1483 | - } |
---|
1484 | - $menu.find('.cur').removeClass('cur'); |
---|
1485 | - return $cur.addClass('cur'); |
---|
1486 | - }; |
---|
1487 | - })(this)).on('click.atwho-view', 'li', (function(_this) { |
---|
1488 | - return function(e) { |
---|
1489 | - $menu.find('.cur').removeClass('cur'); |
---|
1490 | - $(e.currentTarget).addClass('cur'); |
---|
1491 | - _this.choose(e); |
---|
1492 | - return e.preventDefault(); |
---|
1493 | - }; |
---|
1494 | - })(this)); |
---|
1495 | - }; |
---|
1496 | - |
---|
1497 | - View.prototype.visible = function() { |
---|
1498 | - return $.expr.filters.visible(this.$el[0]); |
---|
1499 | - }; |
---|
1500 | - |
---|
1501 | - View.prototype.highlighted = function() { |
---|
1502 | - return this.$el.find(".cur").length > 0; |
---|
1503 | - }; |
---|
1504 | - |
---|
1505 | - View.prototype.choose = function(e) { |
---|
1506 | - var $li, content; |
---|
1507 | - if (($li = this.$el.find(".cur")).length) { |
---|
1508 | - content = this.context.insertContentFor($li); |
---|
1509 | - this.context._stopDelayedCall(); |
---|
1510 | - this.context.insert(this.context.callbacks("beforeInsert").call(this.context, content, $li, e), $li); |
---|
1511 | - this.context.trigger("inserted", [$li, e]); |
---|
1512 | - this.hide(e); |
---|
1513 | - } |
---|
1514 | - if (this.context.getOpt("hideWithoutSuffix")) { |
---|
1515 | - return this.stopShowing = true; |
---|
1516 | - } |
---|
1517 | - }; |
---|
1518 | - |
---|
1519 | - View.prototype.reposition = function(rect) { |
---|
1520 | - var _window, offset, overflowOffset, ref; |
---|
1521 | - _window = this.context.app.iframeAsRoot ? this.context.app.window : window; |
---|
1522 | - if (rect.bottom + this.$el.height() - $(_window).scrollTop() > $(_window).height()) { |
---|
1523 | - rect.bottom = rect.top - this.$el.height(); |
---|
1524 | - } |
---|
1525 | - if (rect.left > (overflowOffset = $(_window).width() - this.$el.width() - 5)) { |
---|
1526 | - rect.left = overflowOffset; |
---|
1527 | - } |
---|
1528 | - offset = { |
---|
1529 | - left: rect.left, |
---|
1530 | - top: rect.bottom |
---|
1531 | - }; |
---|
1532 | - if ((ref = this.context.callbacks("beforeReposition")) != null) { |
---|
1533 | - ref.call(this.context, offset); |
---|
1534 | - } |
---|
1535 | - this.$el.offset(offset); |
---|
1536 | - return this.context.trigger("reposition", [offset]); |
---|
1537 | - }; |
---|
1538 | - |
---|
1539 | - View.prototype.next = function() { |
---|
1540 | - var cur, next, nextEl, offset; |
---|
1541 | - cur = this.$el.find('.cur').removeClass('cur'); |
---|
1542 | - next = cur.next(); |
---|
1543 | - if (!next.length) { |
---|
1544 | - next = this.$el.find('li:first'); |
---|
1545 | - } |
---|
1546 | - next.addClass('cur'); |
---|
1547 | - nextEl = next[0]; |
---|
1548 | - offset = nextEl.offsetTop + nextEl.offsetHeight + (nextEl.nextSibling ? nextEl.nextSibling.offsetHeight : 0); |
---|
1549 | - return this.scrollTop(Math.max(0, offset - this.$el.height())); |
---|
1550 | - }; |
---|
1551 | - |
---|
1552 | - View.prototype.prev = function() { |
---|
1553 | - var cur, offset, prev, prevEl; |
---|
1554 | - cur = this.$el.find('.cur').removeClass('cur'); |
---|
1555 | - prev = cur.prev(); |
---|
1556 | - if (!prev.length) { |
---|
1557 | - prev = this.$el.find('li:last'); |
---|
1558 | - } |
---|
1559 | - prev.addClass('cur'); |
---|
1560 | - prevEl = prev[0]; |
---|
1561 | - offset = prevEl.offsetTop + prevEl.offsetHeight + (prevEl.nextSibling ? prevEl.nextSibling.offsetHeight : 0); |
---|
1562 | - return this.scrollTop(Math.max(0, offset - this.$el.height())); |
---|
1563 | - }; |
---|
1564 | - |
---|
1565 | - View.prototype.scrollTop = function(scrollTop) { |
---|
1566 | - var scrollDuration; |
---|
1567 | - scrollDuration = this.context.getOpt('scrollDuration'); |
---|
1568 | - if (scrollDuration) { |
---|
1569 | - return this.$elUl.animate({ |
---|
1570 | - scrollTop: scrollTop |
---|
1571 | - }, scrollDuration); |
---|
1572 | - } else { |
---|
1573 | - return this.$elUl.scrollTop(scrollTop); |
---|
1574 | - } |
---|
1575 | - }; |
---|
1576 | - |
---|
1577 | - View.prototype.show = function() { |
---|
1578 | - var rect; |
---|
1579 | - if (this.stopShowing) { |
---|
1580 | - this.stopShowing = false; |
---|
1581 | - return; |
---|
1582 | - } |
---|
1583 | - if (!this.visible()) { |
---|
1584 | - this.$el.show(); |
---|
1585 | - this.$el.scrollTop(0); |
---|
1586 | - this.context.trigger('shown'); |
---|
1587 | - } |
---|
1588 | - if (rect = this.context.rect()) { |
---|
1589 | - return this.reposition(rect); |
---|
1590 | - } |
---|
1591 | - }; |
---|
1592 | - |
---|
1593 | - View.prototype.hide = function(e, time) { |
---|
1594 | - var callback; |
---|
1595 | - if (!this.visible()) { |
---|
1596 | - return; |
---|
1597 | - } |
---|
1598 | - if (isNaN(time)) { |
---|
1599 | - this.$el.hide(); |
---|
1600 | - return this.context.trigger('hidden', [e]); |
---|
1601 | - } else { |
---|
1602 | - callback = (function(_this) { |
---|
1603 | - return function() { |
---|
1604 | - return _this.hide(); |
---|
1605 | - }; |
---|
1606 | - })(this); |
---|
1607 | - clearTimeout(this.timeoutID); |
---|
1608 | - return this.timeoutID = setTimeout(callback, time); |
---|
1609 | - } |
---|
1610 | - }; |
---|
1611 | - |
---|
1612 | - View.prototype.render = function(list) { |
---|
1613 | - var $li, $ul, i, item, len, li, tpl; |
---|
1614 | - if (!($.isArray(list) && list.length > 0)) { |
---|
1615 | - this.hide(); |
---|
1616 | - return; |
---|
1617 | - } |
---|
1618 | - this.$el.find('ul').empty(); |
---|
1619 | - $ul = this.$el.find('ul'); |
---|
1620 | - tpl = this.context.getOpt('displayTpl'); |
---|
1621 | - for (i = 0, len = list.length; i < len; i++) { |
---|
1622 | - item = list[i]; |
---|
1623 | - item = $.extend({}, item, { |
---|
1624 | - 'atwho-at': this.context.at |
---|
1625 | - }); |
---|
1626 | - li = this.context.callbacks("tplEval").call(this.context, tpl, item, "onDisplay"); |
---|
1627 | - $li = $(this.context.callbacks("highlighter").call(this.context, li, this.context.query.text)); |
---|
1628 | - $li.data("item-data", item); |
---|
1629 | - $ul.append($li); |
---|
1630 | - } |
---|
1631 | - this.show(); |
---|
1632 | - if (this.context.getOpt('highlightFirst')) { |
---|
1633 | - return $ul.find("li:first").addClass("cur"); |
---|
1634 | - } |
---|
1635 | - }; |
---|
1636 | - |
---|
1637 | - return View; |
---|
1638 | - |
---|
1639 | -})(); |
---|
1640 | - |
---|
1641 | -var Api; |
---|
1642 | - |
---|
1643 | -Api = { |
---|
1644 | - load: function(at, data) { |
---|
1645 | - var c; |
---|
1646 | - if (c = this.controller(at)) { |
---|
1647 | - return c.model.load(data); |
---|
1648 | - } |
---|
1649 | - }, |
---|
1650 | - isSelecting: function() { |
---|
1651 | - var ref; |
---|
1652 | - return !!((ref = this.controller()) != null ? ref.view.visible() : void 0); |
---|
1653 | - }, |
---|
1654 | - hide: function() { |
---|
1655 | - var ref; |
---|
1656 | - return (ref = this.controller()) != null ? ref.view.hide() : void 0; |
---|
1657 | - }, |
---|
1658 | - reposition: function() { |
---|
1659 | - var c; |
---|
1660 | - if (c = this.controller()) { |
---|
1661 | - return c.view.reposition(c.rect()); |
---|
1662 | - } |
---|
1663 | - }, |
---|
1664 | - setIframe: function(iframe, asRoot) { |
---|
1665 | - this.setupRootElement(iframe, asRoot); |
---|
1666 | - return null; |
---|
1667 | - }, |
---|
1668 | - run: function() { |
---|
1669 | - return this.dispatch(); |
---|
1670 | - }, |
---|
1671 | - destroy: function() { |
---|
1672 | - this.shutdown(); |
---|
1673 | - return this.$inputor.data('atwho', null); |
---|
1674 | - } |
---|
1675 | -}; |
---|
1676 | - |
---|
1677 | -$.fn.atwho = function(method) { |
---|
1678 | - var _args, result; |
---|
1679 | - _args = arguments; |
---|
1680 | - result = null; |
---|
1681 | - this.filter('textarea, input, [contenteditable=""], [contenteditable=true]').each(function() { |
---|
1682 | - var $this, app; |
---|
1683 | - if (!(app = ($this = $(this)).data("atwho"))) { |
---|
1684 | - $this.data('atwho', (app = new App(this))); |
---|
1685 | - } |
---|
1686 | - if (typeof method === 'object' || !method) { |
---|
1687 | - return app.reg(method.at, method); |
---|
1688 | - } else if (Api[method] && app) { |
---|
1689 | - return result = Api[method].apply(app, Array.prototype.slice.call(_args, 1)); |
---|
1690 | - } else { |
---|
1691 | - return $.error("Method " + method + " does not exist on jQuery.atwho"); |
---|
1692 | - } |
---|
1693 | - }); |
---|
1694 | - if (result != null) { |
---|
1695 | - return result; |
---|
1696 | - } else { |
---|
1697 | - return this; |
---|
1698 | - } |
---|
1699 | -}; |
---|
1700 | - |
---|
1701 | -$.fn.atwho["default"] = { |
---|
1702 | - at: void 0, |
---|
1703 | - alias: void 0, |
---|
1704 | - data: null, |
---|
1705 | - displayTpl: "<li>${name}</li>", |
---|
1706 | - insertTpl: "${atwho-at}${name}", |
---|
1707 | - headerTpl: null, |
---|
1708 | - callbacks: DEFAULT_CALLBACKS, |
---|
1709 | - functionOverrides: {}, |
---|
1710 | - searchKey: "name", |
---|
1711 | - suffix: void 0, |
---|
1712 | - hideWithoutSuffix: false, |
---|
1713 | - startWithSpace: true, |
---|
1714 | - acceptSpaceBar: false, |
---|
1715 | - highlightFirst: true, |
---|
1716 | - limit: 5, |
---|
1717 | - maxLen: 20, |
---|
1718 | - minLen: 0, |
---|
1719 | - displayTimeout: 300, |
---|
1720 | - delay: null, |
---|
1721 | - spaceSelectsMatch: false, |
---|
1722 | - tabSelectsMatch: true, |
---|
1723 | - editableAtwhoQueryAttrs: {}, |
---|
1724 | - scrollDuration: 150, |
---|
1725 | - suspendOnComposing: true, |
---|
1726 | - lookUpOnClick: true |
---|
1727 | -}; |
---|
1728 | - |
---|
1729 | -$.fn.atwho.debug = false; |
---|
1730 | - |
---|
1731 | -})); |
---|
1732 | diff --git src/bp-core/js/vendor/jquery.atwho.txt src/bp-core/js/vendor/jquery.atwho.txt |
---|
1733 | deleted file mode 100644 |
---|
1734 | index 36cd1c122..000000000 |
---|
1735 | --- src/bp-core/js/vendor/jquery.atwho.txt |
---|
1736 | +++ /dev/null |
---|
1737 | @@ -1,22 +0,0 @@ |
---|
1738 | -Copyright (c) 2013 chord.luo@gmail.com |
---|
1739 | - |
---|
1740 | -Permission is hereby granted, free of charge, to any person |
---|
1741 | -obtaining a copy of this software and associated documentation |
---|
1742 | -files (the "Software"), to deal in the Software without |
---|
1743 | -restriction, including without limitation the rights to use, |
---|
1744 | -copy, modify, merge, publish, distribute, sublicense, and/or sell |
---|
1745 | -copies of the Software, and to permit persons to whom the |
---|
1746 | -Software is furnished to do so, subject to the following |
---|
1747 | -conditions: |
---|
1748 | - |
---|
1749 | -The above copyright notice and this permission notice shall be |
---|
1750 | -included in all copies or substantial portions of the Software. |
---|
1751 | - |
---|
1752 | -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
---|
1753 | -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
---|
1754 | -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
---|
1755 | -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
---|
1756 | -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
---|
1757 | -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
---|
1758 | -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
---|
1759 | -OTHER DEALINGS IN THE SOFTWARE. |
---|
1760 | diff --git src/bp-core/js/vendor/jquery.caret.js src/bp-core/js/vendor/jquery.caret.js |
---|
1761 | deleted file mode 100755 |
---|
1762 | index 811ec63ee..000000000 |
---|
1763 | --- src/bp-core/js/vendor/jquery.caret.js |
---|
1764 | +++ /dev/null |
---|
1765 | @@ -1,436 +0,0 @@ |
---|
1766 | -(function (root, factory) { |
---|
1767 | - if (typeof define === 'function' && define.amd) { |
---|
1768 | - // AMD. Register as an anonymous module. |
---|
1769 | - define(["jquery"], function ($) { |
---|
1770 | - return (root.returnExportsGlobal = factory($)); |
---|
1771 | - }); |
---|
1772 | - } else if (typeof exports === 'object') { |
---|
1773 | - // Node. Does not work with strict CommonJS, but |
---|
1774 | - // only CommonJS-like enviroments that support module.exports, |
---|
1775 | - // like Node. |
---|
1776 | - module.exports = factory(require("jquery")); |
---|
1777 | - } else { |
---|
1778 | - factory(jQuery); |
---|
1779 | - } |
---|
1780 | -}(this, function ($) { |
---|
1781 | - |
---|
1782 | -/* |
---|
1783 | - Implement Github like autocomplete mentions |
---|
1784 | - http://ichord.github.com/At.js |
---|
1785 | - |
---|
1786 | - Copyright (c) 2013 chord.luo@gmail.com |
---|
1787 | - Licensed under the MIT license. |
---|
1788 | -*/ |
---|
1789 | - |
---|
1790 | -/* |
---|
1791 | -æ¬æä»¶æäœ textarea æè
input å
çæå
¥ç¬Š |
---|
1792 | -åªå®ç°äºè·åŸæå
¥ç¬Šå𿿬æ¡äžçäœçœ®ïŒæè®Ÿçœ® |
---|
1793 | -æå
¥ç¬Šçäœçœ®. |
---|
1794 | -*/ |
---|
1795 | - |
---|
1796 | -"use strict"; |
---|
1797 | -var EditableCaret, InputCaret, Mirror, Utils, discoveryIframeOf, methods, oDocument, oFrame, oWindow, pluginName, setContextBy; |
---|
1798 | - |
---|
1799 | -pluginName = 'caret'; |
---|
1800 | - |
---|
1801 | -EditableCaret = (function() { |
---|
1802 | - function EditableCaret($inputor) { |
---|
1803 | - this.$inputor = $inputor; |
---|
1804 | - this.domInputor = this.$inputor[0]; |
---|
1805 | - } |
---|
1806 | - |
---|
1807 | - EditableCaret.prototype.setPos = function(pos) { |
---|
1808 | - var fn, found, offset, sel; |
---|
1809 | - if (sel = oWindow.getSelection()) { |
---|
1810 | - offset = 0; |
---|
1811 | - found = false; |
---|
1812 | - (fn = function(pos, parent) { |
---|
1813 | - var node, range, _i, _len, _ref, _results; |
---|
1814 | - _ref = parent.childNodes; |
---|
1815 | - _results = []; |
---|
1816 | - for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
---|
1817 | - node = _ref[_i]; |
---|
1818 | - if (found) { |
---|
1819 | - break; |
---|
1820 | - } |
---|
1821 | - if (node.nodeType === 3) { |
---|
1822 | - if (offset + node.length >= pos) { |
---|
1823 | - found = true; |
---|
1824 | - range = oDocument.createRange(); |
---|
1825 | - range.setStart(node, pos - offset); |
---|
1826 | - sel.removeAllRanges(); |
---|
1827 | - sel.addRange(range); |
---|
1828 | - break; |
---|
1829 | - } else { |
---|
1830 | - _results.push(offset += node.length); |
---|
1831 | - } |
---|
1832 | - } else { |
---|
1833 | - _results.push(fn(pos, node)); |
---|
1834 | - } |
---|
1835 | - } |
---|
1836 | - return _results; |
---|
1837 | - })(pos, this.domInputor); |
---|
1838 | - } |
---|
1839 | - return this.domInputor; |
---|
1840 | - }; |
---|
1841 | - |
---|
1842 | - EditableCaret.prototype.getIEPosition = function() { |
---|
1843 | - return this.getPosition(); |
---|
1844 | - }; |
---|
1845 | - |
---|
1846 | - EditableCaret.prototype.getPosition = function() { |
---|
1847 | - var inputor_offset, offset; |
---|
1848 | - offset = this.getOffset(); |
---|
1849 | - inputor_offset = this.$inputor.offset(); |
---|
1850 | - offset.left -= inputor_offset.left; |
---|
1851 | - offset.top -= inputor_offset.top; |
---|
1852 | - return offset; |
---|
1853 | - }; |
---|
1854 | - |
---|
1855 | - EditableCaret.prototype.getOldIEPos = function() { |
---|
1856 | - var preCaretTextRange, textRange; |
---|
1857 | - textRange = oDocument.selection.createRange(); |
---|
1858 | - preCaretTextRange = oDocument.body.createTextRange(); |
---|
1859 | - preCaretTextRange.moveToElementText(this.domInputor); |
---|
1860 | - preCaretTextRange.setEndPoint("EndToEnd", textRange); |
---|
1861 | - return preCaretTextRange.text.length; |
---|
1862 | - }; |
---|
1863 | - |
---|
1864 | - EditableCaret.prototype.getPos = function() { |
---|
1865 | - var clonedRange, pos, range; |
---|
1866 | - if (range = this.range()) { |
---|
1867 | - clonedRange = range.cloneRange(); |
---|
1868 | - clonedRange.selectNodeContents(this.domInputor); |
---|
1869 | - clonedRange.setEnd(range.endContainer, range.endOffset); |
---|
1870 | - pos = clonedRange.toString().length; |
---|
1871 | - clonedRange.detach(); |
---|
1872 | - return pos; |
---|
1873 | - } else if (oDocument.selection) { |
---|
1874 | - return this.getOldIEPos(); |
---|
1875 | - } |
---|
1876 | - }; |
---|
1877 | - |
---|
1878 | - EditableCaret.prototype.getOldIEOffset = function() { |
---|
1879 | - var range, rect; |
---|
1880 | - range = oDocument.selection.createRange().duplicate(); |
---|
1881 | - range.moveStart("character", -1); |
---|
1882 | - rect = range.getBoundingClientRect(); |
---|
1883 | - return { |
---|
1884 | - height: rect.bottom - rect.top, |
---|
1885 | - left: rect.left, |
---|
1886 | - top: rect.top |
---|
1887 | - }; |
---|
1888 | - }; |
---|
1889 | - |
---|
1890 | - EditableCaret.prototype.getOffset = function(pos) { |
---|
1891 | - var clonedRange, offset, range, rect, shadowCaret; |
---|
1892 | - if (oWindow.getSelection && (range = this.range())) { |
---|
1893 | - if (range.endOffset - 1 > 0 && range.endContainer !== this.domInputor) { |
---|
1894 | - clonedRange = range.cloneRange(); |
---|
1895 | - clonedRange.setStart(range.endContainer, range.endOffset - 1); |
---|
1896 | - clonedRange.setEnd(range.endContainer, range.endOffset); |
---|
1897 | - rect = clonedRange.getBoundingClientRect(); |
---|
1898 | - offset = { |
---|
1899 | - height: rect.height, |
---|
1900 | - left: rect.left + rect.width, |
---|
1901 | - top: rect.top |
---|
1902 | - }; |
---|
1903 | - clonedRange.detach(); |
---|
1904 | - } |
---|
1905 | - if (!offset || (offset != null ? offset.height : void 0) === 0) { |
---|
1906 | - clonedRange = range.cloneRange(); |
---|
1907 | - shadowCaret = $(oDocument.createTextNode("|")); |
---|
1908 | - clonedRange.insertNode(shadowCaret[0]); |
---|
1909 | - clonedRange.selectNode(shadowCaret[0]); |
---|
1910 | - rect = clonedRange.getBoundingClientRect(); |
---|
1911 | - offset = { |
---|
1912 | - height: rect.height, |
---|
1913 | - left: rect.left, |
---|
1914 | - top: rect.top |
---|
1915 | - }; |
---|
1916 | - shadowCaret.remove(); |
---|
1917 | - clonedRange.detach(); |
---|
1918 | - } |
---|
1919 | - } else if (oDocument.selection) { |
---|
1920 | - offset = this.getOldIEOffset(); |
---|
1921 | - } |
---|
1922 | - if (offset) { |
---|
1923 | - offset.top += $(oWindow).scrollTop(); |
---|
1924 | - offset.left += $(oWindow).scrollLeft(); |
---|
1925 | - } |
---|
1926 | - return offset; |
---|
1927 | - }; |
---|
1928 | - |
---|
1929 | - EditableCaret.prototype.range = function() { |
---|
1930 | - var sel; |
---|
1931 | - if (!oWindow.getSelection) { |
---|
1932 | - return; |
---|
1933 | - } |
---|
1934 | - sel = oWindow.getSelection(); |
---|
1935 | - if (sel.rangeCount > 0) { |
---|
1936 | - return sel.getRangeAt(0); |
---|
1937 | - } else { |
---|
1938 | - return null; |
---|
1939 | - } |
---|
1940 | - }; |
---|
1941 | - |
---|
1942 | - return EditableCaret; |
---|
1943 | - |
---|
1944 | -})(); |
---|
1945 | - |
---|
1946 | -InputCaret = (function() { |
---|
1947 | - function InputCaret($inputor) { |
---|
1948 | - this.$inputor = $inputor; |
---|
1949 | - this.domInputor = this.$inputor[0]; |
---|
1950 | - } |
---|
1951 | - |
---|
1952 | - InputCaret.prototype.getIEPos = function() { |
---|
1953 | - var endRange, inputor, len, normalizedValue, pos, range, textInputRange; |
---|
1954 | - inputor = this.domInputor; |
---|
1955 | - range = oDocument.selection.createRange(); |
---|
1956 | - pos = 0; |
---|
1957 | - if (range && range.parentElement() === inputor) { |
---|
1958 | - normalizedValue = inputor.value.replace(/\r\n/g, "\n"); |
---|
1959 | - len = normalizedValue.length; |
---|
1960 | - textInputRange = inputor.createTextRange(); |
---|
1961 | - textInputRange.moveToBookmark(range.getBookmark()); |
---|
1962 | - endRange = inputor.createTextRange(); |
---|
1963 | - endRange.collapse(false); |
---|
1964 | - if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) { |
---|
1965 | - pos = len; |
---|
1966 | - } else { |
---|
1967 | - pos = -textInputRange.moveStart("character", -len); |
---|
1968 | - } |
---|
1969 | - } |
---|
1970 | - return pos; |
---|
1971 | - }; |
---|
1972 | - |
---|
1973 | - InputCaret.prototype.getPos = function() { |
---|
1974 | - if (oDocument.selection) { |
---|
1975 | - return this.getIEPos(); |
---|
1976 | - } else { |
---|
1977 | - return this.domInputor.selectionStart; |
---|
1978 | - } |
---|
1979 | - }; |
---|
1980 | - |
---|
1981 | - InputCaret.prototype.setPos = function(pos) { |
---|
1982 | - var inputor, range; |
---|
1983 | - inputor = this.domInputor; |
---|
1984 | - if (oDocument.selection) { |
---|
1985 | - range = inputor.createTextRange(); |
---|
1986 | - range.move("character", pos); |
---|
1987 | - range.select(); |
---|
1988 | - } else if (inputor.setSelectionRange) { |
---|
1989 | - inputor.setSelectionRange(pos, pos); |
---|
1990 | - } |
---|
1991 | - return inputor; |
---|
1992 | - }; |
---|
1993 | - |
---|
1994 | - InputCaret.prototype.getIEOffset = function(pos) { |
---|
1995 | - var h, textRange, x, y; |
---|
1996 | - textRange = this.domInputor.createTextRange(); |
---|
1997 | - pos || (pos = this.getPos()); |
---|
1998 | - textRange.move('character', pos); |
---|
1999 | - x = textRange.boundingLeft; |
---|
2000 | - y = textRange.boundingTop; |
---|
2001 | - h = textRange.boundingHeight; |
---|
2002 | - return { |
---|
2003 | - left: x, |
---|
2004 | - top: y, |
---|
2005 | - height: h |
---|
2006 | - }; |
---|
2007 | - }; |
---|
2008 | - |
---|
2009 | - InputCaret.prototype.getOffset = function(pos) { |
---|
2010 | - var $inputor, offset, position; |
---|
2011 | - $inputor = this.$inputor; |
---|
2012 | - if (oDocument.selection) { |
---|
2013 | - offset = this.getIEOffset(pos); |
---|
2014 | - offset.top += $(oWindow).scrollTop() + $inputor.scrollTop(); |
---|
2015 | - offset.left += $(oWindow).scrollLeft() + $inputor.scrollLeft(); |
---|
2016 | - return offset; |
---|
2017 | - } else { |
---|
2018 | - offset = $inputor.offset(); |
---|
2019 | - position = this.getPosition(pos); |
---|
2020 | - return offset = { |
---|
2021 | - left: offset.left + position.left - $inputor.scrollLeft(), |
---|
2022 | - top: offset.top + position.top - $inputor.scrollTop(), |
---|
2023 | - height: position.height |
---|
2024 | - }; |
---|
2025 | - } |
---|
2026 | - }; |
---|
2027 | - |
---|
2028 | - InputCaret.prototype.getPosition = function(pos) { |
---|
2029 | - var $inputor, at_rect, end_range, format, html, mirror, start_range; |
---|
2030 | - $inputor = this.$inputor; |
---|
2031 | - format = function(value) { |
---|
2032 | - value = value.replace(/<|>|`|"|&/g, '?').replace(/\r\n|\r|\n/g, "<br/>"); |
---|
2033 | - if (/firefox/i.test(navigator.userAgent)) { |
---|
2034 | - value = value.replace(/\s/g, ' '); |
---|
2035 | - } |
---|
2036 | - return value; |
---|
2037 | - }; |
---|
2038 | - if (pos === void 0) { |
---|
2039 | - pos = this.getPos(); |
---|
2040 | - } |
---|
2041 | - start_range = $inputor.val().slice(0, pos); |
---|
2042 | - end_range = $inputor.val().slice(pos); |
---|
2043 | - html = "<span style='position: relative; display: inline;'>" + format(start_range) + "</span>"; |
---|
2044 | - html += "<span id='caret' style='position: relative; display: inline;'>|</span>"; |
---|
2045 | - html += "<span style='position: relative; display: inline;'>" + format(end_range) + "</span>"; |
---|
2046 | - mirror = new Mirror($inputor); |
---|
2047 | - return at_rect = mirror.create(html).rect(); |
---|
2048 | - }; |
---|
2049 | - |
---|
2050 | - InputCaret.prototype.getIEPosition = function(pos) { |
---|
2051 | - var h, inputorOffset, offset, x, y; |
---|
2052 | - offset = this.getIEOffset(pos); |
---|
2053 | - inputorOffset = this.$inputor.offset(); |
---|
2054 | - x = offset.left - inputorOffset.left; |
---|
2055 | - y = offset.top - inputorOffset.top; |
---|
2056 | - h = offset.height; |
---|
2057 | - return { |
---|
2058 | - left: x, |
---|
2059 | - top: y, |
---|
2060 | - height: h |
---|
2061 | - }; |
---|
2062 | - }; |
---|
2063 | - |
---|
2064 | - return InputCaret; |
---|
2065 | - |
---|
2066 | -})(); |
---|
2067 | - |
---|
2068 | -Mirror = (function() { |
---|
2069 | - Mirror.prototype.css_attr = ["borderBottomWidth", "borderLeftWidth", "borderRightWidth", "borderTopStyle", "borderRightStyle", "borderBottomStyle", "borderLeftStyle", "borderTopWidth", "boxSizing", "fontFamily", "fontSize", "fontWeight", "height", "letterSpacing", "lineHeight", "marginBottom", "marginLeft", "marginRight", "marginTop", "outlineWidth", "overflow", "overflowX", "overflowY", "paddingBottom", "paddingLeft", "paddingRight", "paddingTop", "textAlign", "textOverflow", "textTransform", "whiteSpace", "wordBreak", "wordWrap"]; |
---|
2070 | - |
---|
2071 | - function Mirror($inputor) { |
---|
2072 | - this.$inputor = $inputor; |
---|
2073 | - } |
---|
2074 | - |
---|
2075 | - Mirror.prototype.mirrorCss = function() { |
---|
2076 | - var css, |
---|
2077 | - _this = this; |
---|
2078 | - css = { |
---|
2079 | - position: 'absolute', |
---|
2080 | - left: -9999, |
---|
2081 | - top: 0, |
---|
2082 | - zIndex: -20000 |
---|
2083 | - }; |
---|
2084 | - if (this.$inputor.prop('tagName') === 'TEXTAREA') { |
---|
2085 | - this.css_attr.push('width'); |
---|
2086 | - } |
---|
2087 | - $.each(this.css_attr, function(i, p) { |
---|
2088 | - return css[p] = _this.$inputor.css(p); |
---|
2089 | - }); |
---|
2090 | - return css; |
---|
2091 | - }; |
---|
2092 | - |
---|
2093 | - Mirror.prototype.create = function(html) { |
---|
2094 | - this.$mirror = $('<div></div>'); |
---|
2095 | - this.$mirror.css(this.mirrorCss()); |
---|
2096 | - this.$mirror.html(html); |
---|
2097 | - this.$inputor.after(this.$mirror); |
---|
2098 | - return this; |
---|
2099 | - }; |
---|
2100 | - |
---|
2101 | - Mirror.prototype.rect = function() { |
---|
2102 | - var $flag, pos, rect; |
---|
2103 | - $flag = this.$mirror.find("#caret"); |
---|
2104 | - pos = $flag.position(); |
---|
2105 | - rect = { |
---|
2106 | - left: pos.left, |
---|
2107 | - top: pos.top, |
---|
2108 | - height: $flag.height() |
---|
2109 | - }; |
---|
2110 | - this.$mirror.remove(); |
---|
2111 | - return rect; |
---|
2112 | - }; |
---|
2113 | - |
---|
2114 | - return Mirror; |
---|
2115 | - |
---|
2116 | -})(); |
---|
2117 | - |
---|
2118 | -Utils = { |
---|
2119 | - contentEditable: function($inputor) { |
---|
2120 | - return !!($inputor[0].contentEditable && $inputor[0].contentEditable === 'true'); |
---|
2121 | - } |
---|
2122 | -}; |
---|
2123 | - |
---|
2124 | -methods = { |
---|
2125 | - pos: function(pos) { |
---|
2126 | - if (pos || pos === 0) { |
---|
2127 | - return this.setPos(pos); |
---|
2128 | - } else { |
---|
2129 | - return this.getPos(); |
---|
2130 | - } |
---|
2131 | - }, |
---|
2132 | - position: function(pos) { |
---|
2133 | - if (oDocument.selection) { |
---|
2134 | - return this.getIEPosition(pos); |
---|
2135 | - } else { |
---|
2136 | - return this.getPosition(pos); |
---|
2137 | - } |
---|
2138 | - }, |
---|
2139 | - offset: function(pos) { |
---|
2140 | - var offset; |
---|
2141 | - offset = this.getOffset(pos); |
---|
2142 | - return offset; |
---|
2143 | - } |
---|
2144 | -}; |
---|
2145 | - |
---|
2146 | -oDocument = null; |
---|
2147 | - |
---|
2148 | -oWindow = null; |
---|
2149 | - |
---|
2150 | -oFrame = null; |
---|
2151 | - |
---|
2152 | -setContextBy = function(settings) { |
---|
2153 | - var iframe; |
---|
2154 | - if (iframe = settings != null ? settings.iframe : void 0) { |
---|
2155 | - oFrame = iframe; |
---|
2156 | - oWindow = iframe.contentWindow; |
---|
2157 | - return oDocument = iframe.contentDocument || oWindow.document; |
---|
2158 | - } else { |
---|
2159 | - oFrame = void 0; |
---|
2160 | - oWindow = window; |
---|
2161 | - return oDocument = document; |
---|
2162 | - } |
---|
2163 | -}; |
---|
2164 | - |
---|
2165 | -discoveryIframeOf = function($dom) { |
---|
2166 | - var error; |
---|
2167 | - oDocument = $dom[0].ownerDocument; |
---|
2168 | - oWindow = oDocument.defaultView || oDocument.parentWindow; |
---|
2169 | - try { |
---|
2170 | - return oFrame = oWindow.frameElement; |
---|
2171 | - } catch (_error) { |
---|
2172 | - error = _error; |
---|
2173 | - } |
---|
2174 | -}; |
---|
2175 | - |
---|
2176 | -$.fn.caret = function(method, value, settings) { |
---|
2177 | - var caret; |
---|
2178 | - if (methods[method]) { |
---|
2179 | - if ($.isPlainObject(value)) { |
---|
2180 | - setContextBy(value); |
---|
2181 | - value = void 0; |
---|
2182 | - } else { |
---|
2183 | - setContextBy(settings); |
---|
2184 | - } |
---|
2185 | - caret = Utils.contentEditable(this) ? new EditableCaret(this) : new InputCaret(this); |
---|
2186 | - return methods[method].apply(caret, [value]); |
---|
2187 | - } else { |
---|
2188 | - return $.error("Method " + method + " does not exist on jQuery.caret"); |
---|
2189 | - } |
---|
2190 | -}; |
---|
2191 | - |
---|
2192 | -$.fn.caret.EditableCaret = EditableCaret; |
---|
2193 | - |
---|
2194 | -$.fn.caret.InputCaret = InputCaret; |
---|
2195 | - |
---|
2196 | -$.fn.caret.Utils = Utils; |
---|
2197 | - |
---|
2198 | -$.fn.caret.apis = methods; |
---|
2199 | - |
---|
2200 | - |
---|
2201 | -})); |
---|
2202 | diff --git src/bp-core/js/vendor/jquery.caret.txt src/bp-core/js/vendor/jquery.caret.txt |
---|
2203 | deleted file mode 100644 |
---|
2204 | index 36cd1c122..000000000 |
---|
2205 | --- src/bp-core/js/vendor/jquery.caret.txt |
---|
2206 | +++ /dev/null |
---|
2207 | @@ -1,22 +0,0 @@ |
---|
2208 | -Copyright (c) 2013 chord.luo@gmail.com |
---|
2209 | - |
---|
2210 | -Permission is hereby granted, free of charge, to any person |
---|
2211 | -obtaining a copy of this software and associated documentation |
---|
2212 | -files (the "Software"), to deal in the Software without |
---|
2213 | -restriction, including without limitation the rights to use, |
---|
2214 | -copy, modify, merge, publish, distribute, sublicense, and/or sell |
---|
2215 | -copies of the Software, and to permit persons to whom the |
---|
2216 | -Software is furnished to do so, subject to the following |
---|
2217 | -conditions: |
---|
2218 | - |
---|
2219 | -The above copyright notice and this permission notice shall be |
---|
2220 | -included in all copies or substantial portions of the Software. |
---|
2221 | - |
---|
2222 | -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
---|
2223 | -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
---|
2224 | -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
---|
2225 | -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
---|
2226 | -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
---|
2227 | -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
---|
2228 | -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
---|
2229 | -OTHER DEALINGS IN THE SOFTWARE. |
---|
2230 | diff --git src/bp-core/js/vendor/tribute.js src/bp-core/js/vendor/tribute.js |
---|
2231 | new file mode 100644 |
---|
2232 | index 000000000..bd029c928 |
---|
2233 | --- /dev/null |
---|
2234 | +++ src/bp-core/js/vendor/tribute.js |
---|
2235 | @@ -0,0 +1,1798 @@ |
---|
2236 | +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Tribute = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ |
---|
2237 | +"use strict"; |
---|
2238 | + |
---|
2239 | +Object.defineProperty(exports, "__esModule", { |
---|
2240 | + value: true |
---|
2241 | +}); |
---|
2242 | + |
---|
2243 | +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); |
---|
2244 | + |
---|
2245 | +var _utils = require("./utils"); |
---|
2246 | + |
---|
2247 | +var _utils2 = _interopRequireDefault(_utils); |
---|
2248 | + |
---|
2249 | +var _TributeEvents = require("./TributeEvents"); |
---|
2250 | + |
---|
2251 | +var _TributeEvents2 = _interopRequireDefault(_TributeEvents); |
---|
2252 | + |
---|
2253 | +var _TributeMenuEvents = require("./TributeMenuEvents"); |
---|
2254 | + |
---|
2255 | +var _TributeMenuEvents2 = _interopRequireDefault(_TributeMenuEvents); |
---|
2256 | + |
---|
2257 | +var _TributeRange = require("./TributeRange"); |
---|
2258 | + |
---|
2259 | +var _TributeRange2 = _interopRequireDefault(_TributeRange); |
---|
2260 | + |
---|
2261 | +var _TributeSearch = require("./TributeSearch"); |
---|
2262 | + |
---|
2263 | +var _TributeSearch2 = _interopRequireDefault(_TributeSearch); |
---|
2264 | + |
---|
2265 | +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } |
---|
2266 | + |
---|
2267 | +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } |
---|
2268 | + |
---|
2269 | +var Tribute = function () { |
---|
2270 | + function Tribute(_ref) { |
---|
2271 | + var _this = this; |
---|
2272 | + |
---|
2273 | + var _ref$values = _ref.values, |
---|
2274 | + values = _ref$values === undefined ? null : _ref$values, |
---|
2275 | + _ref$iframe = _ref.iframe, |
---|
2276 | + iframe = _ref$iframe === undefined ? null : _ref$iframe, |
---|
2277 | + _ref$selectClass = _ref.selectClass, |
---|
2278 | + selectClass = _ref$selectClass === undefined ? 'highlight' : _ref$selectClass, |
---|
2279 | + _ref$trigger = _ref.trigger, |
---|
2280 | + trigger = _ref$trigger === undefined ? '@' : _ref$trigger, |
---|
2281 | + _ref$selectTemplate = _ref.selectTemplate, |
---|
2282 | + selectTemplate = _ref$selectTemplate === undefined ? null : _ref$selectTemplate, |
---|
2283 | + _ref$menuItemTemplate = _ref.menuItemTemplate, |
---|
2284 | + menuItemTemplate = _ref$menuItemTemplate === undefined ? null : _ref$menuItemTemplate, |
---|
2285 | + _ref$lookup = _ref.lookup, |
---|
2286 | + lookup = _ref$lookup === undefined ? 'key' : _ref$lookup, |
---|
2287 | + _ref$fillAttr = _ref.fillAttr, |
---|
2288 | + fillAttr = _ref$fillAttr === undefined ? 'value' : _ref$fillAttr, |
---|
2289 | + _ref$collection = _ref.collection, |
---|
2290 | + collection = _ref$collection === undefined ? null : _ref$collection, |
---|
2291 | + _ref$menuContainer = _ref.menuContainer, |
---|
2292 | + menuContainer = _ref$menuContainer === undefined ? null : _ref$menuContainer, |
---|
2293 | + _ref$noMatchTemplate = _ref.noMatchTemplate, |
---|
2294 | + noMatchTemplate = _ref$noMatchTemplate === undefined ? null : _ref$noMatchTemplate, |
---|
2295 | + _ref$requireLeadingSp = _ref.requireLeadingSpace, |
---|
2296 | + requireLeadingSpace = _ref$requireLeadingSp === undefined ? true : _ref$requireLeadingSp, |
---|
2297 | + _ref$allowSpaces = _ref.allowSpaces, |
---|
2298 | + allowSpaces = _ref$allowSpaces === undefined ? false : _ref$allowSpaces, |
---|
2299 | + _ref$replaceTextSuffi = _ref.replaceTextSuffix, |
---|
2300 | + replaceTextSuffix = _ref$replaceTextSuffi === undefined ? null : _ref$replaceTextSuffi, |
---|
2301 | + _ref$positionMenu = _ref.positionMenu, |
---|
2302 | + positionMenu = _ref$positionMenu === undefined ? true : _ref$positionMenu, |
---|
2303 | + _ref$spaceSelectsMatc = _ref.spaceSelectsMatch, |
---|
2304 | + spaceSelectsMatch = _ref$spaceSelectsMatc === undefined ? false : _ref$spaceSelectsMatc; |
---|
2305 | + |
---|
2306 | + _classCallCheck(this, Tribute); |
---|
2307 | + |
---|
2308 | + this.menuSelected = 0; |
---|
2309 | + this.current = {}; |
---|
2310 | + this.inputEvent = false; |
---|
2311 | + this.isActive = false; |
---|
2312 | + this.menuContainer = menuContainer; |
---|
2313 | + this.allowSpaces = allowSpaces; |
---|
2314 | + this.replaceTextSuffix = replaceTextSuffix; |
---|
2315 | + this.positionMenu = positionMenu; |
---|
2316 | + this.hasTrailingSpace = false; |
---|
2317 | + this.spaceSelectsMatch = spaceSelectsMatch; |
---|
2318 | + |
---|
2319 | + if (values) { |
---|
2320 | + this.collection = [{ |
---|
2321 | + // symbol that starts the lookup |
---|
2322 | + trigger: trigger, |
---|
2323 | + |
---|
2324 | + // is it wrapped in an iframe |
---|
2325 | + iframe: iframe, |
---|
2326 | + |
---|
2327 | + // class applied to selected item |
---|
2328 | + selectClass: selectClass, |
---|
2329 | + |
---|
2330 | + // function called on select that retuns the content to insert |
---|
2331 | + selectTemplate: (selectTemplate || Tribute.defaultSelectTemplate).bind(this), |
---|
2332 | + |
---|
2333 | + // function called that returns content for an item |
---|
2334 | + menuItemTemplate: (menuItemTemplate || Tribute.defaultMenuItemTemplate).bind(this), |
---|
2335 | + |
---|
2336 | + // function called when menu is empty, disables hiding of menu. |
---|
2337 | + noMatchTemplate: function (t) { |
---|
2338 | + if (typeof t === 'function') { |
---|
2339 | + return t.bind(_this); |
---|
2340 | + } |
---|
2341 | + |
---|
2342 | + return noMatchTemplate; |
---|
2343 | + }(noMatchTemplate), |
---|
2344 | + |
---|
2345 | + // column to search against in the object |
---|
2346 | + lookup: lookup, |
---|
2347 | + |
---|
2348 | + // column that contains the content to insert by default |
---|
2349 | + fillAttr: fillAttr, |
---|
2350 | + |
---|
2351 | + // array of objects or a function returning an array of objects |
---|
2352 | + values: values, |
---|
2353 | + |
---|
2354 | + requireLeadingSpace: requireLeadingSpace |
---|
2355 | + }]; |
---|
2356 | + } else if (collection) { |
---|
2357 | + this.collection = collection.map(function (item) { |
---|
2358 | + return { |
---|
2359 | + trigger: item.trigger || trigger, |
---|
2360 | + iframe: item.iframe || iframe, |
---|
2361 | + selectClass: item.selectClass || selectClass, |
---|
2362 | + selectTemplate: (item.selectTemplate || Tribute.defaultSelectTemplate).bind(_this), |
---|
2363 | + menuItemTemplate: (item.menuItemTemplate || Tribute.defaultMenuItemTemplate).bind(_this), |
---|
2364 | + // function called when menu is empty, disables hiding of menu. |
---|
2365 | + noMatchTemplate: function (t) { |
---|
2366 | + if (typeof t === 'function') { |
---|
2367 | + return t.bind(_this); |
---|
2368 | + } |
---|
2369 | + |
---|
2370 | + return null; |
---|
2371 | + }(noMatchTemplate), |
---|
2372 | + lookup: item.lookup || lookup, |
---|
2373 | + fillAttr: item.fillAttr || fillAttr, |
---|
2374 | + values: item.values, |
---|
2375 | + requireLeadingSpace: item.requireLeadingSpace |
---|
2376 | + }; |
---|
2377 | + }); |
---|
2378 | + } else { |
---|
2379 | + throw new Error('[Tribute] No collection specified.'); |
---|
2380 | + } |
---|
2381 | + |
---|
2382 | + new _TributeRange2.default(this); |
---|
2383 | + new _TributeEvents2.default(this); |
---|
2384 | + new _TributeMenuEvents2.default(this); |
---|
2385 | + new _TributeSearch2.default(this); |
---|
2386 | + } |
---|
2387 | + |
---|
2388 | + _createClass(Tribute, [{ |
---|
2389 | + key: "triggers", |
---|
2390 | + value: function triggers() { |
---|
2391 | + return this.collection.map(function (config) { |
---|
2392 | + return config.trigger; |
---|
2393 | + }); |
---|
2394 | + } |
---|
2395 | + }, { |
---|
2396 | + key: "attach", |
---|
2397 | + value: function attach(el) { |
---|
2398 | + if (!el) { |
---|
2399 | + throw new Error('[Tribute] Must pass in a DOM node or NodeList.'); |
---|
2400 | + } |
---|
2401 | + |
---|
2402 | + // Check if it is a jQuery collection |
---|
2403 | + if (typeof jQuery !== 'undefined' && el instanceof jQuery) { |
---|
2404 | + el = el.get(); |
---|
2405 | + } |
---|
2406 | + |
---|
2407 | + // Is el an Array/Array-like object? |
---|
2408 | + if (el.constructor === NodeList || el.constructor === HTMLCollection || el.constructor === Array) { |
---|
2409 | + var length = el.length; |
---|
2410 | + for (var i = 0; i < length; ++i) { |
---|
2411 | + this._attach(el[i]); |
---|
2412 | + } |
---|
2413 | + } else { |
---|
2414 | + this._attach(el); |
---|
2415 | + } |
---|
2416 | + } |
---|
2417 | + }, { |
---|
2418 | + key: "_attach", |
---|
2419 | + value: function _attach(el) { |
---|
2420 | + if (el.hasAttribute('data-tribute')) { |
---|
2421 | + console.warn('Tribute was already bound to ' + el.nodeName); |
---|
2422 | + } |
---|
2423 | + |
---|
2424 | + this.ensureEditable(el); |
---|
2425 | + this.events.bind(el); |
---|
2426 | + el.setAttribute('data-tribute', true); |
---|
2427 | + } |
---|
2428 | + }, { |
---|
2429 | + key: "ensureEditable", |
---|
2430 | + value: function ensureEditable(element) { |
---|
2431 | + if (Tribute.inputTypes().indexOf(element.nodeName) === -1) { |
---|
2432 | + if (element.contentEditable) { |
---|
2433 | + element.contentEditable = true; |
---|
2434 | + } else { |
---|
2435 | + throw new Error('[Tribute] Cannot bind to ' + element.nodeName); |
---|
2436 | + } |
---|
2437 | + } |
---|
2438 | + } |
---|
2439 | + }, { |
---|
2440 | + key: "createMenu", |
---|
2441 | + value: function createMenu() { |
---|
2442 | + var wrapper = this.range.getDocument().createElement('div'), |
---|
2443 | + ul = this.range.getDocument().createElement('ul'); |
---|
2444 | + |
---|
2445 | + wrapper.className = 'tribute-container'; |
---|
2446 | + wrapper.appendChild(ul); |
---|
2447 | + |
---|
2448 | + if (this.menuContainer) { |
---|
2449 | + return this.menuContainer.appendChild(wrapper); |
---|
2450 | + } |
---|
2451 | + |
---|
2452 | + return this.range.getDocument().body.appendChild(wrapper); |
---|
2453 | + } |
---|
2454 | + }, { |
---|
2455 | + key: "showMenuFor", |
---|
2456 | + value: function showMenuFor(element, scrollTo) { |
---|
2457 | + var _this2 = this; |
---|
2458 | + |
---|
2459 | + // Only proceed if menu isn't already shown for the current element & mentionText |
---|
2460 | + if (this.isActive && this.current.element === element && this.current.mentionText === this.currentMentionTextSnapshot) { |
---|
2461 | + return; |
---|
2462 | + } |
---|
2463 | + this.currentMentionTextSnapshot = this.current.mentionText; |
---|
2464 | + |
---|
2465 | + // create the menu if it doesn't exist. |
---|
2466 | + if (!this.menu) { |
---|
2467 | + this.menu = this.createMenu(); |
---|
2468 | + element.tributeMenu = this.menu; |
---|
2469 | + this.menuEvents.bind(this.menu); |
---|
2470 | + } |
---|
2471 | + |
---|
2472 | + this.isActive = true; |
---|
2473 | + this.menuSelected = 0; |
---|
2474 | + |
---|
2475 | + if (!this.current.mentionText) { |
---|
2476 | + this.current.mentionText = ''; |
---|
2477 | + } |
---|
2478 | + |
---|
2479 | + var processValues = function processValues(values) { |
---|
2480 | + // Tribute may not be active any more by the time the value callback returns |
---|
2481 | + if (!_this2.isActive) { |
---|
2482 | + return; |
---|
2483 | + } |
---|
2484 | + |
---|
2485 | + var items = _this2.search.filter(_this2.current.mentionText, values, { |
---|
2486 | + pre: '<span>', |
---|
2487 | + post: '</span>', |
---|
2488 | + extract: function extract(el) { |
---|
2489 | + if (typeof _this2.current.collection.lookup === 'string') { |
---|
2490 | + return el[_this2.current.collection.lookup]; |
---|
2491 | + } else if (typeof _this2.current.collection.lookup === 'function') { |
---|
2492 | + return _this2.current.collection.lookup(el, _this2.current.mentionText); |
---|
2493 | + } else { |
---|
2494 | + throw new Error('Invalid lookup attribute, lookup must be string or function.'); |
---|
2495 | + } |
---|
2496 | + } |
---|
2497 | + }); |
---|
2498 | + |
---|
2499 | + _this2.current.filteredItems = items; |
---|
2500 | + |
---|
2501 | + var ul = _this2.menu.querySelector('ul'); |
---|
2502 | + |
---|
2503 | + _this2.range.positionMenuAtCaret(scrollTo); |
---|
2504 | + |
---|
2505 | + if (!items.length) { |
---|
2506 | + var noMatchEvent = new CustomEvent('tribute-no-match', { detail: _this2.menu }); |
---|
2507 | + _this2.current.element.dispatchEvent(noMatchEvent); |
---|
2508 | + if (!_this2.current.collection.noMatchTemplate) { |
---|
2509 | + _this2.hideMenu(); |
---|
2510 | + } else { |
---|
2511 | + ul.innerHTML = _this2.current.collection.noMatchTemplate(); |
---|
2512 | + } |
---|
2513 | + |
---|
2514 | + return; |
---|
2515 | + } |
---|
2516 | + |
---|
2517 | + ul.innerHTML = ''; |
---|
2518 | + |
---|
2519 | + items.forEach(function (item, index) { |
---|
2520 | + var li = _this2.range.getDocument().createElement('li'); |
---|
2521 | + li.setAttribute('data-index', index); |
---|
2522 | + li.addEventListener('mouseenter', function (e) { |
---|
2523 | + var li = e.target; |
---|
2524 | + var index = li.getAttribute('data-index'); |
---|
2525 | + _this2.events.setActiveLi(index); |
---|
2526 | + }); |
---|
2527 | + if (_this2.menuSelected === index) { |
---|
2528 | + li.className = _this2.current.collection.selectClass; |
---|
2529 | + } |
---|
2530 | + li.innerHTML = _this2.current.collection.menuItemTemplate(item); |
---|
2531 | + ul.appendChild(li); |
---|
2532 | + }); |
---|
2533 | + }; |
---|
2534 | + |
---|
2535 | + if (typeof this.current.collection.values === 'function') { |
---|
2536 | + this.current.collection.values(this.current.mentionText, processValues); |
---|
2537 | + } else { |
---|
2538 | + processValues(this.current.collection.values); |
---|
2539 | + } |
---|
2540 | + } |
---|
2541 | + }, { |
---|
2542 | + key: "showMenuForCollection", |
---|
2543 | + value: function showMenuForCollection(element, collectionIndex) { |
---|
2544 | + if (element !== document.activeElement) { |
---|
2545 | + this.placeCaretAtEnd(element); |
---|
2546 | + } |
---|
2547 | + |
---|
2548 | + this.current.collection = this.collection[collectionIndex || 0]; |
---|
2549 | + this.current.externalTrigger = true; |
---|
2550 | + this.current.element = element; |
---|
2551 | + |
---|
2552 | + if (element.isContentEditable) this.insertTextAtCursor(this.current.collection.trigger);else this.insertAtCaret(element, this.current.collection.trigger); |
---|
2553 | + |
---|
2554 | + this.showMenuFor(element); |
---|
2555 | + } |
---|
2556 | + |
---|
2557 | + // TODO: make sure this works for inputs/textareas |
---|
2558 | + |
---|
2559 | + }, { |
---|
2560 | + key: "placeCaretAtEnd", |
---|
2561 | + value: function placeCaretAtEnd(el) { |
---|
2562 | + el.focus(); |
---|
2563 | + if (typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") { |
---|
2564 | + var range = document.createRange(); |
---|
2565 | + range.selectNodeContents(el); |
---|
2566 | + range.collapse(false); |
---|
2567 | + var sel = window.getSelection(); |
---|
2568 | + sel.removeAllRanges(); |
---|
2569 | + sel.addRange(range); |
---|
2570 | + } else if (typeof document.body.createTextRange != "undefined") { |
---|
2571 | + var textRange = document.body.createTextRange(); |
---|
2572 | + textRange.moveToElementText(el); |
---|
2573 | + textRange.collapse(false); |
---|
2574 | + textRange.select(); |
---|
2575 | + } |
---|
2576 | + } |
---|
2577 | + |
---|
2578 | + // for contenteditable |
---|
2579 | + |
---|
2580 | + }, { |
---|
2581 | + key: "insertTextAtCursor", |
---|
2582 | + value: function insertTextAtCursor(text) { |
---|
2583 | + var sel, range, html; |
---|
2584 | + sel = window.getSelection(); |
---|
2585 | + range = sel.getRangeAt(0); |
---|
2586 | + range.deleteContents(); |
---|
2587 | + var textNode = document.createTextNode(text); |
---|
2588 | + range.insertNode(textNode); |
---|
2589 | + range.selectNodeContents(textNode); |
---|
2590 | + range.collapse(false); |
---|
2591 | + sel.removeAllRanges(); |
---|
2592 | + sel.addRange(range); |
---|
2593 | + } |
---|
2594 | + |
---|
2595 | + // for regular inputs |
---|
2596 | + |
---|
2597 | + }, { |
---|
2598 | + key: "insertAtCaret", |
---|
2599 | + value: function insertAtCaret(textarea, text) { |
---|
2600 | + var scrollPos = textarea.scrollTop; |
---|
2601 | + var caretPos = textarea.selectionStart; |
---|
2602 | + |
---|
2603 | + var front = textarea.value.substring(0, caretPos); |
---|
2604 | + var back = textarea.value.substring(textarea.selectionEnd, textarea.value.length); |
---|
2605 | + textarea.value = front + text + back; |
---|
2606 | + caretPos = caretPos + text.length; |
---|
2607 | + textarea.selectionStart = caretPos; |
---|
2608 | + textarea.selectionEnd = caretPos; |
---|
2609 | + textarea.focus(); |
---|
2610 | + textarea.scrollTop = scrollPos; |
---|
2611 | + } |
---|
2612 | + }, { |
---|
2613 | + key: "hideMenu", |
---|
2614 | + value: function hideMenu() { |
---|
2615 | + if (this.menu) { |
---|
2616 | + this.menu.style.cssText = 'display: none;'; |
---|
2617 | + this.isActive = false; |
---|
2618 | + this.menuSelected = 0; |
---|
2619 | + this.current = {}; |
---|
2620 | + } |
---|
2621 | + } |
---|
2622 | + }, { |
---|
2623 | + key: "selectItemAtIndex", |
---|
2624 | + value: function selectItemAtIndex(index, originalEvent) { |
---|
2625 | + index = parseInt(index); |
---|
2626 | + if (typeof index !== 'number') return; |
---|
2627 | + var item = this.current.filteredItems[index]; |
---|
2628 | + var content = this.current.collection.selectTemplate(item); |
---|
2629 | + if (content !== null) this.replaceText(content, originalEvent, item); |
---|
2630 | + } |
---|
2631 | + }, { |
---|
2632 | + key: "replaceText", |
---|
2633 | + value: function replaceText(content, originalEvent, item) { |
---|
2634 | + this.range.replaceTriggerText(content, true, true, originalEvent, item); |
---|
2635 | + } |
---|
2636 | + }, { |
---|
2637 | + key: "_append", |
---|
2638 | + value: function _append(collection, newValues, replace) { |
---|
2639 | + if (typeof collection.values === 'function') { |
---|
2640 | + throw new Error('Unable to append to values, as it is a function.'); |
---|
2641 | + } else if (!replace) { |
---|
2642 | + collection.values = collection.values.concat(newValues); |
---|
2643 | + } else { |
---|
2644 | + collection.values = newValues; |
---|
2645 | + } |
---|
2646 | + } |
---|
2647 | + }, { |
---|
2648 | + key: "append", |
---|
2649 | + value: function append(collectionIndex, newValues, replace) { |
---|
2650 | + var index = parseInt(collectionIndex); |
---|
2651 | + if (typeof index !== 'number') throw new Error('please provide an index for the collection to update.'); |
---|
2652 | + |
---|
2653 | + var collection = this.collection[index]; |
---|
2654 | + |
---|
2655 | + this._append(collection, newValues, replace); |
---|
2656 | + } |
---|
2657 | + }, { |
---|
2658 | + key: "appendCurrent", |
---|
2659 | + value: function appendCurrent(newValues, replace) { |
---|
2660 | + if (this.isActive) { |
---|
2661 | + this._append(this.current.collection, newValues, replace); |
---|
2662 | + } else { |
---|
2663 | + throw new Error('No active state. Please use append instead and pass an index.'); |
---|
2664 | + } |
---|
2665 | + } |
---|
2666 | + }, { |
---|
2667 | + key: "detach", |
---|
2668 | + value: function detach(el) { |
---|
2669 | + if (!el) { |
---|
2670 | + throw new Error('[Tribute] Must pass in a DOM node or NodeList.'); |
---|
2671 | + } |
---|
2672 | + |
---|
2673 | + // Check if it is a jQuery collection |
---|
2674 | + if (typeof jQuery !== 'undefined' && el instanceof jQuery) { |
---|
2675 | + el = el.get(); |
---|
2676 | + } |
---|
2677 | + |
---|
2678 | + // Is el an Array/Array-like object? |
---|
2679 | + if (el.constructor === NodeList || el.constructor === HTMLCollection || el.constructor === Array) { |
---|
2680 | + var length = el.length; |
---|
2681 | + for (var i = 0; i < length; ++i) { |
---|
2682 | + this._detach(el[i]); |
---|
2683 | + } |
---|
2684 | + } else { |
---|
2685 | + this._detach(el); |
---|
2686 | + } |
---|
2687 | + } |
---|
2688 | + }, { |
---|
2689 | + key: "_detach", |
---|
2690 | + value: function _detach(el) { |
---|
2691 | + var _this3 = this; |
---|
2692 | + |
---|
2693 | + this.events.unbind(el); |
---|
2694 | + if (el.tributeMenu) { |
---|
2695 | + this.menuEvents.unbind(el.tributeMenu); |
---|
2696 | + } |
---|
2697 | + |
---|
2698 | + setTimeout(function () { |
---|
2699 | + el.removeAttribute('data-tribute'); |
---|
2700 | + _this3.isActive = false; |
---|
2701 | + if (el.tributeMenu) { |
---|
2702 | + el.tributeMenu.remove(); |
---|
2703 | + } |
---|
2704 | + }); |
---|
2705 | + } |
---|
2706 | + }], [{ |
---|
2707 | + key: "defaultSelectTemplate", |
---|
2708 | + value: function defaultSelectTemplate(item) { |
---|
2709 | + if (typeof item === 'undefined') return null; |
---|
2710 | + if (this.range.isContentEditable(this.current.element)) { |
---|
2711 | + return '<span class="tribute-mention">' + (this.current.collection.trigger + item.original[this.current.collection.fillAttr]) + '</span>'; |
---|
2712 | + } |
---|
2713 | + |
---|
2714 | + return this.current.collection.trigger + item.original[this.current.collection.fillAttr]; |
---|
2715 | + } |
---|
2716 | + }, { |
---|
2717 | + key: "defaultMenuItemTemplate", |
---|
2718 | + value: function defaultMenuItemTemplate(matchItem) { |
---|
2719 | + return matchItem.string; |
---|
2720 | + } |
---|
2721 | + }, { |
---|
2722 | + key: "inputTypes", |
---|
2723 | + value: function inputTypes() { |
---|
2724 | + return ['TEXTAREA', 'INPUT']; |
---|
2725 | + } |
---|
2726 | + }]); |
---|
2727 | + |
---|
2728 | + return Tribute; |
---|
2729 | +}(); |
---|
2730 | + |
---|
2731 | +exports.default = Tribute; |
---|
2732 | +module.exports = exports["default"]; |
---|
2733 | + |
---|
2734 | +},{"./TributeEvents":2,"./TributeMenuEvents":3,"./TributeRange":4,"./TributeSearch":5,"./utils":7}],2:[function(require,module,exports){ |
---|
2735 | +'use strict'; |
---|
2736 | + |
---|
2737 | +Object.defineProperty(exports, "__esModule", { |
---|
2738 | + value: true |
---|
2739 | +}); |
---|
2740 | + |
---|
2741 | +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); |
---|
2742 | + |
---|
2743 | +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } |
---|
2744 | + |
---|
2745 | +var TributeEvents = function () { |
---|
2746 | + function TributeEvents(tribute) { |
---|
2747 | + _classCallCheck(this, TributeEvents); |
---|
2748 | + |
---|
2749 | + this.tribute = tribute; |
---|
2750 | + this.tribute.events = this; |
---|
2751 | + } |
---|
2752 | + |
---|
2753 | + _createClass(TributeEvents, [{ |
---|
2754 | + key: 'bind', |
---|
2755 | + value: function bind(element) { |
---|
2756 | + element.boundKeydown = this.keydown.bind(element, this); |
---|
2757 | + element.boundKeyup = this.keyup.bind(element, this); |
---|
2758 | + element.boundInput = this.input.bind(element, this); |
---|
2759 | + |
---|
2760 | + element.addEventListener('keydown', element.boundKeydown, false); |
---|
2761 | + element.addEventListener('keyup', element.boundKeyup, false); |
---|
2762 | + element.addEventListener('input', element.boundInput, false); |
---|
2763 | + } |
---|
2764 | + }, { |
---|
2765 | + key: 'unbind', |
---|
2766 | + value: function unbind(element) { |
---|
2767 | + element.removeEventListener('keydown', element.boundKeydown, false); |
---|
2768 | + element.removeEventListener('keyup', element.boundKeyup, false); |
---|
2769 | + element.removeEventListener('input', element.boundInput, false); |
---|
2770 | + |
---|
2771 | + delete element.boundKeydown; |
---|
2772 | + delete element.boundKeyup; |
---|
2773 | + delete element.boundInput; |
---|
2774 | + } |
---|
2775 | + }, { |
---|
2776 | + key: 'keydown', |
---|
2777 | + value: function keydown(instance, event) { |
---|
2778 | + if (instance.shouldDeactivate(event)) { |
---|
2779 | + instance.tribute.isActive = false; |
---|
2780 | + instance.tribute.hideMenu(); |
---|
2781 | + } |
---|
2782 | + |
---|
2783 | + var element = this; |
---|
2784 | + instance.commandEvent = false; |
---|
2785 | + |
---|
2786 | + TributeEvents.keys().forEach(function (o) { |
---|
2787 | + if (o.key === event.keyCode) { |
---|
2788 | + instance.commandEvent = true; |
---|
2789 | + instance.callbacks()[o.value.toLowerCase()](event, element); |
---|
2790 | + } |
---|
2791 | + }); |
---|
2792 | + } |
---|
2793 | + }, { |
---|
2794 | + key: 'input', |
---|
2795 | + value: function input(instance, event) { |
---|
2796 | + instance.inputEvent = true; |
---|
2797 | + instance.keyup.call(this, instance, event); |
---|
2798 | + } |
---|
2799 | + }, { |
---|
2800 | + key: 'click', |
---|
2801 | + value: function click(instance, event) { |
---|
2802 | + var tribute = instance.tribute; |
---|
2803 | + if (tribute.menu && tribute.menu.contains(event.target)) { |
---|
2804 | + var li = event.target; |
---|
2805 | + event.preventDefault(); |
---|
2806 | + event.stopPropagation(); |
---|
2807 | + while (li.nodeName.toLowerCase() !== 'li') { |
---|
2808 | + li = li.parentNode; |
---|
2809 | + if (!li || li === tribute.menu) { |
---|
2810 | + throw new Error('cannot find the <li> container for the click'); |
---|
2811 | + } |
---|
2812 | + } |
---|
2813 | + tribute.selectItemAtIndex(li.getAttribute('data-index'), event); |
---|
2814 | + tribute.hideMenu(); |
---|
2815 | + |
---|
2816 | + // TODO: should fire with externalTrigger and target is outside of menu |
---|
2817 | + } else if (tribute.current.element && !tribute.current.externalTrigger) { |
---|
2818 | + tribute.current.externalTrigger = false; |
---|
2819 | + setTimeout(function () { |
---|
2820 | + return tribute.hideMenu(); |
---|
2821 | + }); |
---|
2822 | + } |
---|
2823 | + } |
---|
2824 | + }, { |
---|
2825 | + key: 'keyup', |
---|
2826 | + value: function keyup(instance, event) { |
---|
2827 | + if (instance.inputEvent) { |
---|
2828 | + instance.inputEvent = false; |
---|
2829 | + } |
---|
2830 | + instance.updateSelection(this); |
---|
2831 | + |
---|
2832 | + if (event.keyCode === 27) return; |
---|
2833 | + |
---|
2834 | + if (!instance.tribute.allowSpaces && instance.tribute.hasTrailingSpace) { |
---|
2835 | + instance.tribute.hasTrailingSpace = false; |
---|
2836 | + instance.commandEvent = true; |
---|
2837 | + instance.callbacks()["space"](event, this); |
---|
2838 | + return; |
---|
2839 | + } |
---|
2840 | + |
---|
2841 | + if (!instance.tribute.isActive) { |
---|
2842 | + var keyCode = instance.getKeyCode(instance, this, event); |
---|
2843 | + |
---|
2844 | + if (isNaN(keyCode) || !keyCode) return; |
---|
2845 | + |
---|
2846 | + var trigger = instance.tribute.triggers().find(function (trigger) { |
---|
2847 | + return trigger.charCodeAt(0) === keyCode; |
---|
2848 | + }); |
---|
2849 | + |
---|
2850 | + if (typeof trigger !== 'undefined') { |
---|
2851 | + instance.callbacks().triggerChar(event, this, trigger); |
---|
2852 | + } |
---|
2853 | + } |
---|
2854 | + |
---|
2855 | + if (instance.tribute.current.trigger && instance.commandEvent === false || instance.tribute.isActive && event.keyCode === 8) { |
---|
2856 | + instance.tribute.showMenuFor(this, true); |
---|
2857 | + } |
---|
2858 | + } |
---|
2859 | + }, { |
---|
2860 | + key: 'shouldDeactivate', |
---|
2861 | + value: function shouldDeactivate(event) { |
---|
2862 | + if (!this.tribute.isActive) return false; |
---|
2863 | + |
---|
2864 | + if (this.tribute.current.mentionText.length === 0) { |
---|
2865 | + var eventKeyPressed = false; |
---|
2866 | + TributeEvents.keys().forEach(function (o) { |
---|
2867 | + if (event.keyCode === o.key) eventKeyPressed = true; |
---|
2868 | + }); |
---|
2869 | + |
---|
2870 | + return !eventKeyPressed; |
---|
2871 | + } |
---|
2872 | + |
---|
2873 | + return false; |
---|
2874 | + } |
---|
2875 | + }, { |
---|
2876 | + key: 'getKeyCode', |
---|
2877 | + value: function getKeyCode(instance, el, event) { |
---|
2878 | + var char = void 0; |
---|
2879 | + var tribute = instance.tribute; |
---|
2880 | + var info = tribute.range.getTriggerInfo(false, tribute.hasTrailingSpace, true, tribute.allowSpaces); |
---|
2881 | + |
---|
2882 | + if (info) { |
---|
2883 | + return info.mentionTriggerChar.charCodeAt(0); |
---|
2884 | + } else { |
---|
2885 | + return false; |
---|
2886 | + } |
---|
2887 | + } |
---|
2888 | + }, { |
---|
2889 | + key: 'updateSelection', |
---|
2890 | + value: function updateSelection(el) { |
---|
2891 | + this.tribute.current.element = el; |
---|
2892 | + var info = this.tribute.range.getTriggerInfo(false, this.tribute.hasTrailingSpace, true, this.tribute.allowSpaces); |
---|
2893 | + |
---|
2894 | + if (info) { |
---|
2895 | + this.tribute.current.selectedPath = info.mentionSelectedPath; |
---|
2896 | + this.tribute.current.mentionText = info.mentionText; |
---|
2897 | + this.tribute.current.selectedOffset = info.mentionSelectedOffset; |
---|
2898 | + } |
---|
2899 | + } |
---|
2900 | + }, { |
---|
2901 | + key: 'callbacks', |
---|
2902 | + value: function callbacks() { |
---|
2903 | + var _this = this; |
---|
2904 | + |
---|
2905 | + return { |
---|
2906 | + triggerChar: function triggerChar(e, el, trigger) { |
---|
2907 | + var tribute = _this.tribute; |
---|
2908 | + tribute.current.trigger = trigger; |
---|
2909 | + |
---|
2910 | + var collectionItem = tribute.collection.find(function (item) { |
---|
2911 | + return item.trigger === trigger; |
---|
2912 | + }); |
---|
2913 | + |
---|
2914 | + tribute.current.collection = collectionItem; |
---|
2915 | + if (tribute.inputEvent) tribute.showMenuFor(el, true); |
---|
2916 | + }, |
---|
2917 | + enter: function enter(e, el) { |
---|
2918 | + // choose selection |
---|
2919 | + if (_this.tribute.isActive) { |
---|
2920 | + e.preventDefault(); |
---|
2921 | + e.stopPropagation(); |
---|
2922 | + setTimeout(function () { |
---|
2923 | + _this.tribute.selectItemAtIndex(_this.tribute.menuSelected, e); |
---|
2924 | + _this.tribute.hideMenu(); |
---|
2925 | + }, 0); |
---|
2926 | + } |
---|
2927 | + }, |
---|
2928 | + escape: function escape(e, el) { |
---|
2929 | + if (_this.tribute.isActive) { |
---|
2930 | + e.preventDefault(); |
---|
2931 | + e.stopPropagation(); |
---|
2932 | + _this.tribute.isActive = false; |
---|
2933 | + _this.tribute.hideMenu(); |
---|
2934 | + } |
---|
2935 | + }, |
---|
2936 | + tab: function tab(e, el) { |
---|
2937 | + // choose first match |
---|
2938 | + _this.callbacks().enter(e, el); |
---|
2939 | + }, |
---|
2940 | + space: function space(e, el) { |
---|
2941 | + if (_this.tribute.isActive) { |
---|
2942 | + if (_this.tribute.spaceSelectsMatch) { |
---|
2943 | + _this.callbacks().enter(e, el); |
---|
2944 | + } else if (!_this.tribute.allowSpaces) { |
---|
2945 | + e.stopPropagation(); |
---|
2946 | + setTimeout(function () { |
---|
2947 | + _this.tribute.hideMenu(); |
---|
2948 | + _this.tribute.isActive = false; |
---|
2949 | + }, 0); |
---|
2950 | + } |
---|
2951 | + } |
---|
2952 | + }, |
---|
2953 | + up: function up(e, el) { |
---|
2954 | + // navigate up ul |
---|
2955 | + if (_this.tribute.isActive) { |
---|
2956 | + e.preventDefault(); |
---|
2957 | + e.stopPropagation(); |
---|
2958 | + var count = _this.tribute.current.filteredItems.length, |
---|
2959 | + selected = _this.tribute.menuSelected; |
---|
2960 | + |
---|
2961 | + if (count > selected && selected > 0) { |
---|
2962 | + _this.tribute.menuSelected--; |
---|
2963 | + _this.setActiveLi(); |
---|
2964 | + } else if (selected === 0) { |
---|
2965 | + _this.tribute.menuSelected = count - 1; |
---|
2966 | + _this.setActiveLi(); |
---|
2967 | + _this.tribute.menu.scrollTop = _this.tribute.menu.scrollHeight; |
---|
2968 | + } |
---|
2969 | + } |
---|
2970 | + }, |
---|
2971 | + down: function down(e, el) { |
---|
2972 | + // navigate down ul |
---|
2973 | + if (_this.tribute.isActive) { |
---|
2974 | + e.preventDefault(); |
---|
2975 | + e.stopPropagation(); |
---|
2976 | + var count = _this.tribute.current.filteredItems.length - 1, |
---|
2977 | + selected = _this.tribute.menuSelected; |
---|
2978 | + |
---|
2979 | + if (count > selected) { |
---|
2980 | + _this.tribute.menuSelected++; |
---|
2981 | + _this.setActiveLi(); |
---|
2982 | + } else if (count === selected) { |
---|
2983 | + _this.tribute.menuSelected = 0; |
---|
2984 | + _this.setActiveLi(); |
---|
2985 | + _this.tribute.menu.scrollTop = 0; |
---|
2986 | + } |
---|
2987 | + } |
---|
2988 | + }, |
---|
2989 | + delete: function _delete(e, el) { |
---|
2990 | + if (_this.tribute.isActive && _this.tribute.current.mentionText.length < 1) { |
---|
2991 | + _this.tribute.hideMenu(); |
---|
2992 | + } else if (_this.tribute.isActive) { |
---|
2993 | + _this.tribute.showMenuFor(el); |
---|
2994 | + } |
---|
2995 | + } |
---|
2996 | + }; |
---|
2997 | + } |
---|
2998 | + }, { |
---|
2999 | + key: 'setActiveLi', |
---|
3000 | + value: function setActiveLi(index) { |
---|
3001 | + var lis = this.tribute.menu.querySelectorAll('li'), |
---|
3002 | + length = lis.length >>> 0; |
---|
3003 | + |
---|
3004 | + // get heights |
---|
3005 | + var menuFullHeight = this.getFullHeight(this.tribute.menu), |
---|
3006 | + liHeight = this.getFullHeight(lis[0]); |
---|
3007 | + |
---|
3008 | + if (index) this.tribute.menuSelected = index; |
---|
3009 | + |
---|
3010 | + for (var i = 0; i < length; i++) { |
---|
3011 | + var li = lis[i]; |
---|
3012 | + if (i === this.tribute.menuSelected) { |
---|
3013 | + var offset = liHeight * (i + 1); |
---|
3014 | + var scrollTop = this.tribute.menu.scrollTop; |
---|
3015 | + var totalScroll = scrollTop + menuFullHeight; |
---|
3016 | + |
---|
3017 | + if (offset > totalScroll) { |
---|
3018 | + this.tribute.menu.scrollTop += liHeight; |
---|
3019 | + } else if (offset < totalScroll) { |
---|
3020 | + this.tribute.menu.scrollTop -= liHeight; |
---|
3021 | + } |
---|
3022 | + |
---|
3023 | + li.className = this.tribute.current.collection.selectClass; |
---|
3024 | + } else { |
---|
3025 | + li.className = ''; |
---|
3026 | + } |
---|
3027 | + } |
---|
3028 | + } |
---|
3029 | + }, { |
---|
3030 | + key: 'getFullHeight', |
---|
3031 | + value: function getFullHeight(elem, includeMargin) { |
---|
3032 | + var height = elem.getBoundingClientRect().height; |
---|
3033 | + |
---|
3034 | + if (includeMargin) { |
---|
3035 | + var style = elem.currentStyle || window.getComputedStyle(elem); |
---|
3036 | + return height + parseFloat(style.marginTop) + parseFloat(style.marginBottom); |
---|
3037 | + } |
---|
3038 | + |
---|
3039 | + return height; |
---|
3040 | + } |
---|
3041 | + }], [{ |
---|
3042 | + key: 'keys', |
---|
3043 | + value: function keys() { |
---|
3044 | + return [{ |
---|
3045 | + key: 9, |
---|
3046 | + value: 'TAB' |
---|
3047 | + }, { |
---|
3048 | + key: 8, |
---|
3049 | + value: 'DELETE' |
---|
3050 | + }, { |
---|
3051 | + key: 13, |
---|
3052 | + value: 'ENTER' |
---|
3053 | + }, { |
---|
3054 | + key: 27, |
---|
3055 | + value: 'ESCAPE' |
---|
3056 | + }, { |
---|
3057 | + key: 32, |
---|
3058 | + value: 'SPACE' |
---|
3059 | + }, { |
---|
3060 | + key: 38, |
---|
3061 | + value: 'UP' |
---|
3062 | + }, { |
---|
3063 | + key: 40, |
---|
3064 | + value: 'DOWN' |
---|
3065 | + }]; |
---|
3066 | + } |
---|
3067 | + }]); |
---|
3068 | + |
---|
3069 | + return TributeEvents; |
---|
3070 | +}(); |
---|
3071 | + |
---|
3072 | +exports.default = TributeEvents; |
---|
3073 | +module.exports = exports['default']; |
---|
3074 | + |
---|
3075 | +},{}],3:[function(require,module,exports){ |
---|
3076 | +'use strict'; |
---|
3077 | + |
---|
3078 | +Object.defineProperty(exports, "__esModule", { |
---|
3079 | + value: true |
---|
3080 | +}); |
---|
3081 | + |
---|
3082 | +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); |
---|
3083 | + |
---|
3084 | +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } |
---|
3085 | + |
---|
3086 | +var TributeMenuEvents = function () { |
---|
3087 | + function TributeMenuEvents(tribute) { |
---|
3088 | + _classCallCheck(this, TributeMenuEvents); |
---|
3089 | + |
---|
3090 | + this.tribute = tribute; |
---|
3091 | + this.tribute.menuEvents = this; |
---|
3092 | + this.menu = this.tribute.menu; |
---|
3093 | + } |
---|
3094 | + |
---|
3095 | + _createClass(TributeMenuEvents, [{ |
---|
3096 | + key: 'bind', |
---|
3097 | + value: function bind(menu) { |
---|
3098 | + var _this = this; |
---|
3099 | + |
---|
3100 | + menu.menuKeydownEvent = this.tribute.events.keydown.bind(this.menu, this); |
---|
3101 | + this.menuClickEvent = this.tribute.events.click.bind(null, this); |
---|
3102 | + this.menuContainerScrollEvent = this.debounce(function () { |
---|
3103 | + if (_this.tribute.isActive) { |
---|
3104 | + _this.tribute.showMenuFor(_this.tribute.current.element, false); |
---|
3105 | + } |
---|
3106 | + }, 300, false); |
---|
3107 | + this.windowResizeEvent = this.debounce(function () { |
---|
3108 | + if (_this.tribute.isActive) { |
---|
3109 | + _this.tribute.range.positionMenuAtCaret(true); |
---|
3110 | + } |
---|
3111 | + }, 300, false); |
---|
3112 | + |
---|
3113 | + // fixes IE11 issues with mouseup |
---|
3114 | + this.tribute.range.getDocument().addEventListener('MSPointerUp', this.menuClickEvent, false); |
---|
3115 | + menu.addEventListener('keydown', this.menuKeydownEvent, false); |
---|
3116 | + this.tribute.range.getDocument().addEventListener('mouseup', this.menuClickEvent, false); |
---|
3117 | + window.addEventListener('resize', this.windowResizeEvent); |
---|
3118 | + |
---|
3119 | + if (this.menuContainer) { |
---|
3120 | + this.menuContainer.addEventListener('scroll', this.menuContainerScrollEvent, false); |
---|
3121 | + } else { |
---|
3122 | + window.addEventListener('scroll', this.menuContainerScrollEvent); |
---|
3123 | + } |
---|
3124 | + } |
---|
3125 | + }, { |
---|
3126 | + key: 'unbind', |
---|
3127 | + value: function unbind(menu) { |
---|
3128 | + menu.removeEventListener('keydown', menu.menuKeydownEvent, false); |
---|
3129 | + delete menu.menuKeydownEvent; |
---|
3130 | + this.tribute.range.getDocument().removeEventListener('mouseup', this.menuClickEvent, false); |
---|
3131 | + this.tribute.range.getDocument().removeEventListener('MSPointerUp', this.menuClickEvent, false); |
---|
3132 | + window.removeEventListener('resize', this.windowResizeEvent); |
---|
3133 | + |
---|
3134 | + if (this.menuContainer) { |
---|
3135 | + this.menuContainer.removeEventListener('scroll', this.menuContainerScrollEvent, false); |
---|
3136 | + } else { |
---|
3137 | + window.removeEventListener('scroll', this.menuContainerScrollEvent); |
---|
3138 | + } |
---|
3139 | + } |
---|
3140 | + }, { |
---|
3141 | + key: 'debounce', |
---|
3142 | + value: function debounce(func, wait, immediate) { |
---|
3143 | + var _this2 = this, |
---|
3144 | + _arguments = arguments; |
---|
3145 | + |
---|
3146 | + var timeout; |
---|
3147 | + return function () { |
---|
3148 | + var context = _this2, |
---|
3149 | + args = _arguments; |
---|
3150 | + var later = function later() { |
---|
3151 | + timeout = null; |
---|
3152 | + if (!immediate) func.apply(context, args); |
---|
3153 | + }; |
---|
3154 | + var callNow = immediate && !timeout; |
---|
3155 | + clearTimeout(timeout); |
---|
3156 | + timeout = setTimeout(later, wait); |
---|
3157 | + if (callNow) func.apply(context, args); |
---|
3158 | + }; |
---|
3159 | + } |
---|
3160 | + }]); |
---|
3161 | + |
---|
3162 | + return TributeMenuEvents; |
---|
3163 | +}(); |
---|
3164 | + |
---|
3165 | +exports.default = TributeMenuEvents; |
---|
3166 | +module.exports = exports['default']; |
---|
3167 | + |
---|
3168 | +},{}],4:[function(require,module,exports){ |
---|
3169 | +'use strict'; |
---|
3170 | + |
---|
3171 | +Object.defineProperty(exports, "__esModule", { |
---|
3172 | + value: true |
---|
3173 | +}); |
---|
3174 | + |
---|
3175 | +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); |
---|
3176 | + |
---|
3177 | +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } |
---|
3178 | + |
---|
3179 | +// Thanks to https://github.com/jeff-collins/ment.io |
---|
3180 | +var TributeRange = function () { |
---|
3181 | + function TributeRange(tribute) { |
---|
3182 | + _classCallCheck(this, TributeRange); |
---|
3183 | + |
---|
3184 | + this.tribute = tribute; |
---|
3185 | + this.tribute.range = this; |
---|
3186 | + } |
---|
3187 | + |
---|
3188 | + _createClass(TributeRange, [{ |
---|
3189 | + key: 'getDocument', |
---|
3190 | + value: function getDocument() { |
---|
3191 | + var iframe = void 0; |
---|
3192 | + if (this.tribute.current.collection) { |
---|
3193 | + iframe = this.tribute.current.collection.iframe; |
---|
3194 | + } |
---|
3195 | + |
---|
3196 | + if (!iframe) { |
---|
3197 | + return document; |
---|
3198 | + } |
---|
3199 | + |
---|
3200 | + return iframe.contentWindow.document; |
---|
3201 | + } |
---|
3202 | + }, { |
---|
3203 | + key: 'positionMenuAtCaret', |
---|
3204 | + value: function positionMenuAtCaret(scrollTo) { |
---|
3205 | + var _this = this; |
---|
3206 | + |
---|
3207 | + var context = this.tribute.current, |
---|
3208 | + coordinates = void 0; |
---|
3209 | + |
---|
3210 | + var info = this.getTriggerInfo(false, this.tribute.hasTrailingSpace, true, this.tribute.allowSpaces); |
---|
3211 | + |
---|
3212 | + if (typeof info !== 'undefined') { |
---|
3213 | + |
---|
3214 | + if (!this.tribute.positionMenu) { |
---|
3215 | + this.tribute.menu.style.cssText = 'display: block;'; |
---|
3216 | + return; |
---|
3217 | + } |
---|
3218 | + |
---|
3219 | + if (!this.isContentEditable(context.element)) { |
---|
3220 | + coordinates = this.getTextAreaOrInputUnderlinePosition(this.tribute.current.element, info.mentionPosition); |
---|
3221 | + } else { |
---|
3222 | + coordinates = this.getContentEditableCaretPosition(info.mentionPosition); |
---|
3223 | + } |
---|
3224 | + |
---|
3225 | + this.tribute.menu.style.cssText = 'top: ' + coordinates.top + 'px;\n left: ' + coordinates.left + 'px;\n right: ' + coordinates.right + 'px;\n bottom: ' + coordinates.bottom + 'px;\n position: absolute;\n zIndex: 10000;\n display: block;'; |
---|
3226 | + |
---|
3227 | + if (coordinates.left === 'auto') { |
---|
3228 | + this.tribute.menu.style.left = 'auto'; |
---|
3229 | + } |
---|
3230 | + |
---|
3231 | + if (coordinates.top === 'auto') { |
---|
3232 | + this.tribute.menu.style.top = 'auto'; |
---|
3233 | + } |
---|
3234 | + |
---|
3235 | + if (scrollTo) this.scrollIntoView(); |
---|
3236 | + |
---|
3237 | + window.setTimeout(function () { |
---|
3238 | + var menuDimensions = { |
---|
3239 | + width: _this.tribute.menu.offsetWidth, |
---|
3240 | + height: _this.tribute.menu.offsetHeight |
---|
3241 | + }; |
---|
3242 | + var menuIsOffScreen = _this.isMenuOffScreen(coordinates, menuDimensions); |
---|
3243 | + |
---|
3244 | + var menuIsOffScreenHorizontally = window.innerWidth > menuDimensions.width && (menuIsOffScreen.left || menuIsOffScreen.right); |
---|
3245 | + var menuIsOffScreenVertically = window.innerHeight > menuDimensions.height && (menuIsOffScreen.top || menuIsOffScreen.bottom); |
---|
3246 | + if (menuIsOffScreenHorizontally || menuIsOffScreenVertically) { |
---|
3247 | + _this.tribute.menu.style.cssText = 'display: none'; |
---|
3248 | + _this.positionMenuAtCaret(scrollTo); |
---|
3249 | + } |
---|
3250 | + }, 0); |
---|
3251 | + } else { |
---|
3252 | + this.tribute.menu.style.cssText = 'display: none'; |
---|
3253 | + } |
---|
3254 | + } |
---|
3255 | + }, { |
---|
3256 | + key: 'selectElement', |
---|
3257 | + value: function selectElement(targetElement, path, offset) { |
---|
3258 | + var range = void 0; |
---|
3259 | + var elem = targetElement; |
---|
3260 | + |
---|
3261 | + if (path) { |
---|
3262 | + for (var i = 0; i < path.length; i++) { |
---|
3263 | + elem = elem.childNodes[path[i]]; |
---|
3264 | + if (elem === undefined) { |
---|
3265 | + return; |
---|
3266 | + } |
---|
3267 | + while (elem.length < offset) { |
---|
3268 | + offset -= elem.length; |
---|
3269 | + elem = elem.nextSibling; |
---|
3270 | + } |
---|
3271 | + if (elem.childNodes.length === 0 && !elem.length) { |
---|
3272 | + elem = elem.previousSibling; |
---|
3273 | + } |
---|
3274 | + } |
---|
3275 | + } |
---|
3276 | + var sel = this.getWindowSelection(); |
---|
3277 | + |
---|
3278 | + range = this.getDocument().createRange(); |
---|
3279 | + range.setStart(elem, offset); |
---|
3280 | + range.setEnd(elem, offset); |
---|
3281 | + range.collapse(true); |
---|
3282 | + |
---|
3283 | + try { |
---|
3284 | + sel.removeAllRanges(); |
---|
3285 | + } catch (error) {} |
---|
3286 | + |
---|
3287 | + sel.addRange(range); |
---|
3288 | + targetElement.focus(); |
---|
3289 | + } |
---|
3290 | + }, { |
---|
3291 | + key: 'resetSelection', |
---|
3292 | + value: function resetSelection(targetElement, path, offset) { |
---|
3293 | + if (!this.isContentEditable(targetElement)) { |
---|
3294 | + if (targetElement !== this.tribute.current.element) { |
---|
3295 | + targetElement.focus(); |
---|
3296 | + } |
---|
3297 | + } else { |
---|
3298 | + this.selectElement(targetElement, path, offset); |
---|
3299 | + } |
---|
3300 | + } |
---|
3301 | + }, { |
---|
3302 | + key: 'replaceTriggerText', |
---|
3303 | + value: function replaceTriggerText(text, requireLeadingSpace, hasTrailingSpace, originalEvent, item) { |
---|
3304 | + var context = this.tribute.current; |
---|
3305 | + this.resetSelection(context.element, context.selectedPath, context.selectedOffset); |
---|
3306 | + |
---|
3307 | + var info = this.getTriggerInfo(true, hasTrailingSpace, requireLeadingSpace, this.tribute.allowSpaces); |
---|
3308 | + |
---|
3309 | + // Create the event |
---|
3310 | + var replaceEvent = new CustomEvent('tribute-replaced', { |
---|
3311 | + detail: { |
---|
3312 | + item: item, |
---|
3313 | + event: originalEvent |
---|
3314 | + } |
---|
3315 | + }); |
---|
3316 | + |
---|
3317 | + if (info !== undefined) { |
---|
3318 | + if (!this.isContentEditable(context.element)) { |
---|
3319 | + var myField = this.tribute.current.element; |
---|
3320 | + var textSuffix = typeof this.tribute.replaceTextSuffix == 'string' ? this.tribute.replaceTextSuffix : ' '; |
---|
3321 | + text += textSuffix; |
---|
3322 | + var startPos = info.mentionPosition; |
---|
3323 | + var endPos = info.mentionPosition + info.mentionText.length + textSuffix.length; |
---|
3324 | + myField.value = myField.value.substring(0, startPos) + text + myField.value.substring(endPos, myField.value.length); |
---|
3325 | + myField.selectionStart = startPos + text.length; |
---|
3326 | + myField.selectionEnd = startPos + text.length; |
---|
3327 | + } else { |
---|
3328 | + // add a space to the end of the pasted text |
---|
3329 | + var _textSuffix = typeof this.tribute.replaceTextSuffix == 'string' ? this.tribute.replaceTextSuffix : '\xA0'; |
---|
3330 | + text += _textSuffix; |
---|
3331 | + this.pasteHtml(text, info.mentionPosition, info.mentionPosition + info.mentionText.length + 1); |
---|
3332 | + } |
---|
3333 | + |
---|
3334 | + context.element.dispatchEvent(replaceEvent); |
---|
3335 | + } |
---|
3336 | + } |
---|
3337 | + }, { |
---|
3338 | + key: 'pasteHtml', |
---|
3339 | + value: function pasteHtml(html, startPos, endPos) { |
---|
3340 | + var range = void 0, |
---|
3341 | + sel = void 0; |
---|
3342 | + sel = this.getWindowSelection(); |
---|
3343 | + range = this.getDocument().createRange(); |
---|
3344 | + range.setStart(sel.anchorNode, startPos); |
---|
3345 | + range.setEnd(sel.anchorNode, endPos); |
---|
3346 | + range.deleteContents(); |
---|
3347 | + |
---|
3348 | + var el = this.getDocument().createElement('div'); |
---|
3349 | + el.innerHTML = html; |
---|
3350 | + var frag = this.getDocument().createDocumentFragment(), |
---|
3351 | + node = void 0, |
---|
3352 | + lastNode = void 0; |
---|
3353 | + while (node = el.firstChild) { |
---|
3354 | + lastNode = frag.appendChild(node); |
---|
3355 | + } |
---|
3356 | + range.insertNode(frag); |
---|
3357 | + |
---|
3358 | + // Preserve the selection |
---|
3359 | + if (lastNode) { |
---|
3360 | + range = range.cloneRange(); |
---|
3361 | + range.setStartAfter(lastNode); |
---|
3362 | + range.collapse(true); |
---|
3363 | + sel.removeAllRanges(); |
---|
3364 | + sel.addRange(range); |
---|
3365 | + } |
---|
3366 | + } |
---|
3367 | + }, { |
---|
3368 | + key: 'getWindowSelection', |
---|
3369 | + value: function getWindowSelection() { |
---|
3370 | + if (this.tribute.collection.iframe) { |
---|
3371 | + return this.tribute.collection.iframe.contentWindow.getSelection(); |
---|
3372 | + } |
---|
3373 | + |
---|
3374 | + return window.getSelection(); |
---|
3375 | + } |
---|
3376 | + }, { |
---|
3377 | + key: 'getNodePositionInParent', |
---|
3378 | + value: function getNodePositionInParent(element) { |
---|
3379 | + if (element.parentNode === null) { |
---|
3380 | + return 0; |
---|
3381 | + } |
---|
3382 | + |
---|
3383 | + for (var i = 0; i < element.parentNode.childNodes.length; i++) { |
---|
3384 | + var node = element.parentNode.childNodes[i]; |
---|
3385 | + |
---|
3386 | + if (node === element) { |
---|
3387 | + return i; |
---|
3388 | + } |
---|
3389 | + } |
---|
3390 | + } |
---|
3391 | + }, { |
---|
3392 | + key: 'getContentEditableSelectedPath', |
---|
3393 | + value: function getContentEditableSelectedPath(ctx) { |
---|
3394 | + var sel = this.getWindowSelection(); |
---|
3395 | + var selected = sel.anchorNode; |
---|
3396 | + var path = []; |
---|
3397 | + var offset = void 0; |
---|
3398 | + |
---|
3399 | + if (selected != null) { |
---|
3400 | + var i = void 0; |
---|
3401 | + var ce = selected.contentEditable; |
---|
3402 | + while (selected !== null && ce !== 'true') { |
---|
3403 | + i = this.getNodePositionInParent(selected); |
---|
3404 | + path.push(i); |
---|
3405 | + selected = selected.parentNode; |
---|
3406 | + if (selected !== null) { |
---|
3407 | + ce = selected.contentEditable; |
---|
3408 | + } |
---|
3409 | + } |
---|
3410 | + path.reverse(); |
---|
3411 | + |
---|
3412 | + // getRangeAt may not exist, need alternative |
---|
3413 | + offset = sel.getRangeAt(0).startOffset; |
---|
3414 | + |
---|
3415 | + return { |
---|
3416 | + selected: selected, |
---|
3417 | + path: path, |
---|
3418 | + offset: offset |
---|
3419 | + }; |
---|
3420 | + } |
---|
3421 | + } |
---|
3422 | + }, { |
---|
3423 | + key: 'getTextPrecedingCurrentSelection', |
---|
3424 | + value: function getTextPrecedingCurrentSelection() { |
---|
3425 | + var context = this.tribute.current, |
---|
3426 | + text = ''; |
---|
3427 | + |
---|
3428 | + if (!this.isContentEditable(context.element)) { |
---|
3429 | + var textComponent = this.tribute.current.element; |
---|
3430 | + if (textComponent) { |
---|
3431 | + var startPos = textComponent.selectionStart; |
---|
3432 | + if (textComponent.value && startPos >= 0) { |
---|
3433 | + text = textComponent.value.substring(0, startPos); |
---|
3434 | + } |
---|
3435 | + } |
---|
3436 | + } else { |
---|
3437 | + var selectedElem = this.getWindowSelection().anchorNode; |
---|
3438 | + |
---|
3439 | + if (selectedElem != null) { |
---|
3440 | + var workingNodeContent = selectedElem.textContent; |
---|
3441 | + var selectStartOffset = this.getWindowSelection().getRangeAt(0).startOffset; |
---|
3442 | + |
---|
3443 | + if (workingNodeContent && selectStartOffset >= 0) { |
---|
3444 | + text = workingNodeContent.substring(0, selectStartOffset); |
---|
3445 | + } |
---|
3446 | + } |
---|
3447 | + } |
---|
3448 | + |
---|
3449 | + return text; |
---|
3450 | + } |
---|
3451 | + }, { |
---|
3452 | + key: 'getTriggerInfo', |
---|
3453 | + value: function getTriggerInfo(menuAlreadyActive, hasTrailingSpace, requireLeadingSpace, allowSpaces) { |
---|
3454 | + var _this2 = this; |
---|
3455 | + |
---|
3456 | + var ctx = this.tribute.current; |
---|
3457 | + var selected = void 0, |
---|
3458 | + path = void 0, |
---|
3459 | + offset = void 0; |
---|
3460 | + |
---|
3461 | + if (!this.isContentEditable(ctx.element)) { |
---|
3462 | + selected = this.tribute.current.element; |
---|
3463 | + } else { |
---|
3464 | + var selectionInfo = this.getContentEditableSelectedPath(ctx); |
---|
3465 | + |
---|
3466 | + if (selectionInfo) { |
---|
3467 | + selected = selectionInfo.selected; |
---|
3468 | + path = selectionInfo.path; |
---|
3469 | + offset = selectionInfo.offset; |
---|
3470 | + } |
---|
3471 | + } |
---|
3472 | + |
---|
3473 | + var effectiveRange = this.getTextPrecedingCurrentSelection(); |
---|
3474 | + |
---|
3475 | + if (effectiveRange !== undefined && effectiveRange !== null) { |
---|
3476 | + var mostRecentTriggerCharPos = -1; |
---|
3477 | + var triggerChar = void 0; |
---|
3478 | + |
---|
3479 | + this.tribute.collection.forEach(function (config) { |
---|
3480 | + var c = config.trigger; |
---|
3481 | + var idx = config.requireLeadingSpace ? _this2.lastIndexWithLeadingSpace(effectiveRange, c) : effectiveRange.lastIndexOf(c); |
---|
3482 | + |
---|
3483 | + if (idx > mostRecentTriggerCharPos) { |
---|
3484 | + mostRecentTriggerCharPos = idx; |
---|
3485 | + triggerChar = c; |
---|
3486 | + requireLeadingSpace = config.requireLeadingSpace; |
---|
3487 | + } |
---|
3488 | + }); |
---|
3489 | + |
---|
3490 | + if (mostRecentTriggerCharPos >= 0 && (mostRecentTriggerCharPos === 0 || !requireLeadingSpace || /[\xA0\s]/g.test(effectiveRange.substring(mostRecentTriggerCharPos - 1, mostRecentTriggerCharPos)))) { |
---|
3491 | + var currentTriggerSnippet = effectiveRange.substring(mostRecentTriggerCharPos + 1, effectiveRange.length); |
---|
3492 | + |
---|
3493 | + triggerChar = effectiveRange.substring(mostRecentTriggerCharPos, mostRecentTriggerCharPos + 1); |
---|
3494 | + var firstSnippetChar = currentTriggerSnippet.substring(0, 1); |
---|
3495 | + var leadingSpace = currentTriggerSnippet.length > 0 && (firstSnippetChar === ' ' || firstSnippetChar === '\xA0'); |
---|
3496 | + if (hasTrailingSpace) { |
---|
3497 | + currentTriggerSnippet = currentTriggerSnippet.trim(); |
---|
3498 | + } |
---|
3499 | + |
---|
3500 | + var regex = allowSpaces ? /[^\S ]/g : /[\xA0\s]/g; |
---|
3501 | + |
---|
3502 | + this.tribute.hasTrailingSpace = regex.test(currentTriggerSnippet); |
---|
3503 | + |
---|
3504 | + if (!leadingSpace && (menuAlreadyActive || !regex.test(currentTriggerSnippet))) { |
---|
3505 | + return { |
---|
3506 | + mentionPosition: mostRecentTriggerCharPos, |
---|
3507 | + mentionText: currentTriggerSnippet, |
---|
3508 | + mentionSelectedElement: selected, |
---|
3509 | + mentionSelectedPath: path, |
---|
3510 | + mentionSelectedOffset: offset, |
---|
3511 | + mentionTriggerChar: triggerChar |
---|
3512 | + }; |
---|
3513 | + } |
---|
3514 | + } |
---|
3515 | + } |
---|
3516 | + } |
---|
3517 | + }, { |
---|
3518 | + key: 'lastIndexWithLeadingSpace', |
---|
3519 | + value: function lastIndexWithLeadingSpace(str, char) { |
---|
3520 | + var reversedStr = str.split('').reverse().join(''); |
---|
3521 | + var index = -1; |
---|
3522 | + |
---|
3523 | + for (var cidx = 0, len = str.length; cidx < len; cidx++) { |
---|
3524 | + var firstChar = cidx === str.length - 1; |
---|
3525 | + var leadingSpace = /\s/.test(reversedStr[cidx + 1]); |
---|
3526 | + var match = char === reversedStr[cidx]; |
---|
3527 | + |
---|
3528 | + if (match && (firstChar || leadingSpace)) { |
---|
3529 | + index = str.length - 1 - cidx; |
---|
3530 | + break; |
---|
3531 | + } |
---|
3532 | + } |
---|
3533 | + |
---|
3534 | + return index; |
---|
3535 | + } |
---|
3536 | + }, { |
---|
3537 | + key: 'isContentEditable', |
---|
3538 | + value: function isContentEditable(element) { |
---|
3539 | + return element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA'; |
---|
3540 | + } |
---|
3541 | + }, { |
---|
3542 | + key: 'isMenuOffScreen', |
---|
3543 | + value: function isMenuOffScreen(coordinates, menuDimensions) { |
---|
3544 | + var windowWidth = window.innerWidth; |
---|
3545 | + var windowHeight = window.innerHeight; |
---|
3546 | + var doc = document.documentElement; |
---|
3547 | + var windowLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0); |
---|
3548 | + var windowTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0); |
---|
3549 | + |
---|
3550 | + var menuTop = typeof coordinates.top === 'number' ? coordinates.top : windowTop + windowHeight - coordinates.bottom - menuDimensions.height; |
---|
3551 | + var menuRight = typeof coordinates.right === 'number' ? coordinates.right : coordinates.left + menuDimensions.width; |
---|
3552 | + var menuBottom = typeof coordinates.bottom === 'number' ? coordinates.bottom : coordinates.top + menuDimensions.height; |
---|
3553 | + var menuLeft = typeof coordinates.left === 'number' ? coordinates.left : windowLeft + windowWidth - coordinates.right - menuDimensions.width; |
---|
3554 | + |
---|
3555 | + return { |
---|
3556 | + top: menuTop < Math.floor(windowTop), |
---|
3557 | + right: menuRight > Math.ceil(windowLeft + windowWidth), |
---|
3558 | + bottom: menuBottom > Math.ceil(windowTop + windowHeight), |
---|
3559 | + left: menuLeft < Math.floor(windowLeft) |
---|
3560 | + }; |
---|
3561 | + } |
---|
3562 | + }, { |
---|
3563 | + key: 'getMenuDimensions', |
---|
3564 | + value: function getMenuDimensions() { |
---|
3565 | + // Width of the menu depends of its contents and position |
---|
3566 | + // We must check what its width would be without any obstruction |
---|
3567 | + // This way, we can achieve good positioning for flipping the menu |
---|
3568 | + var dimensions = { |
---|
3569 | + width: null, |
---|
3570 | + height: null |
---|
3571 | + }; |
---|
3572 | + |
---|
3573 | + this.tribute.menu.style.cssText = 'top: 0px;\n left: 0px;\n position: fixed;\n zIndex: 10000;\n display: block;\n visibility; hidden;'; |
---|
3574 | + dimensions.width = this.tribute.menu.offsetWidth; |
---|
3575 | + dimensions.height = this.tribute.menu.offsetHeight; |
---|
3576 | + |
---|
3577 | + this.tribute.menu.style.cssText = 'display: none;'; |
---|
3578 | + |
---|
3579 | + return dimensions; |
---|
3580 | + } |
---|
3581 | + }, { |
---|
3582 | + key: 'getTextAreaOrInputUnderlinePosition', |
---|
3583 | + value: function getTextAreaOrInputUnderlinePosition(element, position, flipped) { |
---|
3584 | + var properties = ['direction', 'boxSizing', 'width', 'height', 'overflowX', 'overflowY', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft', 'fontStyle', 'fontVariant', 'fontWeight', 'fontStretch', 'fontSize', 'fontSizeAdjust', 'lineHeight', 'fontFamily', 'textAlign', 'textTransform', 'textIndent', 'textDecoration', 'letterSpacing', 'wordSpacing']; |
---|
3585 | + |
---|
3586 | + var isFirefox = window.mozInnerScreenX !== null; |
---|
3587 | + |
---|
3588 | + var div = this.getDocument().createElement('div'); |
---|
3589 | + div.id = 'input-textarea-caret-position-mirror-div'; |
---|
3590 | + this.getDocument().body.appendChild(div); |
---|
3591 | + |
---|
3592 | + var style = div.style; |
---|
3593 | + var computed = window.getComputedStyle ? getComputedStyle(element) : element.currentStyle; |
---|
3594 | + |
---|
3595 | + style.whiteSpace = 'pre-wrap'; |
---|
3596 | + if (element.nodeName !== 'INPUT') { |
---|
3597 | + style.wordWrap = 'break-word'; |
---|
3598 | + } |
---|
3599 | + |
---|
3600 | + // position off-screen |
---|
3601 | + style.position = 'absolute'; |
---|
3602 | + style.visibility = 'hidden'; |
---|
3603 | + |
---|
3604 | + // transfer the element's properties to the div |
---|
3605 | + properties.forEach(function (prop) { |
---|
3606 | + style[prop] = computed[prop]; |
---|
3607 | + }); |
---|
3608 | + |
---|
3609 | + if (isFirefox) { |
---|
3610 | + style.width = parseInt(computed.width) - 2 + 'px'; |
---|
3611 | + if (element.scrollHeight > parseInt(computed.height)) style.overflowY = 'scroll'; |
---|
3612 | + } else { |
---|
3613 | + style.overflow = 'hidden'; |
---|
3614 | + } |
---|
3615 | + |
---|
3616 | + div.textContent = element.value.substring(0, position); |
---|
3617 | + |
---|
3618 | + if (element.nodeName === 'INPUT') { |
---|
3619 | + div.textContent = div.textContent.replace(/\s/g, 'Â '); |
---|
3620 | + } |
---|
3621 | + |
---|
3622 | + var span = this.getDocument().createElement('span'); |
---|
3623 | + span.textContent = element.value.substring(position) || '.'; |
---|
3624 | + div.appendChild(span); |
---|
3625 | + |
---|
3626 | + var rect = element.getBoundingClientRect(); |
---|
3627 | + var doc = document.documentElement; |
---|
3628 | + var windowLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0); |
---|
3629 | + var windowTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0); |
---|
3630 | + |
---|
3631 | + var coordinates = { |
---|
3632 | + top: rect.top + windowTop + span.offsetTop + parseInt(computed.borderTopWidth) + parseInt(computed.fontSize) - element.scrollTop, |
---|
3633 | + left: rect.left + windowLeft + span.offsetLeft + parseInt(computed.borderLeftWidth) |
---|
3634 | + }; |
---|
3635 | + |
---|
3636 | + var windowWidth = window.innerWidth; |
---|
3637 | + var windowHeight = window.innerHeight; |
---|
3638 | + |
---|
3639 | + var menuDimensions = this.getMenuDimensions(); |
---|
3640 | + var menuIsOffScreen = this.isMenuOffScreen(coordinates, menuDimensions); |
---|
3641 | + |
---|
3642 | + if (menuIsOffScreen.right) { |
---|
3643 | + coordinates.right = windowWidth - coordinates.left; |
---|
3644 | + coordinates.left = 'auto'; |
---|
3645 | + } |
---|
3646 | + |
---|
3647 | + var parentHeight = this.tribute.menuContainer ? this.tribute.menuContainer.offsetHeight : this.getDocument().body.offsetHeight; |
---|
3648 | + |
---|
3649 | + if (menuIsOffScreen.bottom) { |
---|
3650 | + var parentRect = this.tribute.menuContainer ? this.tribute.menuContainer.getBoundingClientRect() : this.getDocument().body.getBoundingClientRect(); |
---|
3651 | + var scrollStillAvailable = parentHeight - (windowHeight - parentRect.top); |
---|
3652 | + |
---|
3653 | + coordinates.bottom = scrollStillAvailable + (windowHeight - rect.top - span.offsetTop); |
---|
3654 | + coordinates.top = 'auto'; |
---|
3655 | + } |
---|
3656 | + |
---|
3657 | + menuIsOffScreen = this.isMenuOffScreen(coordinates, menuDimensions); |
---|
3658 | + if (menuIsOffScreen.left) { |
---|
3659 | + coordinates.left = windowWidth > menuDimensions.width ? windowLeft + windowWidth - menuDimensions.width : windowLeft; |
---|
3660 | + delete coordinates.right; |
---|
3661 | + } |
---|
3662 | + if (menuIsOffScreen.top) { |
---|
3663 | + coordinates.top = windowHeight > menuDimensions.height ? windowTop + windowHeight - menuDimensions.height : windowTop; |
---|
3664 | + delete coordinates.bottom; |
---|
3665 | + } |
---|
3666 | + |
---|
3667 | + this.getDocument().body.removeChild(div); |
---|
3668 | + return coordinates; |
---|
3669 | + } |
---|
3670 | + }, { |
---|
3671 | + key: 'getContentEditableCaretPosition', |
---|
3672 | + value: function getContentEditableCaretPosition(selectedNodePosition) { |
---|
3673 | + var markerTextChar = ''; |
---|
3674 | + var markerEl = void 0, |
---|
3675 | + markerId = 'sel_' + new Date().getTime() + '_' + Math.random().toString().substr(2); |
---|
3676 | + var range = void 0; |
---|
3677 | + var sel = this.getWindowSelection(); |
---|
3678 | + var prevRange = sel.getRangeAt(0); |
---|
3679 | + |
---|
3680 | + range = this.getDocument().createRange(); |
---|
3681 | + range.setStart(sel.anchorNode, selectedNodePosition); |
---|
3682 | + range.setEnd(sel.anchorNode, selectedNodePosition); |
---|
3683 | + |
---|
3684 | + range.collapse(false); |
---|
3685 | + |
---|
3686 | + // Create the marker element containing a single invisible character using DOM methods and insert it |
---|
3687 | + markerEl = this.getDocument().createElement('span'); |
---|
3688 | + markerEl.id = markerId; |
---|
3689 | + |
---|
3690 | + markerEl.appendChild(this.getDocument().createTextNode(markerTextChar)); |
---|
3691 | + range.insertNode(markerEl); |
---|
3692 | + sel.removeAllRanges(); |
---|
3693 | + sel.addRange(prevRange); |
---|
3694 | + |
---|
3695 | + var rect = markerEl.getBoundingClientRect(); |
---|
3696 | + var doc = document.documentElement; |
---|
3697 | + var windowLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0); |
---|
3698 | + var windowTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0); |
---|
3699 | + var coordinates = { |
---|
3700 | + left: rect.left + windowLeft, |
---|
3701 | + top: rect.top + markerEl.offsetHeight + windowTop |
---|
3702 | + }; |
---|
3703 | + var windowWidth = window.innerWidth; |
---|
3704 | + var windowHeight = window.innerHeight; |
---|
3705 | + |
---|
3706 | + var menuDimensions = this.getMenuDimensions(); |
---|
3707 | + var menuIsOffScreen = this.isMenuOffScreen(coordinates, menuDimensions); |
---|
3708 | + |
---|
3709 | + if (menuIsOffScreen.right) { |
---|
3710 | + coordinates.left = 'auto'; |
---|
3711 | + coordinates.right = windowWidth - rect.left - windowLeft; |
---|
3712 | + } |
---|
3713 | + |
---|
3714 | + var parentHeight = this.tribute.menuContainer ? this.tribute.menuContainer.offsetHeight : this.getDocument().body.offsetHeight; |
---|
3715 | + |
---|
3716 | + if (menuIsOffScreen.bottom) { |
---|
3717 | + var parentRect = this.tribute.menuContainer ? this.tribute.menuContainer.getBoundingClientRect() : this.getDocument().body.getBoundingClientRect(); |
---|
3718 | + var scrollStillAvailable = parentHeight - (windowHeight - parentRect.top); |
---|
3719 | + |
---|
3720 | + coordinates.top = 'auto'; |
---|
3721 | + coordinates.bottom = scrollStillAvailable + (windowHeight - rect.top); |
---|
3722 | + } |
---|
3723 | + |
---|
3724 | + menuIsOffScreen = this.isMenuOffScreen(coordinates, menuDimensions); |
---|
3725 | + if (menuIsOffScreen.left) { |
---|
3726 | + coordinates.left = windowWidth > menuDimensions.width ? windowLeft + windowWidth - menuDimensions.width : windowLeft; |
---|
3727 | + delete coordinates.right; |
---|
3728 | + } |
---|
3729 | + if (menuIsOffScreen.top) { |
---|
3730 | + coordinates.top = windowHeight > menuDimensions.height ? windowTop + windowHeight - menuDimensions.height : windowTop; |
---|
3731 | + delete coordinates.bottom; |
---|
3732 | + } |
---|
3733 | + |
---|
3734 | + markerEl.parentNode.removeChild(markerEl); |
---|
3735 | + return coordinates; |
---|
3736 | + } |
---|
3737 | + }, { |
---|
3738 | + key: 'scrollIntoView', |
---|
3739 | + value: function scrollIntoView(elem) { |
---|
3740 | + var reasonableBuffer = 20, |
---|
3741 | + clientRect = void 0; |
---|
3742 | + var maxScrollDisplacement = 100; |
---|
3743 | + var e = this.menu; |
---|
3744 | + |
---|
3745 | + if (typeof e === 'undefined') return; |
---|
3746 | + |
---|
3747 | + while (clientRect === undefined || clientRect.height === 0) { |
---|
3748 | + clientRect = e.getBoundingClientRect(); |
---|
3749 | + |
---|
3750 | + if (clientRect.height === 0) { |
---|
3751 | + e = e.childNodes[0]; |
---|
3752 | + if (e === undefined || !e.getBoundingClientRect) { |
---|
3753 | + return; |
---|
3754 | + } |
---|
3755 | + } |
---|
3756 | + } |
---|
3757 | + |
---|
3758 | + var elemTop = clientRect.top; |
---|
3759 | + var elemBottom = elemTop + clientRect.height; |
---|
3760 | + |
---|
3761 | + if (elemTop < 0) { |
---|
3762 | + window.scrollTo(0, window.pageYOffset + clientRect.top - reasonableBuffer); |
---|
3763 | + } else if (elemBottom > window.innerHeight) { |
---|
3764 | + var maxY = window.pageYOffset + clientRect.top - reasonableBuffer; |
---|
3765 | + |
---|
3766 | + if (maxY - window.pageYOffset > maxScrollDisplacement) { |
---|
3767 | + maxY = window.pageYOffset + maxScrollDisplacement; |
---|
3768 | + } |
---|
3769 | + |
---|
3770 | + var targetY = window.pageYOffset - (window.innerHeight - elemBottom); |
---|
3771 | + |
---|
3772 | + if (targetY > maxY) { |
---|
3773 | + targetY = maxY; |
---|
3774 | + } |
---|
3775 | + |
---|
3776 | + window.scrollTo(0, targetY); |
---|
3777 | + } |
---|
3778 | + } |
---|
3779 | + }]); |
---|
3780 | + |
---|
3781 | + return TributeRange; |
---|
3782 | +}(); |
---|
3783 | + |
---|
3784 | +exports.default = TributeRange; |
---|
3785 | +module.exports = exports['default']; |
---|
3786 | + |
---|
3787 | +},{}],5:[function(require,module,exports){ |
---|
3788 | +'use strict'; |
---|
3789 | + |
---|
3790 | +Object.defineProperty(exports, "__esModule", { |
---|
3791 | + value: true |
---|
3792 | +}); |
---|
3793 | + |
---|
3794 | +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); |
---|
3795 | + |
---|
3796 | +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } |
---|
3797 | + |
---|
3798 | +// Thanks to https://github.com/mattyork/fuzzy |
---|
3799 | +var TributeSearch = function () { |
---|
3800 | + function TributeSearch(tribute) { |
---|
3801 | + _classCallCheck(this, TributeSearch); |
---|
3802 | + |
---|
3803 | + this.tribute = tribute; |
---|
3804 | + this.tribute.search = this; |
---|
3805 | + } |
---|
3806 | + |
---|
3807 | + _createClass(TributeSearch, [{ |
---|
3808 | + key: 'simpleFilter', |
---|
3809 | + value: function simpleFilter(pattern, array) { |
---|
3810 | + var _this = this; |
---|
3811 | + |
---|
3812 | + return array.filter(function (string) { |
---|
3813 | + return _this.test(pattern, string); |
---|
3814 | + }); |
---|
3815 | + } |
---|
3816 | + }, { |
---|
3817 | + key: 'test', |
---|
3818 | + value: function test(pattern, string) { |
---|
3819 | + return this.match(pattern, string) !== null; |
---|
3820 | + } |
---|
3821 | + }, { |
---|
3822 | + key: 'match', |
---|
3823 | + value: function match(pattern, string, opts) { |
---|
3824 | + opts = opts || {}; |
---|
3825 | + var patternIdx = 0, |
---|
3826 | + result = [], |
---|
3827 | + len = string.length, |
---|
3828 | + totalScore = 0, |
---|
3829 | + currScore = 0, |
---|
3830 | + pre = opts.pre || '', |
---|
3831 | + post = opts.post || '', |
---|
3832 | + compareString = opts.caseSensitive && string || string.toLowerCase(), |
---|
3833 | + ch = void 0, |
---|
3834 | + compareChar = void 0; |
---|
3835 | + |
---|
3836 | + pattern = opts.caseSensitive && pattern || pattern.toLowerCase(); |
---|
3837 | + |
---|
3838 | + var patternCache = this.traverse(compareString, pattern, 0, 0, []); |
---|
3839 | + if (!patternCache) { |
---|
3840 | + return null; |
---|
3841 | + } |
---|
3842 | + |
---|
3843 | + return { |
---|
3844 | + rendered: this.render(string, patternCache.cache, pre, post), |
---|
3845 | + score: patternCache.score |
---|
3846 | + }; |
---|
3847 | + } |
---|
3848 | + }, { |
---|
3849 | + key: 'traverse', |
---|
3850 | + value: function traverse(string, pattern, stringIndex, patternIndex, patternCache) { |
---|
3851 | + // if the pattern search at end |
---|
3852 | + if (pattern.length === patternIndex) { |
---|
3853 | + |
---|
3854 | + // calculate score and copy the cache containing the indices where it's found |
---|
3855 | + return { |
---|
3856 | + score: this.calculateScore(patternCache), |
---|
3857 | + cache: patternCache.slice() |
---|
3858 | + }; |
---|
3859 | + } |
---|
3860 | + |
---|
3861 | + // if string at end or remaining pattern > remaining string |
---|
3862 | + if (string.length === stringIndex || pattern.length - patternIndex > string.length - stringIndex) { |
---|
3863 | + return undefined; |
---|
3864 | + } |
---|
3865 | + |
---|
3866 | + var c = pattern[patternIndex]; |
---|
3867 | + var index = string.indexOf(c, stringIndex); |
---|
3868 | + var best = void 0, |
---|
3869 | + temp = void 0; |
---|
3870 | + |
---|
3871 | + while (index > -1) { |
---|
3872 | + patternCache.push(index); |
---|
3873 | + temp = this.traverse(string, pattern, index + 1, patternIndex + 1, patternCache); |
---|
3874 | + patternCache.pop(); |
---|
3875 | + |
---|
3876 | + // if downstream traversal failed, return best answer so far |
---|
3877 | + if (!temp) { |
---|
3878 | + return best; |
---|
3879 | + } |
---|
3880 | + |
---|
3881 | + if (!best || best.score < temp.score) { |
---|
3882 | + best = temp; |
---|
3883 | + } |
---|
3884 | + |
---|
3885 | + index = string.indexOf(c, index + 1); |
---|
3886 | + } |
---|
3887 | + |
---|
3888 | + return best; |
---|
3889 | + } |
---|
3890 | + }, { |
---|
3891 | + key: 'calculateScore', |
---|
3892 | + value: function calculateScore(patternCache) { |
---|
3893 | + var score = 0; |
---|
3894 | + var temp = 1; |
---|
3895 | + |
---|
3896 | + patternCache.forEach(function (index, i) { |
---|
3897 | + if (i > 0) { |
---|
3898 | + if (patternCache[i - 1] + 1 === index) { |
---|
3899 | + temp += temp + 1; |
---|
3900 | + } else { |
---|
3901 | + temp = 1; |
---|
3902 | + } |
---|
3903 | + } |
---|
3904 | + |
---|
3905 | + score += temp; |
---|
3906 | + }); |
---|
3907 | + |
---|
3908 | + return score; |
---|
3909 | + } |
---|
3910 | + }, { |
---|
3911 | + key: 'render', |
---|
3912 | + value: function render(string, indices, pre, post) { |
---|
3913 | + var rendered = string.substring(0, indices[0]); |
---|
3914 | + |
---|
3915 | + indices.forEach(function (index, i) { |
---|
3916 | + rendered += pre + string[index] + post + string.substring(index + 1, indices[i + 1] ? indices[i + 1] : string.length); |
---|
3917 | + }); |
---|
3918 | + |
---|
3919 | + return rendered; |
---|
3920 | + } |
---|
3921 | + }, { |
---|
3922 | + key: 'filter', |
---|
3923 | + value: function filter(pattern, arr, opts) { |
---|
3924 | + var _this2 = this; |
---|
3925 | + |
---|
3926 | + opts = opts || {}; |
---|
3927 | + return arr.reduce(function (prev, element, idx, arr) { |
---|
3928 | + var str = element; |
---|
3929 | + |
---|
3930 | + if (opts.extract) { |
---|
3931 | + str = opts.extract(element); |
---|
3932 | + |
---|
3933 | + if (!str) { |
---|
3934 | + // take care of undefineds / nulls / etc. |
---|
3935 | + str = ''; |
---|
3936 | + } |
---|
3937 | + } |
---|
3938 | + |
---|
3939 | + var rendered = _this2.match(pattern, str, opts); |
---|
3940 | + |
---|
3941 | + if (rendered != null) { |
---|
3942 | + prev[prev.length] = { |
---|
3943 | + string: rendered.rendered, |
---|
3944 | + score: rendered.score, |
---|
3945 | + index: idx, |
---|
3946 | + original: element |
---|
3947 | + }; |
---|
3948 | + } |
---|
3949 | + |
---|
3950 | + return prev; |
---|
3951 | + }, []).sort(function (a, b) { |
---|
3952 | + var compare = b.score - a.score; |
---|
3953 | + if (compare) return compare; |
---|
3954 | + return a.index - b.index; |
---|
3955 | + }); |
---|
3956 | + } |
---|
3957 | + }]); |
---|
3958 | + |
---|
3959 | + return TributeSearch; |
---|
3960 | +}(); |
---|
3961 | + |
---|
3962 | +exports.default = TributeSearch; |
---|
3963 | +module.exports = exports['default']; |
---|
3964 | + |
---|
3965 | +},{}],6:[function(require,module,exports){ |
---|
3966 | +"use strict"; |
---|
3967 | + |
---|
3968 | +Object.defineProperty(exports, "__esModule", { |
---|
3969 | + value: true |
---|
3970 | +}); |
---|
3971 | + |
---|
3972 | +var _Tribute = require("./Tribute"); |
---|
3973 | + |
---|
3974 | +var _Tribute2 = _interopRequireDefault(_Tribute); |
---|
3975 | + |
---|
3976 | +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } |
---|
3977 | + |
---|
3978 | +exports.default = _Tribute2.default; /** |
---|
3979 | + * Tribute.js |
---|
3980 | + * Native ES6 JavaScript @mention Plugin |
---|
3981 | + **/ |
---|
3982 | + |
---|
3983 | +module.exports = exports["default"]; |
---|
3984 | + |
---|
3985 | +},{"./Tribute":1}],7:[function(require,module,exports){ |
---|
3986 | +'use strict'; |
---|
3987 | + |
---|
3988 | +if (!Array.prototype.find) { |
---|
3989 | + Array.prototype.find = function (predicate) { |
---|
3990 | + if (this === null) { |
---|
3991 | + throw new TypeError('Array.prototype.find called on null or undefined'); |
---|
3992 | + } |
---|
3993 | + if (typeof predicate !== 'function') { |
---|
3994 | + throw new TypeError('predicate must be a function'); |
---|
3995 | + } |
---|
3996 | + var list = Object(this); |
---|
3997 | + var length = list.length >>> 0; |
---|
3998 | + var thisArg = arguments[1]; |
---|
3999 | + var value; |
---|
4000 | + |
---|
4001 | + for (var i = 0; i < length; i++) { |
---|
4002 | + value = list[i]; |
---|
4003 | + if (predicate.call(thisArg, value, i, list)) { |
---|
4004 | + return value; |
---|
4005 | + } |
---|
4006 | + } |
---|
4007 | + return undefined; |
---|
4008 | + }; |
---|
4009 | +} |
---|
4010 | + |
---|
4011 | +if (window && typeof window.CustomEvent !== "function") { |
---|
4012 | + var CustomEvent = function CustomEvent(event, params) { |
---|
4013 | + params = params || { |
---|
4014 | + bubbles: false, |
---|
4015 | + cancelable: false, |
---|
4016 | + detail: undefined |
---|
4017 | + }; |
---|
4018 | + var evt = document.createEvent('CustomEvent'); |
---|
4019 | + evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); |
---|
4020 | + return evt; |
---|
4021 | + }; |
---|
4022 | + |
---|
4023 | + if (typeof window.Event !== 'undefined') { |
---|
4024 | + CustomEvent.prototype = window.Event.prototype; |
---|
4025 | + } |
---|
4026 | + |
---|
4027 | + window.CustomEvent = CustomEvent; |
---|
4028 | +} |
---|
4029 | + |
---|
4030 | +},{}]},{},[6])(6) |
---|
4031 | +}); |
---|
4032 | + |
---|
4033 | +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvVHJpYnV0ZS5qcyIsInNyYy9UcmlidXRlRXZlbnRzLmpzIiwic3JjL1RyaWJ1dGVNZW51RXZlbnRzLmpzIiwic3JjL1RyaWJ1dGVSYW5nZS5qcyIsInNyYy9UcmlidXRlU2VhcmNoLmpzIiwic3JjL2luZGV4LmpzIiwic3JjL3V0aWxzLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7QUNBQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7OztJQUVNLE87QUFDRiwyQkFpQkc7QUFBQTs7QUFBQSwrQkFoQkMsTUFnQkQ7QUFBQSxZQWhCQyxNQWdCRCwrQkFoQlUsSUFnQlY7QUFBQSwrQkFmQyxNQWVEO0FBQUEsWUFmQyxNQWVELCtCQWZVLElBZVY7QUFBQSxvQ0FkQyxXQWNEO0FBQUEsWUFkQyxXQWNELG9DQWRlLFdBY2Y7QUFBQSxnQ0FiQyxPQWFEO0FBQUEsWUFiQyxPQWFELGdDQWJXLEdBYVg7QUFBQSx1Q0FaQyxjQVlEO0FBQUEsWUFaQyxjQVlELHVDQVprQixJQVlsQjtBQUFBLHlDQVhDLGdCQVdEO0FBQUEsWUFYQyxnQkFXRCx5Q0FYb0IsSUFXcEI7QUFBQSwrQkFWQyxNQVVEO0FBQUEsWUFWQyxNQVVELCtCQVZVLEtBVVY7QUFBQSxpQ0FUQyxRQVNEO0FBQUEsWUFUQyxRQVNELGlDQVRZLE9BU1o7QUFBQSxtQ0FSQyxVQVFEO0FBQUEsWUFSQyxVQVFELG1DQVJjLElBUWQ7QUFBQSxzQ0FQQyxhQU9EO0FBQUEsWUFQQyxhQU9ELHNDQVBpQixJQU9qQjtBQUFBLHdDQU5DLGVBTUQ7QUFBQSxZQU5DLGVBTUQsd0NBTm1CLElBTW5CO0FBQUEseUNBTEMsbUJBS0Q7QUFBQSxZQUxDLG1CQUtELHlDQUx1QixJQUt2QjtBQUFBLG9DQUpDLFdBSUQ7QUFBQSxZQUpDLFdBSUQsb0NBSmUsS0FJZjtBQUFBLHlDQUhDLGlCQUdEO0FBQUEs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VSxPQUFPLE9BQU8sV0FBZCxLQUE4QixVQUE1QyxFQUF3RDtBQUFBLFFBQzdDLFdBRDZDLEdBQ3RELFNBQVMsV0FBVCxDQUFxQixLQUFyQixFQUE0QixNQUE1QixFQUFvQztBQUNsQyxpQkFBUyxVQUFVO0FBQ2pCLHFCQUFTLEtBRFE7QUFFakIsd0JBQVksS0FGSztBQUdqQixvQkFBUTtBQUhTLFNBQW5CO0FBS0EsWUFBSSxNQUFNLFNBQVMsV0FBVCxDQUFxQixhQUFyQixDQUFWO0FBQ0EsWUFBSSxlQUFKLENBQW9CLEtBQXBCLEVBQTJCLE9BQU8sT0FBbEMsRUFBMkMsT0FBTyxVQUFsRCxFQUE4RCxPQUFPLE1BQXJFO0FBQ0EsZUFBTyxHQUFQO0FBQ0QsS0FWcUQ7O0FBWXZELFFBQUksT0FBTyxPQUFPLEtBQWQsS0FBd0IsV0FBNUIsRUFBeUM7QUFDdkMsb0JBQVksU0FBWixHQUF3QixPQUFPLEtBQVAsQ0FBYSxTQUFyQztBQUNEOztBQUVBLFdBQU8sV0FBUCxHQUFxQixXQUFyQjtBQUNEIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24oKXtmdW5jdGlvbiByKGUsbix0KXtmdW5jdGlvbiBvKGksZil7aWYoIW5baV0pe2lmKCFlW2ldKXt2YXIgYz1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlO2lmKCFmJiZjKXJldHVybiBjKGksITApO2lmKHUpcmV0dXJuIHUoaSwhMCk7dmFyIGE9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitpK1wiJ1wiKTt0aHJvdyBhLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsYX12YXIgcD1uW2ldPXtleHBvcnRzOnt9fTtlW2ldWzBdLmNhbGwocC5leHBvcnRzLGZ1bmN0aW9uKHIpe3ZhciBuPWVbaV1bMV1bcl07cmV0dXJuIG8obnx8cil9LHAscC5leHBvcnRzLHIsZSxuLHQpfXJldHVybiBuW2ldLmV4cG9ydHN9Zm9yKHZhciB1PVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmUsaT0wO2k8dC5sZW5ndGg7aSsrKW8odFtpXSk7cmV0dXJuIG99cmV0dXJuIHJ9KSgpIiwiaW1wb3J0IFRyaWJ1dGVVdGlscyBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IFRyaWJ1dGVFdmVudHMgZnJvbSBcIi4vVHJpYnV0ZUV2ZW50c1wiO1xuaW1wb3J0IFRyaWJ1dGVNZW51RXZlbnRzIGZyb20gXCIuL1RyaWJ1dGVNZW51RXZlbnRzXCI7XG5pbXBvcnQgVHJpYnV0ZVJhbmdlIGZyb20gXCIuL1RyaWJ1dGVSYW5nZVwiO1xuaW1wb3J0IFRyaWJ1dGVTZWFyY2ggZnJvbSBcIi4vVHJpYnV0ZVNlYXJjaFwiO1xuXG5jbGFzcyBUcmlidXRlIHtcbiAgICBjb25zdHJ1Y3Rvcih7XG4gICAgICAgIHZhbHVlcyA9IG51bGwsXG4gICAgICAgIGlmcmFtZSA9IG51bGwsXG4gICAgICAgIHNlbGVjdENsYXNzID0gJ2hpZ2hsaWdodCcsXG4gICAgICAgIHRyaWdnZXIgPSAnQCcsXG4gICAgICAgIHNlbGVjdFRlbXBsYXRlID0gbnVsbCxcbiAgICAgICAgbWVudUl0ZW1UZW1wbGF0ZSA9IG51bGwsXG4gICAgICAgIGxvb2t1cCA9ICdrZXknLFxuICAgICAgICBmaWxsQXR0ciA9ICd2YWx1ZScsXG4gICAgICAgIGNvbGxlY3Rpb24gPSBudWxsLFxuICAgICAgICBtZW51Q29udGFpbmVyID0gbnVsbCxcbiAgICAgICAgbm9NYXRjaFRlbXBsYXRlID0gbnVsbCxcbiAgICAgICAgcmVxdWlyZUxlYWRpbmdTcGFjZSA9IHRydWUsXG4gICAgICAgIGFsbG93U3BhY2VzID0gZmFsc2UsXG4gICAgICAgIHJlcGxhY2VUZXh0U3VmZml4ID0gbnVsbCxcbiAgICAgICAgcG9zaXRpb25NZW51ID0gdHJ1ZSxcbiAgICAgICAgc3BhY2VTZWxlY3RzTWF0Y2ggPSBmYWxzZSxcbiAgICB9KSB7XG5cbiAgICAgICAgdGhpcy5tZW51U2VsZWN0ZWQgPSAwXG4gICAgICAgIHRoaXMuY3VycmVudCA9IHt9XG4gICAgICAgIHRoaXMuaW5wdXRFdmVudCA9IGZhbHNlXG4gICAgICAgIHRoaXMuaXNBY3RpdmUgPSBmYWxzZVxuICAgICAgICB0aGlzLm1lbnVDb250YWluZXIgPSBtZW51Q29udGFpbmVyXG4gICAgICAgIHRoaXMuYWxsb3dTcGFjZXMgPSBhbGxvd1NwYWNlc1xuICAgICAgICB0aGlzLnJlcGxhY2VUZXh0U3VmZml4ID0gcmVwbGFjZVRleHRTdWZmaXhcbiAgICAgICAgdGhpcy5wb3NpdGlvbk1lbnUgPSBwb3NpdGlvbk1lbnVcbiAgICAgICAgdGhpcy5oYXNUcmFpbGluZ1NwYWNlID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc3BhY2VTZWxlY3RzTWF0Y2ggPSBzcGFjZVNlbGVjdHNNYXRjaDtcblxuICAgICAgICBpZiAodmFsdWVzKSB7XG4gICAgICAgICAgICB0aGlzLmNvbGxlY3Rpb24gPSBbe1xuICAgICAgICAgICAgICAgIC8vIHN5bWJvbCB0aGF0IHN0YXJ0cyB0aGUgbG9va3VwXG4gICAgICAgICAgICAgICAgdHJpZ2dlcjogdHJpZ2dlcixcblxuICAgICAgICAgICAgICAgIC8vIGlzIGl0IHdyYXBwZWQgaW4gYW4gaWZyYW1lXG4gICAgICAgICAgICAgICAgaWZyYW1lOiBpZnJhbWUsXG5cbiAgICAgICAgICAgICAgICAvLyBjbGFzcyBhcHBsaWVkIHRvIHNlbGVjdGVkIGl0ZW1cbiAgICAgICAgICAgICAgICBzZWxlY3RDbGFzczogc2VsZWN0Q2xhc3MsXG5cbiAgICAgICAgICAgICAgICAvLyBmdW5jdGlvbiBjYWxsZWQgb24gc2VsZWN0IHRoYXQgcmV0dW5zIHRoZSBjb250ZW50IHRvIGluc2VydFxuICAgICAgICAgICAgICAgIHNlbGVjdFRlbXBsYXRlOiAoc2VsZWN0VGVtcGxhdGUgfHwgVHJpYnV0ZS5kZWZhdWx0U2VsZWN0VGVtcGxhdGUpLmJpbmQodGhpcyksXG5cbiAgICAgICAgICAgICAgICAvLyBmdW5jdGlvbiBjYWxsZWQgdGhhdCByZXR1cm5zIGNvbnRlbnQgZm9yIGFuIGl0ZW1cbiAgICAgICAgICAgICAgICBtZW51SXRlbVRlbXBsYXRlOiAobWVudUl0ZW1UZW1wbGF0ZSB8fCBUcmlidXRlLmRlZmF1bHRNZW51SXRlbVRlbXBsYXRlKS5iaW5kKHRoaXMpLFxuXG4gICAgICAgICAgICAgICAgLy8gZnVuY3Rpb24gY2FsbGVkIHdoZW4gbWVudSBpcyBlbXB0eSwgZGlzYWJsZXMgaGlkaW5nIG9mIG1lbnUuXG4gICAgICAgICAgICAgICAgbm9NYXRjaFRlbXBsYXRlOiAodCA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHQuYmluZCh0aGlzKVxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vTWF0Y2hUZW1wbGF0ZVxuICAgICAgICAgICAgICAgIH0pKG5vTWF0Y2hUZW1wbGF0ZSksXG5cbiAgICAgICAgICAgICAgICAvLyBjb2x1bW4gdG8gc2VhcmNoIGFnYWluc3QgaW4gdGhlIG9iamVjdFxuICAgICAgICAgICAgICAgIGxvb2t1cDogbG9va3VwLFxuXG4gICAgICAgICAgICAgICAgLy8gY29sdW1uIHRoYXQgY29udGFpbnMgdGhlIGNvbnRlbnQgdG8gaW5zZXJ0IGJ5IGRlZmF1bHRcbiAgICAgICAgICAgICAgICBmaWxsQXR0cjogZmlsbEF0dHIsXG5cbiAgICAgICAgICAgICAgICAvLyBhcnJheSBvZiBvYmplY3RzIG9yIGEgZnVuY3Rpb24gcmV0dXJuaW5nIGFuIGFycmF5IG9mIG9iamVjdHNcbiAgICAgICAgICAgICAgICB2YWx1ZXM6IHZhbHVlcyxcblxuICAgICAgICAgICAgICAgIHJlcXVpcmVMZWFkaW5nU3BhY2U6IHJlcXVpcmVMZWFkaW5nU3BhY2VcbiAgICAgICAgICAgIH1dXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoY29sbGVjdGlvbikge1xuICAgICAgICAgICAgdGhpcy5jb2xsZWN0aW9uID0gY29sbGVjdGlvbi5tYXAoaXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdHJpZ2dlcjogaXRlbS50cmlnZ2VyIHx8IHRyaWdnZXIsXG4gICAgICAgICAgICAgICAgICAgIGlmcmFtZTogaXRlbS5pZnJhbWUgfHwgaWZyYW1lLFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RDbGFzczogaXRlbS5zZWxlY3RDbGFzcyB8fCBzZWxlY3RDbGFzcyxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0VGVtcGxhdGU6IChpdGVtLnNlbGVjdFRlbXBsYXRlIHx8IFRyaWJ1dGUuZGVmYXVsdFNlbGVjdFRlbXBsYXRlKS5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgICAgICBtZW51SXRlbVRlbXBsYXRlOiAoaXRlbS5tZW51SXRlbVRlbXBsYXRlIHx8IFRyaWJ1dGUuZGVmYXVsdE1lbnVJdGVtVGVtcGxhdGUpLmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgICAgIC8vIGZ1bmN0aW9uIGNhbGxlZCB3aGVuIG1lbnUgaXMgZW1wdHksIGRpc2FibGVzIGhpZGluZyBvZiBtZW51LlxuICAgICAgICAgICAgICAgICAgICBub01hdGNoVGVtcGxhdGU6ICh0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0LmJpbmQodGhpcylcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgICAgICAgICAgICAgfSkobm9NYXRjaFRlbXBsYXRlKSxcbiAgICAgICAgICAgICAgICAgICAgbG9va3VwOiBpdGVtLmxvb2t1cCB8fCBsb29rdXAsXG4gICAgICAgICAgICAgICAgICAgIGZpbGxBdHRyOiBpdGVtLmZpbGxBdHRyIHx8IGZpbGxBdHRyLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXM6IGl0ZW0udmFsdWVzLFxuICAgICAgICAgICAgICAgICAgICByZXF1aXJlTGVhZGluZ1NwYWNlOiBpdGVtLnJlcXVpcmVMZWFkaW5nU3BhY2VcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdbVHJpYnV0ZV0gTm8gY29sbGVjdGlvbiBzcGVjaWZpZWQuJylcbiAgICAgICAgfVxuXG4gICAgICAgIG5ldyBUcmlidXRlUmFuZ2UodGhpcylcbiAgICAgICAgbmV3IFRyaWJ1dGVFdmVudHModGhpcylcbiAgICAgICAgbmV3IFRyaWJ1dGVNZW51RXZlbnRzKHRoaXMpXG4gICAgICAgIG5ldyBUcmlidXRlU2VhcmNoKHRoaXMpXG4gICAgfVxuXG4gICAgc3RhdGljIGRlZmF1bHRTZWxlY3RUZW1wbGF0ZShpdGVtKSB7XG4gICAgICBpZiAodHlwZW9mIGl0ZW0gPT09ICd1bmRlZmluZWQnKSByZXR1cm4gbnVsbDtcbiAgICAgIGlmICh0aGlzLnJhbmdlLmlzQ29udGVudEVkaXRhYmxlKHRoaXMuY3VycmVudC5lbGVtZW50KSkge1xuICAgICAgICAgIHJldHVybiAnPHNwYW4gY2xhc3M9XCJ0cmlidXRlLW1lbnRpb25cIj4nICsgKHRoaXMuY3VycmVudC5jb2xsZWN0aW9uLnRyaWdnZXIgKyBpdGVtLm9yaWdpbmFsW3RoaXMuY3VycmVudC5jb2xsZWN0aW9uLmZpbGxBdHRyXSkgKyAnPC9zcGFuPic7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLmN1cnJlbnQuY29sbGVjdGlvbi50cmlnZ2VyICsgaXRlbS5vcmlnaW5hbFt0aGlzLmN1cnJlbnQuY29sbGVjdGlvbi5maWxsQXR0cl07XG4gICAgfVxuXG4gICAgc3RhdGljIGRlZmF1bHRNZW51SXRlbVRlbXBsYXRlKG1hdGNoSXRlbSkge1xuICAgICAgICByZXR1cm4gbWF0Y2hJdGVtLnN0cmluZ1xuICAgIH1cblxuICAgIHN0YXRpYyBpbnB1dFR5cGVzKCkge1xuICAgICAgICByZXR1cm4gWydURVhUQVJFQScsICdJTlBVVCddXG4gICAgfVxuXG4gICAgdHJpZ2dlcnMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbGxlY3Rpb24ubWFwKGNvbmZpZyA9PiB7XG4gICAgICAgICAgICByZXR1cm4gY29uZmlnLnRyaWdnZXJcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICBhdHRhY2goZWwpIHtcbiAgICAgICAgaWYgKCFlbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdbVHJpYnV0ZV0gTXVzdCBwYXNzIGluIGEgRE9NIG5vZGUgb3IgTm9kZUxpc3QuJylcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENoZWNrIGlmIGl0IGlzIGEgalF1ZXJ5IGNvbGxlY3Rpb25cbiAgICAgICAgaWYgKHR5cGVvZiBqUXVlcnkgIT09ICd1bmRlZmluZWQnICYmIGVsIGluc3RhbmNlb2YgalF1ZXJ5KSB7XG4gICAgICAgICAgICBlbCA9IGVsLmdldCgpXG4gICAgICAgIH1cblxuICAgICAgICAvLyBJcyBlbCBhbiBBcnJheS9BcnJheS1saWtlIG9iamVjdD9cbiAgICAgICAgaWYgKGVsLmNvbnN0cnVjdG9yID09PSBOb2RlTGlzdCB8fCBlbC5jb25zdHJ1Y3RvciA9PT0gSFRNTENvbGxlY3Rpb24gfHwgZWwuY29uc3RydWN0b3IgPT09IEFycmF5KSB7XG4gICAgICAgICAgICBsZXQgbGVuZ3RoID0gZWwubGVuZ3RoXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fYXR0YWNoKGVsW2ldKVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fYXR0YWNoKGVsKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2F0dGFjaChlbCkge1xuICAgICAgICBpZiAoZWwuaGFzQXR0cmlidXRlKCdkYXRhLXRyaWJ1dGUnKSkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdUcmlidXRlIHdhcyBhbHJlYWR5IGJvdW5kIHRvICcgKyBlbC5ub2RlTmFtZSlcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZW5zdXJlRWRpdGFibGUoZWwpXG4gICAgICAgIHRoaXMuZXZlbnRzLmJpbmQoZWwpXG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZSgnZGF0YS10cmlidXRlJywgdHJ1ZSlcbiAgICB9XG5cbiAgICBlbnN1cmVFZGl0YWJsZShlbGVtZW50KSB7XG4gICAgICAgIGlmIChUcmlidXRlLmlucHV0VHlwZXMoKS5pbmRleE9mKGVsZW1lbnQubm9kZU5hbWUpID09PSAtMSkge1xuICAgICAgICAgICAgaWYgKGVsZW1lbnQuY29udGVudEVkaXRhYmxlKSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudC5jb250ZW50RWRpdGFibGUgPSB0cnVlXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignW1RyaWJ1dGVdIENhbm5vdCBiaW5kIHRvICcgKyBlbGVtZW50Lm5vZGVOYW1lKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgY3JlYXRlTWVudSgpIHtcbiAgICAgICAgbGV0IHdyYXBwZXIgPSB0aGlzLnJhbmdlLmdldERvY3VtZW50KCkuY3JlYXRlRWxlbWVudCgnZGl2JyksXG4gICAgICAgICAgICB1bCA9IHRoaXMucmFuZ2UuZ2V0RG9jdW1lbnQoKS5jcmVhdGVFbGVtZW50KCd1bCcpXG5cbiAgICAgICAgd3JhcHBlci5jbGFzc05hbWUgPSAndHJpYnV0ZS1jb250YWluZXInXG4gICAgICAgIHdyYXBwZXIuYXBwZW5kQ2hpbGQodWwpXG5cbiAgICAgICAgaWYgKHRoaXMubWVudUNvbnRhaW5lcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubWVudUNvbnRhaW5lci5hcHBlbmRDaGlsZCh3cmFwcGVyKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMucmFuZ2UuZ2V0RG9jdW1lbnQoKS5ib2R5LmFwcGVuZENoaWxkKHdyYXBwZXIpXG4gICAgfVxuXG4gICAgc2hvd01lbnVGb3IoZWxlbWVudCwgc2Nyb2xsVG8pIHtcbiAgICAgICAgLy8gT25seSBwcm9jZWVkIGlmIG1lbnUgaXNuJ3QgYWxyZWFkeSBzaG93biBmb3IgdGhlIGN1cnJlbnQgZWxlbWVudCAmIG1lbnRpb25UZXh0XG4gICAgICAgIGlmICh0aGlzLmlzQWN0aXZlICYmIHRoaXMuY3VycmVudC5lbGVtZW50ID09PSBlbGVtZW50ICYmIHRoaXMuY3VycmVudC5tZW50aW9uVGV4dCA9PT0gdGhpcy5jdXJyZW50TWVudGlvblRleHRTbmFwc2hvdCkge1xuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIHRoaXMuY3VycmVudE1lbnRpb25UZXh0U25hcHNob3QgPSB0aGlzLmN1cnJlbnQubWVudGlvblRleHRcblxuICAgICAgICAvLyBjcmVhdGUgdGhlIG1lbnUgaWYgaXQgZG9lc24ndCBleGlzdC5cbiAgICAgICAgaWYgKCF0aGlzLm1lbnUpIHtcbiAgICAgICAgICAgIHRoaXMubWVudSA9IHRoaXMuY3JlYXRlTWVudSgpXG4gICAgICAgICAgICBlbGVtZW50LnRyaWJ1dGVNZW51ID0gdGhpcy5tZW51XG4gICAgICAgICAgICB0aGlzLm1lbnVFdmVudHMuYmluZCh0aGlzLm1lbnUpXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmlzQWN0aXZlID0gdHJ1ZVxuICAgICAgICB0aGlzLm1lbnVTZWxlY3RlZCA9IDBcblxuICAgICAgICBpZiAoIXRoaXMuY3VycmVudC5tZW50aW9uVGV4dCkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50Lm1lbnRpb25UZXh0ID0gJydcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHByb2Nlc3NWYWx1ZXMgPSAodmFsdWVzKSA9PiB7XG4gICAgICAgICAgICAvLyBUcmlidXRlIG1heSBub3QgYmUgYWN0aXZlIGFueSBtb3JlIGJ5IHRoZSB0aW1lIHRoZSB2YWx1ZSBjYWxsYmFjayByZXR1cm5zXG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNBY3RpdmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IGl0ZW1zID0gdGhpcy5zZWFyY2guZmlsdGVyKHRoaXMuY3VycmVudC5tZW50aW9uVGV4dCwgdmFsdWVzLCB7XG4gICAgICAgICAgICAgICAgcHJlOiAnPHNwYW4+JyxcbiAgICAgICAgICAgICAgICBwb3N0OiAnPC9zcGFuPicsXG4gICAgICAgICAgICAgICAgZXh0cmFjdDogKGVsKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5jdXJyZW50LmNvbGxlY3Rpb24ubG9va3VwID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVsW3RoaXMuY3VycmVudC5jb2xsZWN0aW9uLmxvb2t1cF1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5jdXJyZW50LmNvbGxlY3Rpb24ubG9va3VwID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50LmNvbGxlY3Rpb24ubG9va3VwKGVsLCB0aGlzLmN1cnJlbnQubWVudGlvblRleHQpXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgbG9va3VwIGF0dHJpYnV0ZSwgbG9va3VwIG11c3QgYmUgc3RyaW5nIG9yIGZ1bmN0aW9uLicpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnQuZmlsdGVyZWRJdGVtcyA9IGl0ZW1zXG5cblxuICAgICAgICAgICAgbGV0IHVsID0gdGhpcy5tZW51LnF1ZXJ5U2VsZWN0b3IoJ3VsJylcblxuICAgICAgICAgICAgdGhpcy5yYW5nZS5wb3NpdGlvbk1lbnVBdENhcmV0KHNjcm9sbFRvKVxuXG4gICAgICAgICAgICBpZiAoIWl0ZW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGxldCBub01hdGNoRXZlbnQgPSBuZXcgQ3VzdG9tRXZlbnQoJ3RyaWJ1dGUtbm8tbWF0Y2gnLCB7IGRldGFpbDogdGhpcy5tZW51IH0pXG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50LmVsZW1lbnQuZGlzcGF0Y2hFdmVudChub01hdGNoRXZlbnQpXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmN1cnJlbnQuY29sbGVjdGlvbi5ub01hdGNoVGVtcGxhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oaWRlTWVudSgpXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdWwuaW5uZXJIVE1MID0gdGhpcy5jdXJyZW50LmNvbGxlY3Rpb24ubm9NYXRjaFRlbXBsYXRlKClcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdWwuaW5uZXJIVE1MID0gJydcblxuICAgICAgICAgICAgaXRlbXMuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgbGkgPSB0aGlzLnJhbmdlLmdldERvY3VtZW50KCkuY3JlYXRlRWxlbWVudCgnbGknKVxuICAgICAgICAgICAgICAgIGxpLnNldEF0dHJpYnV0ZSgnZGF0YS1pbmRleCcsIGluZGV4KVxuICAgICAgICAgICAgICAgIGxpLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZW50ZXInLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgbGV0IGxpID0gZS50YXJnZXQ7XG4gICAgICAgICAgICAgICAgICBsZXQgaW5kZXggPSBsaS5nZXRBdHRyaWJ1dGUoJ2RhdGEtaW5kZXgnKVxuICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudHMuc2V0QWN0aXZlTGkoaW5kZXgpXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5tZW51U2VsZWN0ZWQgPT09IGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIGxpLmNsYXNzTmFtZSA9IHRoaXMuY3VycmVudC5jb2xsZWN0aW9uLnNlbGVjdENsYXNzXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxpLmlubmVySFRNTCA9IHRoaXMuY3VycmVudC5jb2xsZWN0aW9uLm1lbnVJdGVtVGVtcGxhdGUoaXRlbSlcbiAgICAgICAgICAgICAgICB1bC5hcHBlbmRDaGlsZChsaSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHRoaXMuY3VycmVudC5jb2xsZWN0aW9uLnZhbHVlcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50LmNvbGxlY3Rpb24udmFsdWVzKHRoaXMuY3VycmVudC5tZW50aW9uVGV4dCwgcHJvY2Vzc1ZhbHVlcylcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHByb2Nlc3NWYWx1ZXModGhpcy5jdXJyZW50LmNvbGxlY3Rpb24udmFsdWVzKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2hvd01lbnVGb3JDb2xsZWN0aW9uKGVsZW1lbnQsIGNvbGxlY3Rpb25JbmRleCkge1xuICAgICAgICBpZiAoZWxlbWVudCAhPT0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5wbGFjZUNhcmV0QXRFbmQoZWxlbWVudClcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY3VycmVudC5jb2xsZWN0aW9uID0gdGhpcy5jb2xsZWN0aW9uW2NvbGxlY3Rpb25JbmRleCB8fCAwXVxuICAgICAgICB0aGlzLmN1cnJlbnQuZXh0ZXJuYWxUcmlnZ2VyID0gdHJ1ZVxuICAgICAgICB0aGlzLmN1cnJlbnQuZWxlbWVudCA9IGVsZW1lbnRcblxuICAgICAgICBpZiAoZWxlbWVudC5pc0NvbnRlbnRFZGl0YWJsZSlcbiAgICAgICAgICAgIHRoaXMuaW5zZXJ0VGV4dEF0Q3Vyc29yKHRoaXMuY3VycmVudC5jb2xsZWN0aW9uLnRyaWdnZXIpXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHRoaXMuaW5zZXJ0QXRDYXJldChlbGVtZW50LCB0aGlzLmN1cnJlbnQuY29sbGVjdGlvbi50cmlnZ2VyKVxuXG4gICAgICAgIHRoaXMuc2hvd01lbnVGb3IoZWxlbWVudClcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBtYWtlIHN1cmUgdGhpcyB3b3JrcyBmb3IgaW5wdXRzL3RleHRhcmVhc1xuICAgIHBsYWNlQ2FyZXRBdEVuZChlbCkge1xuICAgICAgICBlbC5mb2N1cygpO1xuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdy5nZXRTZWxlY3Rpb24gIT0gXCJ1bmRlZmluZWRcIlxuICAgICAgICAgICAgICAgICYmIHR5cGVvZiBkb2N1bWVudC5jcmVhdGVSYW5nZSAhPSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICB2YXIgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgICAgICAgICAgcmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKGVsKTtcbiAgICAgICAgICAgIHJhbmdlLmNvbGxhcHNlKGZhbHNlKTtcbiAgICAgICAgICAgIHZhciBzZWwgPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgICAgICAgICBzZWwucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gICAgICAgICAgICBzZWwuYWRkUmFuZ2UocmFuZ2UpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkb2N1bWVudC5ib2R5LmNyZWF0ZVRleHRSYW5nZSAhPSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICB2YXIgdGV4dFJhbmdlID0gZG9jdW1lbnQuYm9keS5jcmVhdGVUZXh0UmFuZ2UoKTtcbiAgICAgICAgICAgIHRleHRSYW5nZS5tb3ZlVG9FbGVtZW50VGV4dChlbCk7XG4gICAgICAgICAgICB0ZXh0UmFuZ2UuY29sbGFwc2UoZmFsc2UpO1xuICAgICAgICAgICAgdGV4dFJhbmdlLnNlbGVjdCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gZm9yIGNvbnRlbnRlZGl0YWJsZVxuICAgIGluc2VydFRleHRBdEN1cnNvcih0ZXh0KSB7XG4gICAgICAgIHZhciBzZWwsIHJhbmdlLCBodG1sO1xuICAgICAgICBzZWwgPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgICAgIHJhbmdlID0gc2VsLmdldFJhbmdlQXQoMCk7XG4gICAgICAgIHJhbmdlLmRlbGV0ZUNvbnRlbnRzKCk7XG4gICAgICAgIHZhciB0ZXh0Tm9kZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRleHQpO1xuICAgICAgICByYW5nZS5pbnNlcnROb2RlKHRleHROb2RlKTtcbiAgICAgICAgcmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKHRleHROb2RlKVxuICAgICAgICByYW5nZS5jb2xsYXBzZShmYWxzZSlcbiAgICAgICAgc2VsLnJlbW92ZUFsbFJhbmdlcygpXG4gICAgICAgIHNlbC5hZGRSYW5nZShyYW5nZSlcbiAgICB9XG5cbiAgICAvLyBmb3IgcmVndWxhciBpbnB1dHNcbiAgICBpbnNlcnRBdENhcmV0KHRleHRhcmVhLCB0ZXh0KSB7XG4gICAgICAgIHZhciBzY3JvbGxQb3MgPSB0ZXh0YXJlYS5zY3JvbGxUb3A7XG4gICAgICAgIHZhciBjYXJldFBvcyA9IHRleHRhcmVhLnNlbGVjdGlvblN0YXJ0O1xuXG4gICAgICAgIHZhciBmcm9udCA9ICh0ZXh0YXJlYS52YWx1ZSkuc3Vic3RyaW5nKDAsIGNhcmV0UG9zKTtcbiAgICAgICAgdmFyIGJhY2sgPSAodGV4dGFyZWEudmFsdWUpLnN1YnN0cmluZyh0ZXh0YXJlYS5zZWxlY3Rpb25FbmQsIHRleHRhcmVhLnZhbHVlLmxlbmd0aCk7XG4gICAgICAgIHRleHRhcmVhLnZhbHVlID0gZnJvbnQgKyB0ZXh0ICsgYmFjaztcbiAgICAgICAgY2FyZXRQb3MgPSBjYXJldFBvcyArIHRleHQubGVuZ3RoO1xuICAgICAgICB0ZXh0YXJlYS5zZWxlY3Rpb25TdGFydCA9IGNhcmV0UG9zO1xuICAgICAgICB0ZXh0YXJlYS5zZWxlY3Rpb25FbmQgPSBjYXJldFBvcztcbiAgICAgICAgdGV4dGFyZWEuZm9jdXMoKTtcbiAgICAgICAgdGV4dGFyZWEuc2Nyb2xsVG9wID0gc2Nyb2xsUG9zO1xuICAgIH1cblxuICAgIGhpZGVNZW51KCkge1xuICAgICAgICBpZiAodGhpcy5tZW51KSB7XG4gICAgICAgICAgICB0aGlzLm1lbnUuc3R5bGUuY3NzVGV4dCA9ICdkaXNwbGF5OiBub25lOydcbiAgICAgICAgICAgIHRoaXMuaXNBY3RpdmUgPSBmYWxzZVxuICAgICAgICAgICAgdGhpcy5tZW51U2VsZWN0ZWQgPSAwXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnQgPSB7fVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2VsZWN0SXRlbUF0SW5kZXgoaW5kZXgsIG9yaWdpbmFsRXZlbnQpIHtcbiAgICAgICAgaW5kZXggPSBwYXJzZUludChpbmRleClcbiAgICAgICAgaWYgKHR5cGVvZiBpbmRleCAhPT0gJ251bWJlcicpIHJldHVyblxuICAgICAgICBsZXQgaXRlbSA9IHRoaXMuY3VycmVudC5maWx0ZXJlZEl0ZW1zW2luZGV4XVxuICAgICAgICBsZXQgY29udGVudCA9IHRoaXMuY3VycmVudC5jb2xsZWN0aW9uLnNlbGVjdFRlbXBsYXRlKGl0ZW0pXG4gICAgICAgIGlmIChjb250ZW50ICE9PSBudWxsKSB0aGlzLnJlcGxhY2VUZXh0KGNvbnRlbnQsIG9yaWdpbmFsRXZlbnQsIGl0ZW0pXG4gICAgfVxuXG4gICAgcmVwbGFjZVRleHQoY29udGVudCwgb3JpZ2luYWxFdmVudCwgaXRlbSkge1xuICAgICAgICB0aGlzLnJhbmdlLnJlcGxhY2VUcmlnZ2VyVGV4dChjb250ZW50LCB0cnVlLCB0cnVlLCBvcmlnaW5hbEV2ZW50LCBpdGVtKVxuICAgIH1cblxuICAgIF9hcHBlbmQoY29sbGVjdGlvbiwgbmV3VmFsdWVzLCByZXBsYWNlKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY29sbGVjdGlvbi52YWx1ZXMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGFwcGVuZCB0byB2YWx1ZXMsIGFzIGl0IGlzIGEgZnVuY3Rpb24uJylcbiAgICAgICAgfSBlbHNlIGlmICghcmVwbGFjZSkge1xuICAgICAgICAgICAgY29sbGVjdGlvbi52YWx1ZXMgPSBjb2xsZWN0aW9uLnZhbHVlcy5jb25jYXQobmV3VmFsdWVzKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29sbGVjdGlvbi52YWx1ZXMgPSBuZXdWYWx1ZXNcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFwcGVuZChjb2xsZWN0aW9uSW5kZXgsIG5ld1ZhbHVlcywgcmVwbGFjZSkge1xuICAgICAgICBsZXQgaW5kZXggPSBwYXJzZUludChjb2xsZWN0aW9uSW5kZXgpXG4gICAgICAgIGlmICh0eXBlb2YgaW5kZXggIT09ICdudW1iZXInKSB0aHJvdyBuZXcgRXJyb3IoJ3BsZWFzZSBwcm92aWRlIGFuIGluZGV4IGZvciB0aGUgY29sbGVjdGlvbiB0byB1cGRhdGUuJylcblxuICAgICAgICBsZXQgY29sbGVjdGlvbiA9IHRoaXMuY29sbGVjdGlvbltpbmRleF1cblxuICAgICAgICB0aGlzLl9hcHBlbmQoY29sbGVjdGlvbiwgbmV3VmFsdWVzLCByZXBsYWNlKVxuICAgIH1cblxuICAgIGFwcGVuZEN1cnJlbnQobmV3VmFsdWVzLCByZXBsYWNlKSB7XG4gICAgICAgIGlmICh0aGlzLmlzQWN0aXZlKSB7XG4gICAgICAgICAgICB0aGlzLl9hcHBlbmQodGhpcy5jdXJyZW50LmNvbGxlY3Rpb24sIG5ld1ZhbHVlcywgcmVwbGFjZSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTm8gYWN0aXZlIHN0YXRlLiBQbGVhc2UgdXNlIGFwcGVuZCBpbnN0ZWFkIGFuZCBwYXNzIGFuIGluZGV4LicpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkZXRhY2goZWwpIHtcbiAgICAgICAgaWYgKCFlbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdbVHJpYnV0ZV0gTXVzdCBwYXNzIGluIGEgRE9NIG5vZGUgb3IgTm9kZUxpc3QuJylcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENoZWNrIGlmIGl0IGlzIGEgalF1ZXJ5IGNvbGxlY3Rpb25cbiAgICAgICAgaWYgKHR5cGVvZiBqUXVlcnkgIT09ICd1bmRlZmluZWQnICYmIGVsIGluc3RhbmNlb2YgalF1ZXJ5KSB7XG4gICAgICAgICAgICBlbCA9IGVsLmdldCgpXG4gICAgICAgIH1cblxuICAgICAgICAvLyBJcyBlbCBhbiBBcnJheS9BcnJheS1saWtlIG9iamVjdD9cbiAgICAgICAgaWYgKGVsLmNvbnN0cnVjdG9yID09PSBOb2RlTGlzdCB8fCBlbC5jb25zdHJ1Y3RvciA9PT0gSFRNTENvbGxlY3Rpb24gfHwgZWwuY29uc3RydWN0b3IgPT09IEFycmF5KSB7XG4gICAgICAgICAgICBsZXQgbGVuZ3RoID0gZWwubGVuZ3RoXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZGV0YWNoKGVsW2ldKVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fZGV0YWNoKGVsKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2RldGFjaChlbCkge1xuICAgICAgICB0aGlzLmV2ZW50cy51bmJpbmQoZWwpXG4gICAgICAgIGlmIChlbC50cmlidXRlTWVudSkge1xuICAgICAgICAgICAgdGhpcy5tZW51RXZlbnRzLnVuYmluZChlbC50cmlidXRlTWVudSlcbiAgICAgICAgfVxuXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKCdkYXRhLXRyaWJ1dGUnKVxuICAgICAgICAgICAgdGhpcy5pc0FjdGl2ZSA9IGZhbHNlXG4gICAgICAgICAgICBpZiAoZWwudHJpYnV0ZU1lbnUpIHtcbiAgICAgICAgICAgICAgICBlbC50cmlidXRlTWVudS5yZW1vdmUoKVxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgVHJpYnV0ZTtcbiIsImNsYXNzIFRyaWJ1dGVFdmVudHMge1xuICAgIGNvbnN0cnVjdG9yKHRyaWJ1dGUpIHtcbiAgICAgICAgdGhpcy50cmlidXRlID0gdHJpYnV0ZVxuICAgICAgICB0aGlzLnRyaWJ1dGUuZXZlbnRzID0gdGhpc1xuICAgIH1cblxuICAgIHN0YXRpYyBrZXlzKCkge1xuICAgICAgICByZXR1cm4gW3tcbiAgICAgICAgICAgIGtleTogOSxcbiAgICAgICAgICAgIHZhbHVlOiAnVEFCJ1xuICAgICAgICB9LCB7XG4gICAgICAgICAgICBrZXk6IDgsXG4gICAgICAgICAgICB2YWx1ZTogJ0RFTEVURSdcbiAgICAgICAgfSwge1xuICAgICAgICAgICAga2V5OiAxMyxcbiAgICAgICAgICAgIHZhbHVlOiAnRU5URVInXG4gICAgICAgIH0sIHtcbiAgICAgICAgICAgIGtleTogMjcsXG4gICAgICAgICAgICB2YWx1ZTogJ0VTQ0FQRSdcbiAgICAgICAgfSwge1xuICAgICAgICAgICAga2V5OiAzMixcbiAgICAgICAgICAgIHZhbHVlOiAnU1BBQ0UnXG4gICAgICAgIH0sIHtcbiAgICAgICAgICAgIGtleTogMzgsXG4gICAgICAgICAgICB2YWx1ZTogJ1VQJ1xuICAgICAgICB9LCB7XG4gICAgICAgICAgICBrZXk6IDQwLFxuICAgICAgICAgICAgdmFsdWU6ICdET1dOJ1xuICAgICAgICB9XVxuICAgIH1cblxuICAgIGJpbmQoZWxlbWVudCkge1xuICAgICAgICBlbGVtZW50LmJvdW5kS2V5ZG93biA9IHRoaXMua2V5ZG93bi5iaW5kKGVsZW1lbnQsIHRoaXMpO1xuICAgICAgICBlbGVtZW50LmJvdW5kS2V5dXAgPSB0aGlzLmtleXVwLmJpbmQoZWxlbWVudCwgdGhpcyk7XG4gICAgICAgIGVsZW1lbnQuYm91bmRJbnB1dCA9IHRoaXMuaW5wdXQuYmluZChlbGVtZW50LCB0aGlzKTtcblxuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLFxuICAgICAgICAgICAgZWxlbWVudC5ib3VuZEtleWRvd24sIGZhbHNlKVxuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleXVwJyxcbiAgICAgICAgICAgIGVsZW1lbnQuYm91bmRLZXl1cCwgZmFsc2UpXG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLFxuICAgICAgICAgICAgZWxlbWVudC5ib3VuZElucHV0LCBmYWxzZSlcbiAgICB9XG5cbiAgICB1bmJpbmQoZWxlbWVudCkge1xuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLFxuICAgICAgICAgICAgZWxlbWVudC5ib3VuZEtleWRvd24sIGZhbHNlKVxuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleXVwJyxcbiAgICAgICAgICAgIGVsZW1lbnQuYm91bmRLZXl1cCwgZmFsc2UpXG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignaW5wdXQnLFxuICAgICAgICAgICAgZWxlbWVudC5ib3VuZElucHV0LCBmYWxzZSlcblxuICAgICAgICBkZWxldGUgZWxlbWVudC5ib3VuZEtleWRvd25cbiAgICAgICAgZGVsZXRlIGVsZW1lbnQuYm91bmRLZXl1cFxuICAgICAgICBkZWxldGUgZWxlbWVudC5ib3VuZElucHV0XG4gICAgfVxuXG4gICAga2V5ZG93bihpbnN0YW5jZSwgZXZlbnQpIHtcbiAgICAgICAgaWYgKGluc3RhbmNlLnNob3VsZERlYWN0aXZhdGUoZXZlbnQpKSB7XG4gICAgICAgICAgICBpbnN0YW5jZS50cmlidXRlLmlzQWN0aXZlID0gZmFsc2VcbiAgICAgICAgICAgIGluc3RhbmNlLnRyaWJ1dGUuaGlkZU1lbnUoKVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGVsZW1lbnQgPSB0aGlzXG4gICAgICAgIGluc3RhbmNlLmNvbW1hbmRFdmVudCA9IGZhbHNlXG5cbiAgICAgICAgVHJpYnV0ZUV2ZW50cy5rZXlzKCkuZm9yRWFjaChvID0+IHtcbiAgICAgICAgICAgIGlmIChvLmtleSA9PT0gZXZlbnQua2V5Q29kZSkge1xuICAgICAgICAgICAgICAgIGluc3RhbmNlLmNvbW1hbmRFdmVudCA9IHRydWVcbiAgICAgICAgICAgICAgICBpbnN0YW5jZS5jYWxsYmFja3MoKVtvLnZhbHVlLnRvTG93ZXJDYXNlKCldKGV2ZW50LCBlbGVtZW50KVxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuICAgIH1cblxuICAgIGlucHV0KGluc3RhbmNlLCBldmVudCkge1xuICAgICAgICBpbnN0YW5jZS5pbnB1dEV2ZW50ID0gdHJ1ZVxuICAgICAgICBpbnN0YW5jZS5rZXl1cC5jYWxsKHRoaXMsIGluc3RhbmNlLCBldmVudClcbiAgICB9XG5cbiAgICBjbGljayhpbnN0YW5jZSwgZXZlbnQpIHtcbiAgICAgICAgbGV0IHRyaWJ1dGUgPSBpbnN0YW5jZS50cmlidXRlXG4gICAgICAgIGlmICh0cmlidXRlLm1lbnUgJiYgdHJpYnV0ZS5tZW51LmNvbnRhaW5zKGV2ZW50LnRhcmdldCkpIHtcbiAgICAgICAgICAgIGxldCBsaSA9IGV2ZW50LnRhcmdldFxuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxuICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcbiAgICAgICAgICAgIHdoaWxlIChsaS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpICE9PSAnbGknKSB7XG4gICAgICAgICAgICAgICAgbGkgPSBsaS5wYXJlbnROb2RlXG4gICAgICAgICAgICAgICAgaWYgKCFsaSB8fCBsaSA9PT0gdHJpYnV0ZS5tZW51KSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IGZpbmQgdGhlIDxsaT4gY29udGFpbmVyIGZvciB0aGUgY2xpY2snKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRyaWJ1dGUuc2VsZWN0SXRlbUF0SW5kZXgobGkuZ2V0QXR0cmlidXRlKCdkYXRhLWluZGV4JyksIGV2ZW50KVxuICAgICAgICAgICAgdHJpYnV0ZS5oaWRlTWVudSgpXG5cbiAgICAgICAgLy8gVE9ETzogc2hvdWxkIGZpcmUgd2l0aCBleHRlcm5hbFRyaWdnZXIgYW5kIHRhcmdldCBpcyBvdXRzaWRlIG9mIG1lbnVcbiAgICAgICAgfSBlbHNlIGlmICh0cmlidXRlLmN1cnJlbnQuZWxlbWVudCAmJiAhdHJpYnV0ZS5jdXJyZW50LmV4dGVybmFsVHJpZ2dlcikge1xuICAgICAgICAgICAgdHJpYnV0ZS5jdXJyZW50LmV4dGVybmFsVHJpZ2dlciA9IGZhbHNlXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRyaWJ1dGUuaGlkZU1lbnUoKSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGtleXVwKGluc3RhbmNlLCBldmVudCkge1xuICAgICAgICBpZiAoaW5zdGFuY2UuaW5wdXRFdmVudCkge1xuICAgICAgICAgICAgaW5zdGFuY2UuaW5wdXRFdmVudCA9IGZhbHNlXG4gICAgICAgIH1cbiAgICAgICAgaW5zdGFuY2UudXBkYXRlU2VsZWN0aW9uKHRoaXMpXG5cbiAgICAgICAgaWYgKGV2ZW50LmtleUNvZGUgPT09IDI3KSByZXR1cm5cblxuICAgICAgICBpZiAoIWluc3RhbmNlLnRyaWJ1dGUuYWxsb3dTcGFjZXMgJiYgaW5zdGFuY2UudHJpYnV0ZS5oYXNUcmFpbGluZ1NwYWNlKSB7XG4gICAgICAgICAgICBpbnN0YW5jZS50cmlidXRlLmhhc1RyYWlsaW5nU3BhY2UgPSBmYWxzZTtcbiAgICAgICAgICAgIGluc3RhbmNlLmNvbW1hbmRFdmVudCA9IHRydWU7XG4gICAgICAgICAgICBpbnN0YW5jZS5jYWxsYmFja3MoKVtcInNwYWNlXCJdKGV2ZW50LCB0aGlzKTtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFpbnN0YW5jZS50cmlidXRlLmlzQWN0aXZlKSB7XG4gICAgICAgICAgICBsZXQga2V5Q29kZSA9IGluc3RhbmNlLmdldEtleUNvZGUoaW5zdGFuY2UsIHRoaXMsIGV2ZW50KVxuXG4gICAgICAgICAgICBpZiAoaXNOYU4oa2V5Q29kZSkgfHwgIWtleUNvZGUpIHJldHVyblxuXG4gICAgICAgICAgICBsZXQgdHJpZ2dlciA9IGluc3RhbmNlLnRyaWJ1dGUudHJpZ2dlcnMoKS5maW5kKHRyaWdnZXIgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cmlnZ2VyLmNoYXJDb2RlQXQoMCkgPT09IGtleUNvZGVcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgdHJpZ2dlciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICBpbnN0YW5jZS5jYWxsYmFja3MoKS50cmlnZ2VyQ2hhcihldmVudCwgdGhpcywgdHJpZ2dlcilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbnN0YW5jZS50cmlidXRlLmN1cnJlbnQudHJpZ2dlciAmJiBpbnN0YW5jZS5jb21tYW5kRXZlbnQgPT09IGZhbHNlXG4gICAgICAgICAgICB8fCBpbnN0YW5jZS50cmlidXRlLmlzQWN0aXZlICYmIGV2ZW50LmtleUNvZGUgPT09IDgpIHtcbiAgICAgICAgICBpbnN0YW5jZS50cmlidXRlLnNob3dNZW51Rm9yKHRoaXMsIHRydWUpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzaG91bGREZWFjdGl2YXRlKGV2ZW50KSB7XG4gICAgICAgIGlmICghdGhpcy50cmlidXRlLmlzQWN0aXZlKSByZXR1cm4gZmFsc2VcblxuICAgICAgICBpZiAodGhpcy50cmlidXRlLmN1cnJlbnQubWVudGlvblRleHQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBsZXQgZXZlbnRLZXlQcmVzc2VkID0gZmFsc2VcbiAgICAgICAgICAgIFRyaWJ1dGVFdmVudHMua2V5cygpLmZvckVhY2gobyA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LmtleUNvZGUgPT09IG8ua2V5KSBldmVudEtleVByZXNzZWQgPSB0cnVlXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICByZXR1cm4gIWV2ZW50S2V5UHJlc3NlZFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgZ2V0S2V5Q29kZShpbnN0YW5jZSwgZWwsIGV2ZW50KSB7XG4gICAgICAgIGxldCBjaGFyXG4gICAgICAgIGxldCB0cmlidXRlID0gaW5zdGFuY2UudHJpYnV0ZVxuICAgICAgICBsZXQgaW5mbyA9IHRyaWJ1dGUucmFuZ2UuZ2V0VHJpZ2dlckluZm8oZmFsc2UsIHRyaWJ1dGUuaGFzVHJhaWxpbmdTcGFjZSwgdHJ1ZSwgdHJpYnV0ZS5hbGxvd1NwYWNlcylcblxuICAgICAgICBpZiAoaW5mbykge1xuICAgICAgICAgICAgcmV0dXJuIGluZm8ubWVudGlvblRyaWdnZXJDaGFyLmNoYXJDb2RlQXQoMClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgdXBkYXRlU2VsZWN0aW9uKGVsKSB7XG4gICAgICAgIHRoaXMudHJpYnV0ZS5jdXJyZW50LmVsZW1lbnQgPSBlbFxuICAgICAgICBsZXQgaW5mbyA9IHRoaXMudHJpYnV0ZS5yYW5nZS5nZXRUcmlnZ2VySW5mbyhmYWxzZSwgdGhpcy50cmlidXRlLmhhc1RyYWlsaW5nU3BhY2UsIHRydWUsIHRoaXMudHJpYnV0ZS5hbGxvd1NwYWNlcylcblxuICAgICAgICBpZiAoaW5mbykge1xuICAgICAgICAgICAgdGhpcy50cmlidXRlLmN1cnJlbnQuc2VsZWN0ZWRQYXRoID0gaW5mby5tZW50aW9uU2VsZWN0ZWRQYXRoXG4gICAgICAgICAgICB0aGlzLnRyaWJ1dGUuY3VycmVudC5tZW50aW9uVGV4dCA9IGluZm8ubWVudGlvblRleHRcbiAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5jdXJyZW50LnNlbGVjdGVkT2Zmc2V0ID0gaW5mby5tZW50aW9uU2VsZWN0ZWRPZmZzZXRcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNhbGxiYWNrcygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHRyaWdnZXJDaGFyOiAoZSwgZWwsIHRyaWdnZXIpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgdHJpYnV0ZSA9IHRoaXMudHJpYnV0ZVxuICAgICAgICAgICAgICAgIHRyaWJ1dGUuY3VycmVudC50cmlnZ2VyID0gdHJpZ2dlclxuXG4gICAgICAgICAgICAgICAgbGV0IGNvbGxlY3Rpb25JdGVtID0gdHJpYnV0ZS5jb2xsZWN0aW9uLmZpbmQoaXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpdGVtLnRyaWdnZXIgPT09IHRyaWdnZXJcbiAgICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgICAgdHJpYnV0ZS5jdXJyZW50LmNvbGxlY3Rpb24gPSBjb2xsZWN0aW9uSXRlbVxuICAgICAgICAgICAgICAgIGlmICh0cmlidXRlLmlucHV0RXZlbnQpIHRyaWJ1dGUuc2hvd01lbnVGb3IoZWwsIHRydWUpXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZW50ZXI6IChlLCBlbCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIGNob29zZSBzZWxlY3Rpb25cbiAgICAgICAgICAgICAgICBpZiAodGhpcy50cmlidXRlLmlzQWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKVxuICAgICAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpXG4gICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50cmlidXRlLnNlbGVjdEl0ZW1BdEluZGV4KHRoaXMudHJpYnV0ZS5tZW51U2VsZWN0ZWQsIGUpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWJ1dGUuaGlkZU1lbnUoKVxuICAgICAgICAgICAgICAgICAgICB9LCAwKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlc2NhcGU6IChlLCBlbCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRyaWJ1dGUuaXNBY3RpdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICAgICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKClcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50cmlidXRlLmlzQWN0aXZlID0gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50cmlidXRlLmhpZGVNZW51KClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGFiOiAoZSwgZWwpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBjaG9vc2UgZmlyc3QgbWF0Y2hcbiAgICAgICAgICAgICAgICB0aGlzLmNhbGxiYWNrcygpLmVudGVyKGUsIGVsKVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNwYWNlOiAoZSwgZWwpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy50cmlidXRlLmlzQWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnRyaWJ1dGUuc3BhY2VTZWxlY3RzTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2FsbGJhY2tzKCkuZW50ZXIoZSwgZWwpXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXRoaXMudHJpYnV0ZS5hbGxvd1NwYWNlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5oaWRlTWVudSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5pc0FjdGl2ZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdXA6IChlLCBlbCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIG5hdmlnYXRlIHVwIHVsXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudHJpYnV0ZS5pc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KClcbiAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKVxuICAgICAgICAgICAgICAgICAgICBsZXQgY291bnQgPSB0aGlzLnRyaWJ1dGUuY3VycmVudC5maWx0ZXJlZEl0ZW1zLmxlbmd0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkID0gdGhpcy50cmlidXRlLm1lbnVTZWxlY3RlZFxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb3VudCA+IHNlbGVjdGVkICYmIHNlbGVjdGVkID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50cmlidXRlLm1lbnVTZWxlY3RlZC0tXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEFjdGl2ZUxpKClcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzZWxlY3RlZCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5tZW51U2VsZWN0ZWQgPSBjb3VudCAtIDFcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEFjdGl2ZUxpKClcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWJ1dGUubWVudS5zY3JvbGxUb3AgPSB0aGlzLnRyaWJ1dGUubWVudS5zY3JvbGxIZWlnaHRcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkb3duOiAoZSwgZWwpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBuYXZpZ2F0ZSBkb3duIHVsXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudHJpYnV0ZS5pc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KClcbiAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKVxuICAgICAgICAgICAgICAgICAgICBsZXQgY291bnQgPSB0aGlzLnRyaWJ1dGUuY3VycmVudC5maWx0ZXJlZEl0ZW1zLmxlbmd0aCAtIDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZCA9IHRoaXMudHJpYnV0ZS5tZW51U2VsZWN0ZWRcblxuICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPiBzZWxlY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50cmlidXRlLm1lbnVTZWxlY3RlZCsrXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEFjdGl2ZUxpKClcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjb3VudCA9PT0gc2VsZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5tZW51U2VsZWN0ZWQgPSAwXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEFjdGl2ZUxpKClcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5tZW51LnNjcm9sbFRvcCA9IDBcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkZWxldGU6IChlLCBlbCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRyaWJ1dGUuaXNBY3RpdmUgJiYgdGhpcy50cmlidXRlLmN1cnJlbnQubWVudGlvblRleHQubGVuZ3RoIDwgMSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWJ1dGUuaGlkZU1lbnUoKVxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy50cmlidXRlLmlzQWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5zaG93TWVudUZvcihlbClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRBY3RpdmVMaShpbmRleCkge1xuICAgICAgICBsZXQgbGlzID0gdGhpcy50cmlidXRlLm1lbnUucXVlcnlTZWxlY3RvckFsbCgnbGknKSxcbiAgICAgICAgICAgIGxlbmd0aCA9IGxpcy5sZW5ndGggPj4+IDBcblxuICAgICAgICAvLyBnZXQgaGVpZ2h0c1xuICAgICAgICBsZXQgbWVudUZ1bGxIZWlnaHQgPSB0aGlzLmdldEZ1bGxIZWlnaHQodGhpcy50cmlidXRlLm1lbnUpLFxuICAgICAgICAgICAgbGlIZWlnaHQgPSB0aGlzLmdldEZ1bGxIZWlnaHQobGlzWzBdKVxuXG4gICAgICAgIGlmIChpbmRleCkgdGhpcy50cmlidXRlLm1lbnVTZWxlY3RlZCA9IGluZGV4O1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBsaSA9IGxpc1tpXVxuICAgICAgICAgICAgaWYgKGkgPT09IHRoaXMudHJpYnV0ZS5tZW51U2VsZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICBsZXQgb2Zmc2V0ID0gbGlIZWlnaHQgKiAoaSsxKVxuICAgICAgICAgICAgICAgIGxldCBzY3JvbGxUb3AgPSB0aGlzLnRyaWJ1dGUubWVudS5zY3JvbGxUb3BcbiAgICAgICAgICAgICAgICBsZXQgdG90YWxTY3JvbGwgPSBzY3JvbGxUb3AgKyBtZW51RnVsbEhlaWdodFxuXG4gICAgICAgICAgICAgICAgaWYgKG9mZnNldCA+IHRvdGFsU2Nyb2xsKSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLnRyaWJ1dGUubWVudS5zY3JvbGxUb3AgKz0gbGlIZWlnaHRcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG9mZnNldCA8IHRvdGFsU2Nyb2xsKSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLnRyaWJ1dGUubWVudS5zY3JvbGxUb3AgLT0gbGlIZWlnaHRcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBsaS5jbGFzc05hbWUgPSB0aGlzLnRyaWJ1dGUuY3VycmVudC5jb2xsZWN0aW9uLnNlbGVjdENsYXNzXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxpLmNsYXNzTmFtZSA9ICcnXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRGdWxsSGVpZ2h0KGVsZW0sIGluY2x1ZGVNYXJnaW4pIHtcbiAgICAgIGxldCBoZWlnaHQgPSBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmhlaWdodFxuXG4gICAgICBpZiAoaW5jbHVkZU1hcmdpbikge1xuICAgICAgICBsZXQgc3R5bGUgPSBlbGVtLmN1cnJlbnRTdHlsZSB8fCB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbGVtKVxuICAgICAgICByZXR1cm4gaGVpZ2h0ICsgcGFyc2VGbG9hdChzdHlsZS5tYXJnaW5Ub3ApICsgcGFyc2VGbG9hdChzdHlsZS5tYXJnaW5Cb3R0b20pXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBoZWlnaHRcbiAgICB9XG5cbn1cblxuZXhwb3J0IGRlZmF1bHQgVHJpYnV0ZUV2ZW50cztcbiIsImNsYXNzIFRyaWJ1dGVNZW51RXZlbnRzIHtcbiAgICBjb25zdHJ1Y3Rvcih0cmlidXRlKSB7XG4gICAgICAgIHRoaXMudHJpYnV0ZSA9IHRyaWJ1dGVcbiAgICAgICAgdGhpcy50cmlidXRlLm1lbnVFdmVudHMgPSB0aGlzXG4gICAgICAgIHRoaXMubWVudSA9IHRoaXMudHJpYnV0ZS5tZW51XG4gICAgfVxuXG4gICAgYmluZChtZW51KSB7XG4gICAgICAgIG1lbnUubWVudUtleWRvd25FdmVudCA9IHRoaXMudHJpYnV0ZS5ldmVudHMua2V5ZG93bi5iaW5kKHRoaXMubWVudSwgdGhpcylcbiAgICAgICAgdGhpcy5tZW51Q2xpY2tFdmVudCA9IHRoaXMudHJpYnV0ZS5ldmVudHMuY2xpY2suYmluZChudWxsLCB0aGlzKVxuICAgICAgICB0aGlzLm1lbnVDb250YWluZXJTY3JvbGxFdmVudCA9IHRoaXMuZGVib3VuY2UoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMudHJpYnV0ZS5pc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5zaG93TWVudUZvcih0aGlzLnRyaWJ1dGUuY3VycmVudC5lbGVtZW50LCBmYWxzZSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgMzAwLCBmYWxzZSlcbiAgICAgICAgdGhpcy53aW5kb3dSZXNpemVFdmVudCA9IHRoaXMuZGVib3VuY2UoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMudHJpYnV0ZS5pc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5yYW5nZS5wb3NpdGlvbk1lbnVBdENhcmV0KHRydWUpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIDMwMCwgZmFsc2UpXG5cbiAgICAgICAgLy8gZml4ZXMgSUUxMSBpc3N1ZXMgd2l0aCBtb3VzZXVwXG4gICAgICAgIHRoaXMudHJpYnV0ZS5yYW5nZS5nZXREb2N1bWVudCgpLmFkZEV2ZW50TGlzdGVuZXIoJ01TUG9pbnRlclVwJyxcbiAgICAgICAgICAgIHRoaXMubWVudUNsaWNrRXZlbnQsIGZhbHNlKVxuICAgICAgICBtZW51LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLFxuICAgICAgICAgICAgdGhpcy5tZW51S2V5ZG93bkV2ZW50LCBmYWxzZSlcbiAgICAgICAgdGhpcy50cmlidXRlLnJhbmdlLmdldERvY3VtZW50KCkuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsXG4gICAgICAgICAgICB0aGlzLm1lbnVDbGlja0V2ZW50LCBmYWxzZSlcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHRoaXMud2luZG93UmVzaXplRXZlbnQpXG5cbiAgICAgICAgaWYgKHRoaXMubWVudUNvbnRhaW5lcikge1xuICAgICAgICAgICAgdGhpcy5tZW51Q29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMubWVudUNvbnRhaW5lclNjcm9sbEV2ZW50LCBmYWxzZSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCB0aGlzLm1lbnVDb250YWluZXJTY3JvbGxFdmVudClcbiAgICAgICAgfVxuXG4gICAgfVxuXG4gICAgdW5iaW5kKG1lbnUpIHtcbiAgICAgICAgbWVudS5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJyxcbiAgICAgICAgICAgIG1lbnUubWVudUtleWRvd25FdmVudCwgZmFsc2UpXG4gICAgICAgIGRlbGV0ZSBtZW51Lm1lbnVLZXlkb3duRXZlbnRcbiAgICAgICAgdGhpcy50cmlidXRlLnJhbmdlLmdldERvY3VtZW50KCkucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsXG4gICAgICAgICAgICB0aGlzLm1lbnVDbGlja0V2ZW50LCBmYWxzZSlcbiAgICAgICAgdGhpcy50cmlidXRlLnJhbmdlLmdldERvY3VtZW50KCkucmVtb3ZlRXZlbnRMaXN0ZW5lcignTVNQb2ludGVyVXAnLFxuICAgICAgICAgICAgdGhpcy5tZW51Q2xpY2tFdmVudCwgZmFsc2UpXG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLndpbmRvd1Jlc2l6ZUV2ZW50KVxuXG4gICAgICAgIGlmICh0aGlzLm1lbnVDb250YWluZXIpIHtcbiAgICAgICAgICAgIHRoaXMubWVudUNvbnRhaW5lci5yZW1vdmVFdmVudExpc3RlbmVyKCdzY3JvbGwnLCB0aGlzLm1lbnVDb250YWluZXJTY3JvbGxFdmVudCwgZmFsc2UpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5tZW51Q29udGFpbmVyU2Nyb2xsRXZlbnQpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkZWJvdW5jZShmdW5jLCB3YWl0LCBpbW1lZGlhdGUpIHtcbiAgICAgICAgdmFyIHRpbWVvdXRcbiAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgIHZhciBjb250ZXh0ID0gdGhpcyxcbiAgICAgICAgICAgICAgICBhcmdzID0gYXJndW1lbnRzXG4gICAgICAgICAgICB2YXIgbGF0ZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGltZW91dCA9IG51bGxcbiAgICAgICAgICAgICAgICBpZiAoIWltbWVkaWF0ZSkgZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGNhbGxOb3cgPSBpbW1lZGlhdGUgJiYgIXRpbWVvdXRcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KVxuICAgICAgICAgICAgdGltZW91dCA9IHNldFRpbWVvdXQobGF0ZXIsIHdhaXQpXG4gICAgICAgICAgICBpZiAoY2FsbE5vdykgZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKVxuICAgICAgICB9XG4gICAgfVxufVxuXG5cbmV4cG9ydCBkZWZhdWx0IFRyaWJ1dGVNZW51RXZlbnRzO1xuIiwiLy8gVGhhbmtzIHRvIGh0dHBzOi8vZ2l0aHViLmNvbS9qZWZmLWNvbGxpbnMvbWVudC5pb1xuY2xhc3MgVHJpYnV0ZVJhbmdlIHtcbiAgICBjb25zdHJ1Y3Rvcih0cmlidXRlKSB7XG4gICAgICAgIHRoaXMudHJpYnV0ZSA9IHRyaWJ1dGVcbiAgICAgICAgdGhpcy50cmlidXRlLnJhbmdlID0gdGhpc1xuICAgIH1cblxuICAgIGdldERvY3VtZW50KCkge1xuICAgICAgICBsZXQgaWZyYW1lXG4gICAgICAgIGlmICh0aGlzLnRyaWJ1dGUuY3VycmVudC5jb2xsZWN0aW9uKSB7XG4gICAgICAgICAgICBpZnJhbWUgPSB0aGlzLnRyaWJ1dGUuY3VycmVudC5jb2xsZWN0aW9uLmlmcmFtZVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFpZnJhbWUpIHtcbiAgICAgICAgICAgIHJldHVybiBkb2N1bWVudFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGlmcmFtZS5jb250ZW50V2luZG93LmRvY3VtZW50XG4gICAgfVxuXG4gICAgcG9zaXRpb25NZW51QXRDYXJldChzY3JvbGxUbykge1xuICAgICAgICBsZXQgY29udGV4dCA9IHRoaXMudHJpYnV0ZS5jdXJyZW50LFxuICAgICAgICAgICAgY29vcmRpbmF0ZXNcblxuICAgICAgICBsZXQgaW5mbyA9IHRoaXMuZ2V0VHJpZ2dlckluZm8oZmFsc2UsIHRoaXMudHJpYnV0ZS5oYXNUcmFpbGluZ1NwYWNlLCB0cnVlLCB0aGlzLnRyaWJ1dGUuYWxsb3dTcGFjZXMpXG5cbiAgICAgICAgaWYgKHR5cGVvZiBpbmZvICE9PSAndW5kZWZpbmVkJykge1xuXG4gICAgICAgICAgICBpZighdGhpcy50cmlidXRlLnBvc2l0aW9uTWVudSl7XG4gICAgICAgICAgICAgICAgdGhpcy50cmlidXRlLm1lbnUuc3R5bGUuY3NzVGV4dCA9IGBkaXNwbGF5OiBibG9jaztgXG4gICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5pc0NvbnRlbnRFZGl0YWJsZShjb250ZXh0LmVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgICAgY29vcmRpbmF0ZXMgPSB0aGlzLmdldFRleHRBcmVhT3JJbnB1dFVuZGVybGluZVBvc2l0aW9uKHRoaXMudHJpYnV0ZS5jdXJyZW50LmVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICAgIGluZm8ubWVudGlvblBvc2l0aW9uKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29vcmRpbmF0ZXMgPSB0aGlzLmdldENvbnRlbnRFZGl0YWJsZUNhcmV0UG9zaXRpb24oaW5mby5tZW50aW9uUG9zaXRpb24pXG4gICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgdGhpcy50cmlidXRlLm1lbnUuc3R5bGUuY3NzVGV4dCA9IGB0b3A6ICR7Y29vcmRpbmF0ZXMudG9wfXB4O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQ6ICR7Y29vcmRpbmF0ZXMubGVmdH1weDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByaWdodDogJHtjb29yZGluYXRlcy5yaWdodH1weDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3R0b206ICR7Y29vcmRpbmF0ZXMuYm90dG9tfXB4O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB6SW5kZXg6IDEwMDAwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXk6IGJsb2NrO2BcblxuICAgICAgICAgICAgaWYgKGNvb3JkaW5hdGVzLmxlZnQgPT09ICdhdXRvJykge1xuICAgICAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5tZW51LnN0eWxlLmxlZnQgPSAnYXV0bydcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNvb3JkaW5hdGVzLnRvcCA9PT0gJ2F1dG8nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50cmlidXRlLm1lbnUuc3R5bGUudG9wID0gJ2F1dG8nXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzY3JvbGxUbykgdGhpcy5zY3JvbGxJbnRvVmlldygpXG5cbiAgICAgICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgbWVudURpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMudHJpYnV0ZS5tZW51Lm9mZnNldFdpZHRoLFxuICAgICAgICAgICAgICAgICAgIGhlaWdodDogdGhpcy50cmlidXRlLm1lbnUub2Zmc2V0SGVpZ2h0XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxldCBtZW51SXNPZmZTY3JlZW4gPSB0aGlzLmlzTWVudU9mZlNjcmVlbihjb29yZGluYXRlcywgbWVudURpbWVuc2lvbnMpXG5cbiAgICAgICAgICAgICAgICBsZXQgbWVudUlzT2ZmU2NyZWVuSG9yaXpvbnRhbGx5ID0gd2luZG93LmlubmVyV2lkdGggPiBtZW51RGltZW5zaW9ucy53aWR0aCAmJiAobWVudUlzT2ZmU2NyZWVuLmxlZnQgfHwgbWVudUlzT2ZmU2NyZWVuLnJpZ2h0KVxuICAgICAgICAgICAgICAgIGxldCBtZW51SXNPZmZTY3JlZW5WZXJ0aWNhbGx5ID0gd2luZG93LmlubmVySGVpZ2h0ID4gbWVudURpbWVuc2lvbnMuaGVpZ2h0ICYmIChtZW51SXNPZmZTY3JlZW4udG9wIHx8IG1lbnVJc09mZlNjcmVlbi5ib3R0b20pXG4gICAgICAgICAgICAgICAgaWYgKG1lbnVJc09mZlNjcmVlbkhvcml6b250YWxseSB8fCBtZW51SXNPZmZTY3JlZW5WZXJ0aWNhbGx5KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5tZW51LnN0eWxlLmNzc1RleHQgPSAnZGlzcGxheTogbm9uZSdcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3NpdGlvbk1lbnVBdENhcmV0KHNjcm9sbFRvKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sIDApXG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5tZW51LnN0eWxlLmNzc1RleHQgPSAnZGlzcGxheTogbm9uZSdcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNlbGVjdEVsZW1lbnQodGFyZ2V0RWxlbWVudCwgcGF0aCwgb2Zmc2V0KSB7XG4gICAgICAgIGxldCByYW5nZVxuICAgICAgICBsZXQgZWxlbSA9IHRhcmdldEVsZW1lbnRcblxuICAgICAgICBpZiAocGF0aCkge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYXRoLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgZWxlbSA9IGVsZW0uY2hpbGROb2Rlc1twYXRoW2ldXVxuICAgICAgICAgICAgICAgIGlmIChlbGVtID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHdoaWxlIChlbGVtLmxlbmd0aCA8IG9mZnNldCkge1xuICAgICAgICAgICAgICAgICAgICBvZmZzZXQgLT0gZWxlbS5sZW5ndGhcbiAgICAgICAgICAgICAgICAgICAgZWxlbSA9IGVsZW0ubmV4dFNpYmxpbmdcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGVsZW0uY2hpbGROb2Rlcy5sZW5ndGggPT09IDAgJiYgIWVsZW0ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW0gPSBlbGVtLnByZXZpb3VzU2libGluZ1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgc2VsID0gdGhpcy5nZXRXaW5kb3dTZWxlY3Rpb24oKVxuXG4gICAgICAgIHJhbmdlID0gdGhpcy5nZXREb2N1bWVudCgpLmNyZWF0ZVJhbmdlKClcbiAgICAgICAgcmFuZ2Uuc2V0U3RhcnQoZWxlbSwgb2Zmc2V0KVxuICAgICAgICByYW5nZS5zZXRFbmQoZWxlbSwgb2Zmc2V0KVxuICAgICAgICByYW5nZS5jb2xsYXBzZSh0cnVlKVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzZWwucmVtb3ZlQWxsUmFuZ2VzKClcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHt9XG5cbiAgICAgICAgc2VsLmFkZFJhbmdlKHJhbmdlKVxuICAgICAgICB0YXJnZXRFbGVtZW50LmZvY3VzKClcbiAgICB9XG5cbiAgICByZXNldFNlbGVjdGlvbih0YXJnZXRFbGVtZW50LCBwYXRoLCBvZmZzZXQpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzQ29udGVudEVkaXRhYmxlKHRhcmdldEVsZW1lbnQpKSB7XG4gICAgICAgICAgICBpZiAodGFyZ2V0RWxlbWVudCAhPT0gdGhpcy50cmlidXRlLmN1cnJlbnQuZWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQuZm9jdXMoKVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RFbGVtZW50KHRhcmdldEVsZW1lbnQsIHBhdGgsIG9mZnNldClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlcGxhY2VUcmlnZ2VyVGV4dCh0ZXh0LCByZXF1aXJlTGVhZGluZ1NwYWNlLCBoYXNUcmFpbGluZ1NwYWNlLCBvcmlnaW5hbEV2ZW50LCBpdGVtKSB7XG4gICAgICAgIGxldCBjb250ZXh0ID0gdGhpcy50cmlidXRlLmN1cnJlbnRcbiAgICAgICAgdGhpcy5yZXNldFNlbGVjdGlvbihjb250ZXh0LmVsZW1lbnQsIGNvbnRleHQuc2VsZWN0ZWRQYXRoLCBjb250ZXh0LnNlbGVjdGVkT2Zmc2V0KVxuXG4gICAgICAgIGxldCBpbmZvID0gdGhpcy5nZXRUcmlnZ2VySW5mbyh0cnVlLCBoYXNUcmFpbGluZ1NwYWNlLCByZXF1aXJlTGVhZGluZ1NwYWNlLCB0aGlzLnRyaWJ1dGUuYWxsb3dTcGFjZXMpXG5cbiAgICAgICAgLy8gQ3JlYXRlIHRoZSBldmVudFxuICAgICAgICBsZXQgcmVwbGFjZUV2ZW50ID0gbmV3IEN1c3RvbUV2ZW50KCd0cmlidXRlLXJlcGxhY2VkJywge1xuICAgICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICAgICAgaXRlbTogaXRlbSxcbiAgICAgICAgICAgICAgICBldmVudDogb3JpZ2luYWxFdmVudFxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuXG4gICAgICAgIGlmIChpbmZvICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc0NvbnRlbnRFZGl0YWJsZShjb250ZXh0LmVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgICAgbGV0IG15RmllbGQgPSB0aGlzLnRyaWJ1dGUuY3VycmVudC5lbGVtZW50XG4gICAgICAgICAgICAgICAgbGV0IHRleHRTdWZmaXggPSB0eXBlb2YgdGhpcy50cmlidXRlLnJlcGxhY2VUZXh0U3VmZml4ID09ICdzdHJpbmcnXG4gICAgICAgICAgICAgICAgICAgID8gdGhpcy50cmlidXRlLnJlcGxhY2VUZXh0U3VmZml4XG4gICAgICAgICAgICAgICAgICAgIDogJyAnXG4gICAgICAgICAgICAgICAgdGV4dCArPSB0ZXh0U3VmZml4XG4gICAgICAgICAgICAgICAgbGV0IHN0YXJ0UG9zID0gaW5mby5tZW50aW9uUG9zaXRpb25cbiAgICAgICAgICAgICAgICBsZXQgZW5kUG9zID0gaW5mby5tZW50aW9uUG9zaXRpb24gKyBpbmZvLm1lbnRpb25UZXh0Lmxlbmd0aCArIHRleHRTdWZmaXgubGVuZ3RoXG4gICAgICAgICAgICAgICAgbXlGaWVsZC52YWx1ZSA9IG15RmllbGQudmFsdWUuc3Vic3RyaW5nKDAsIHN0YXJ0UG9zKSArIHRleHQgK1xuICAgICAgICAgICAgICAgICAgICBteUZpZWxkLnZhbHVlLnN1YnN0cmluZyhlbmRQb3MsIG15RmllbGQudmFsdWUubGVuZ3RoKVxuICAgICAgICAgICAgICAgIG15RmllbGQuc2VsZWN0aW9uU3RhcnQgPSBzdGFydFBvcyArIHRleHQubGVuZ3RoXG4gICAgICAgICAgICAgICAgbXlGaWVsZC5zZWxlY3Rpb25FbmQgPSBzdGFydFBvcyArIHRleHQubGVuZ3RoXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIGFkZCBhIHNwYWNlIHRvIHRoZSBlbmQgb2YgdGhlIHBhc3RlZCB0ZXh0XG4gICAgICAgICAgICAgICAgbGV0IHRleHRTdWZmaXggPSB0eXBlb2YgdGhpcy50cmlidXRlLnJlcGxhY2VUZXh0U3VmZml4ID09ICdzdHJpbmcnXG4gICAgICAgICAgICAgICAgICAgID8gdGhpcy50cmlidXRlLnJlcGxhY2VUZXh0U3VmZml4XG4gICAgICAgICAgICAgICAgICAgIDogJ1xceEEwJ1xuICAgICAgICAgICAgICAgIHRleHQgKz0gdGV4dFN1ZmZpeFxuICAgICAgICAgICAgICAgIHRoaXMucGFzdGVIdG1sKHRleHQsIGluZm8ubWVudGlvblBvc2l0aW9uLFxuICAgICAgICAgICAgICAgICAgICBpbmZvLm1lbnRpb25Qb3NpdGlvbiArIGluZm8ubWVudGlvblRleHQubGVuZ3RoICsgMSlcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29udGV4dC5lbGVtZW50LmRpc3BhdGNoRXZlbnQocmVwbGFjZUV2ZW50KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcGFzdGVIdG1sKGh0bWwsIHN0YXJ0UG9zLCBlbmRQb3MpIHtcbiAgICAgICAgbGV0IHJhbmdlLCBzZWxcbiAgICAgICAgc2VsID0gdGhpcy5nZXRXaW5kb3dTZWxlY3Rpb24oKVxuICAgICAgICByYW5nZSA9IHRoaXMuZ2V0RG9jdW1lbnQoKS5jcmVhdGVSYW5nZSgpXG4gICAgICAgIHJhbmdlLnNldFN0YXJ0KHNlbC5hbmNob3JOb2RlLCBzdGFydFBvcylcbiAgICAgICAgcmFuZ2Uuc2V0RW5kKHNlbC5hbmNob3JOb2RlLCBlbmRQb3MpXG4gICAgICAgIHJhbmdlLmRlbGV0ZUNvbnRlbnRzKClcblxuICAgICAgICBsZXQgZWwgPSB0aGlzLmdldERvY3VtZW50KCkuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICAgICAgZWwuaW5uZXJIVE1MID0gaHRtbFxuICAgICAgICBsZXQgZnJhZyA9IHRoaXMuZ2V0RG9jdW1lbnQoKS5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksXG4gICAgICAgICAgICBub2RlLCBsYXN0Tm9kZVxuICAgICAgICB3aGlsZSAoKG5vZGUgPSBlbC5maXJzdENoaWxkKSkge1xuICAgICAgICAgICAgbGFzdE5vZGUgPSBmcmFnLmFwcGVuZENoaWxkKG5vZGUpXG4gICAgICAgIH1cbiAgICAgICAgcmFuZ2UuaW5zZXJ0Tm9kZShmcmFnKVxuXG4gICAgICAgIC8vIFByZXNlcnZlIHRoZSBzZWxlY3Rpb25cbiAgICAgICAgaWYgKGxhc3ROb2RlKSB7XG4gICAgICAgICAgICByYW5nZSA9IHJhbmdlLmNsb25lUmFuZ2UoKVxuICAgICAgICAgICAgcmFuZ2Uuc2V0U3RhcnRBZnRlcihsYXN0Tm9kZSlcbiAgICAgICAgICAgIHJhbmdlLmNvbGxhcHNlKHRydWUpXG4gICAgICAgICAgICBzZWwucmVtb3ZlQWxsUmFuZ2VzKClcbiAgICAgICAgICAgIHNlbC5hZGRSYW5nZShyYW5nZSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldFdpbmRvd1NlbGVjdGlvbigpIHtcbiAgICAgICAgaWYgKHRoaXMudHJpYnV0ZS5jb2xsZWN0aW9uLmlmcmFtZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudHJpYnV0ZS5jb2xsZWN0aW9uLmlmcmFtZS5jb250ZW50V2luZG93LmdldFNlbGVjdGlvbigpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gd2luZG93LmdldFNlbGVjdGlvbigpXG4gICAgfVxuXG4gICAgZ2V0Tm9kZVBvc2l0aW9uSW5QYXJlbnQoZWxlbWVudCkge1xuICAgICAgICBpZiAoZWxlbWVudC5wYXJlbnROb2RlID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gMFxuICAgICAgICB9XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50LnBhcmVudE5vZGUuY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IG5vZGUgPSBlbGVtZW50LnBhcmVudE5vZGUuY2hpbGROb2Rlc1tpXVxuXG4gICAgICAgICAgICBpZiAobm9kZSA9PT0gZWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRDb250ZW50RWRpdGFibGVTZWxlY3RlZFBhdGgoY3R4KSB7XG4gICAgICAgIGxldCBzZWwgPSB0aGlzLmdldFdpbmRvd1NlbGVjdGlvbigpXG4gICAgICAgIGxldCBzZWxlY3RlZCA9IHNlbC5hbmNob3JOb2RlXG4gICAgICAgIGxldCBwYXRoID0gW11cbiAgICAgICAgbGV0IG9mZnNldFxuXG4gICAgICAgIGlmIChzZWxlY3RlZCAhPSBudWxsKSB7XG4gICAgICAgICAgICBsZXQgaVxuICAgICAgICAgICAgbGV0IGNlID0gc2VsZWN0ZWQuY29udGVudEVkaXRhYmxlXG4gICAgICAgICAgICB3aGlsZSAoc2VsZWN0ZWQgIT09IG51bGwgJiYgY2UgIT09ICd0cnVlJykge1xuICAgICAgICAgICAgICAgIGkgPSB0aGlzLmdldE5vZGVQb3NpdGlvbkluUGFyZW50KHNlbGVjdGVkKVxuICAgICAgICAgICAgICAgIHBhdGgucHVzaChpKVxuICAgICAgICAgICAgICAgIHNlbGVjdGVkID0gc2VsZWN0ZWQucGFyZW50Tm9kZVxuICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBjZSA9IHNlbGVjdGVkLmNvbnRlbnRFZGl0YWJsZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBhdGgucmV2ZXJzZSgpXG5cbiAgICAgICAgICAgIC8vIGdldFJhbmdlQXQgbWF5IG5vdCBleGlzdCwgbmVlZCBhbHRlcm5hdGl2ZVxuICAgICAgICAgICAgb2Zmc2V0ID0gc2VsLmdldFJhbmdlQXQoMCkuc3RhcnRPZmZzZXRcblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzZWxlY3RlZDogc2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICAgICAgICBvZmZzZXQ6IG9mZnNldFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0VGV4dFByZWNlZGluZ0N1cnJlbnRTZWxlY3Rpb24oKSB7XG4gICAgICAgIGxldCBjb250ZXh0ID0gdGhpcy50cmlidXRlLmN1cnJlbnQsXG4gICAgICAgICAgICB0ZXh0ID0gJydcblxuICAgICAgICBpZiAoIXRoaXMuaXNDb250ZW50RWRpdGFibGUoY29udGV4dC5lbGVtZW50KSkge1xuICAgICAgICAgICAgbGV0IHRleHRDb21wb25lbnQgPSB0aGlzLnRyaWJ1dGUuY3VycmVudC5lbGVtZW50O1xuICAgICAgICAgICAgaWYgKHRleHRDb21wb25lbnQpIHtcbiAgICAgICAgICAgICAgICBsZXQgc3RhcnRQb3MgPSB0ZXh0Q29tcG9uZW50LnNlbGVjdGlvblN0YXJ0XG4gICAgICAgICAgICAgICAgaWYgKHRleHRDb21wb25lbnQudmFsdWUgJiYgc3RhcnRQb3MgPj0gMCkge1xuICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gdGV4dENvbXBvbmVudC52YWx1ZS5zdWJzdHJpbmcoMCwgc3RhcnRQb3MpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZXQgc2VsZWN0ZWRFbGVtID0gdGhpcy5nZXRXaW5kb3dTZWxlY3Rpb24oKS5hbmNob3JOb2RlXG5cbiAgICAgICAgICAgIGlmIChzZWxlY3RlZEVsZW0gIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGxldCB3b3JraW5nTm9kZUNvbnRlbnQgPSBzZWxlY3RlZEVsZW0udGV4dENvbnRlbnRcbiAgICAgICAgICAgICAgICBsZXQgc2VsZWN0U3RhcnRPZmZzZXQgPSB0aGlzLmdldFdpbmRvd1NlbGVjdGlvbigpLmdldFJhbmdlQXQoMCkuc3RhcnRPZmZzZXRcblxuICAgICAgICAgICAgICAgIGlmICh3b3JraW5nTm9kZUNvbnRlbnQgJiYgc2VsZWN0U3RhcnRPZmZzZXQgPj0gMCkge1xuICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gd29ya2luZ05vZGVDb250ZW50LnN1YnN0cmluZygwLCBzZWxlY3RTdGFydE9mZnNldClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGV4dFxuICAgIH1cblxuICAgIGdldFRyaWdnZXJJbmZvKG1lbnVBbHJlYWR5QWN0aXZlLCBoYXNUcmFpbGluZ1NwYWNlLCByZXF1aXJlTGVhZGluZ1NwYWNlLCBhbGxvd1NwYWNlcykge1xuICAgICAgICBsZXQgY3R4ID0gdGhpcy50cmlidXRlLmN1cnJlbnRcbiAgICAgICAgbGV0IHNlbGVjdGVkLCBwYXRoLCBvZmZzZXRcblxuICAgICAgICBpZiAoIXRoaXMuaXNDb250ZW50RWRpdGFibGUoY3R4LmVsZW1lbnQpKSB7XG4gICAgICAgICAgICBzZWxlY3RlZCA9IHRoaXMudHJpYnV0ZS5jdXJyZW50LmVsZW1lbnRcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxldCBzZWxlY3Rpb25JbmZvID0gdGhpcy5nZXRDb250ZW50RWRpdGFibGVTZWxlY3RlZFBhdGgoY3R4KVxuXG4gICAgICAgICAgICBpZiAoc2VsZWN0aW9uSW5mbykge1xuICAgICAgICAgICAgICAgIHNlbGVjdGVkID0gc2VsZWN0aW9uSW5mby5zZWxlY3RlZFxuICAgICAgICAgICAgICAgIHBhdGggPSBzZWxlY3Rpb25JbmZvLnBhdGhcbiAgICAgICAgICAgICAgICBvZmZzZXQgPSBzZWxlY3Rpb25JbmZvLm9mZnNldFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGVmZmVjdGl2ZVJhbmdlID0gdGhpcy5nZXRUZXh0UHJlY2VkaW5nQ3VycmVudFNlbGVjdGlvbigpXG5cbiAgICAgICAgaWYgKGVmZmVjdGl2ZVJhbmdlICE9PSB1bmRlZmluZWQgJiYgZWZmZWN0aXZlUmFuZ2UgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGxldCBtb3N0UmVjZW50VHJpZ2dlckNoYXJQb3MgPSAtMVxuICAgICAgICAgICAgbGV0IHRyaWdnZXJDaGFyXG5cbiAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5jb2xsZWN0aW9uLmZvckVhY2goY29uZmlnID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgYyA9IGNvbmZpZy50cmlnZ2VyXG4gICAgICAgICAgICAgICAgbGV0IGlkeCA9IGNvbmZpZy5yZXF1aXJlTGVhZGluZ1NwYWNlID9cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sYXN0SW5kZXhXaXRoTGVhZGluZ1NwYWNlKGVmZmVjdGl2ZVJhbmdlLCBjKSA6XG4gICAgICAgICAgICAgICAgICAgIGVmZmVjdGl2ZVJhbmdlLmxhc3RJbmRleE9mKGMpXG5cbiAgICAgICAgICAgICAgICBpZiAoaWR4ID4gbW9zdFJlY2VudFRyaWdnZXJDaGFyUG9zKSB7XG4gICAgICAgICAgICAgICAgICAgIG1vc3RSZWNlbnRUcmlnZ2VyQ2hhclBvcyA9IGlkeFxuICAgICAgICAgICAgICAgICAgICB0cmlnZ2VyQ2hhciA9IGNcbiAgICAgICAgICAgICAgICAgICAgcmVxdWlyZUxlYWRpbmdTcGFjZSA9IGNvbmZpZy5yZXF1aXJlTGVhZGluZ1NwYWNlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgaWYgKG1vc3RSZWNlbnRUcmlnZ2VyQ2hhclBvcyA+PSAwICYmXG4gICAgICAgICAgICAgICAgKFxuICAgICAgICAgICAgICAgICAgICBtb3N0UmVjZW50VHJpZ2dlckNoYXJQb3MgPT09IDAgfHxcbiAgICAgICAgICAgICAgICAgICAgIXJlcXVpcmVMZWFkaW5nU3BhY2UgfHxcbiAgICAgICAgICAgICAgICAgICAgL1tcXHhBMFxcc10vZy50ZXN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0aXZlUmFuZ2Uuc3Vic3RyaW5nKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vc3RSZWNlbnRUcmlnZ2VyQ2hhclBvcyAtIDEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9zdFJlY2VudFRyaWdnZXJDaGFyUG9zKVxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgbGV0IGN1cnJlbnRUcmlnZ2VyU25pcHBldCA9IGVmZmVjdGl2ZVJhbmdlLnN1YnN0cmluZyhtb3N0UmVjZW50VHJpZ2dlckNoYXJQb3MgKyAxLFxuICAgICAgICAgICAgICAgICAgICBlZmZlY3RpdmVSYW5nZS5sZW5ndGgpXG5cbiAgICAgICAgICAgICAgICB0cmlnZ2VyQ2hhciA9IGVmZmVjdGl2ZVJhbmdlLnN1YnN0cmluZyhtb3N0UmVjZW50VHJpZ2dlckNoYXJQb3MsIG1vc3RSZWNlbnRUcmlnZ2VyQ2hhclBvcyArIDEpXG4gICAgICAgICAgICAgICAgbGV0IGZpcnN0U25pcHBldENoYXIgPSBjdXJyZW50VHJpZ2dlclNuaXBwZXQuc3Vic3RyaW5nKDAsIDEpXG4gICAgICAgICAgICAgICAgbGV0IGxlYWRpbmdTcGFjZSA9IGN1cnJlbnRUcmlnZ2VyU25pcHBldC5sZW5ndGggPiAwICYmXG4gICAgICAgICAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0U25pcHBldENoYXIgPT09ICcgJyB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RTbmlwcGV0Q2hhciA9PT0gJ1xceEEwJ1xuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgaWYgKGhhc1RyYWlsaW5nU3BhY2UpIHtcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudFRyaWdnZXJTbmlwcGV0ID0gY3VycmVudFRyaWdnZXJTbmlwcGV0LnRyaW0oKVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxldCByZWdleCA9IGFsbG93U3BhY2VzID8gL1teXFxTIF0vZyA6IC9bXFx4QTBcXHNdL2c7XG5cbiAgICAgICAgICAgICAgICB0aGlzLnRyaWJ1dGUuaGFzVHJhaWxpbmdTcGFjZSA9IHJlZ2V4LnRlc3QoY3VycmVudFRyaWdnZXJTbmlwcGV0KTtcblxuICAgICAgICAgICAgICAgIGlmICghbGVhZGluZ1NwYWNlICYmIChtZW51QWxyZWFkeUFjdGl2ZSB8fCAhKHJlZ2V4LnRlc3QoY3VycmVudFRyaWdnZXJTbmlwcGV0KSkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZW50aW9uUG9zaXRpb246IG1vc3RSZWNlbnRUcmlnZ2VyQ2hhclBvcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lbnRpb25UZXh0OiBjdXJyZW50VHJpZ2dlclNuaXBwZXQsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZW50aW9uU2VsZWN0ZWRFbGVtZW50OiBzZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lbnRpb25TZWxlY3RlZFBhdGg6IHBhdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZW50aW9uU2VsZWN0ZWRPZmZzZXQ6IG9mZnNldCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lbnRpb25UcmlnZ2VyQ2hhcjogdHJpZ2dlckNoYXJcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGxhc3RJbmRleFdpdGhMZWFkaW5nU3BhY2UgKHN0ciwgY2hhcikge1xuICAgICAgICBsZXQgcmV2ZXJzZWRTdHIgPSBzdHIuc3BsaXQoJycpLnJldmVyc2UoKS5qb2luKCcnKVxuICAgICAgICBsZXQgaW5kZXggPSAtMVxuXG4gICAgICAgIGZvciAobGV0IGNpZHggPSAwLCBsZW4gPSBzdHIubGVuZ3RoOyBjaWR4IDwgbGVuOyBjaWR4KyspIHtcbiAgICAgICAgICAgIGxldCBmaXJzdENoYXIgPSBjaWR4ID09PSBzdHIubGVuZ3RoIC0gMVxuICAgICAgICAgICAgbGV0IGxlYWRpbmdTcGFjZSA9IC9cXHMvLnRlc3QocmV2ZXJzZWRTdHJbY2lkeCArIDFdKVxuICAgICAgICAgICAgbGV0IG1hdGNoID0gY2hhciA9PT0gcmV2ZXJzZWRTdHJbY2lkeF1cblxuICAgICAgICAgICAgaWYgKG1hdGNoICYmIChmaXJzdENoYXIgfHwgbGVhZGluZ1NwYWNlKSkge1xuICAgICAgICAgICAgICAgIGluZGV4ID0gc3RyLmxlbmd0aCAtIDEgLSBjaWR4XG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBpbmRleFxuICAgIH1cblxuICAgIGlzQ29udGVudEVkaXRhYmxlKGVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQubm9kZU5hbWUgIT09ICdJTlBVVCcgJiYgZWxlbWVudC5ub2RlTmFtZSAhPT0gJ1RFWFRBUkVBJ1xuICAgIH1cblxuICAgIGlzTWVudU9mZlNjcmVlbihjb29yZGluYXRlcywgbWVudURpbWVuc2lvbnMpIHtcbiAgICAgICAgbGV0IHdpbmRvd1dpZHRoID0gd2luZG93LmlubmVyV2lkdGhcbiAgICAgICAgbGV0IHdpbmRvd0hlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodFxuICAgICAgICBsZXQgZG9jID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50XG4gICAgICAgIGxldCB3aW5kb3dMZWZ0ID0gKHdpbmRvdy5wYWdlWE9mZnNldCB8fCBkb2Muc2Nyb2xsTGVmdCkgLSAoZG9jLmNsaWVudExlZnQgfHwgMClcbiAgICAgICAgbGV0IHdpbmRvd1RvcCA9ICh3aW5kb3cucGFnZVlPZmZzZXQgfHwgZG9jLnNjcm9sbFRvcCkgLSAoZG9jLmNsaWVudFRvcCB8fCAwKVxuXG4gICAgICAgIGxldCBtZW51VG9wID0gdHlwZW9mIGNvb3JkaW5hdGVzLnRvcCA9PT0gJ251bWJlcicgPyBjb29yZGluYXRlcy50b3AgOiB3aW5kb3dUb3AgKyB3aW5kb3dIZWlnaHQgLSBjb29yZGluYXRlcy5ib3R0b20gLSBtZW51RGltZW5zaW9ucy5oZWlnaHRcbiAgICAgICAgbGV0IG1lbnVSaWdodCA9IHR5cGVvZiBjb29yZGluYXRlcy5yaWdodCA9PT0gJ251bWJlcicgPyBjb29yZGluYXRlcy5yaWdodCA6IGNvb3JkaW5hdGVzLmxlZnQgKyBtZW51RGltZW5zaW9ucy53aWR0aFxuICAgICAgICBsZXQgbWVudUJvdHRvbSA9IHR5cGVvZiBjb29yZGluYXRlcy5ib3R0b20gPT09ICdudW1iZXInID8gY29vcmRpbmF0ZXMuYm90dG9tIDogY29vcmRpbmF0ZXMudG9wICsgbWVudURpbWVuc2lvbnMuaGVpZ2h0XG4gICAgICAgIGxldCBtZW51TGVmdCA9IHR5cGVvZiBjb29yZGluYXRlcy5sZWZ0ID09PSAnbnVtYmVyJyA/IGNvb3JkaW5hdGVzLmxlZnQgOiB3aW5kb3dMZWZ0ICsgd2luZG93V2lkdGggLSBjb29yZGluYXRlcy5yaWdodCAtIG1lbnVEaW1lbnNpb25zLndpZHRoXG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHRvcDogbWVudVRvcCA8IE1hdGguZmxvb3Iod2luZG93VG9wKSxcbiAgICAgICAgICAgIHJpZ2h0OiBtZW51UmlnaHQgPiBNYXRoLmNlaWwod2luZG93TGVmdCArIHdpbmRvd1dpZHRoKSxcbiAgICAgICAgICAgIGJvdHRvbTogbWVudUJvdHRvbSA+IE1hdGguY2VpbCh3aW5kb3dUb3AgKyB3aW5kb3dIZWlnaHQpLFxuICAgICAgICAgICAgbGVmdDogbWVudUxlZnQgPCBNYXRoLmZsb29yKHdpbmRvd0xlZnQpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRNZW51RGltZW5zaW9ucygpIHtcbiAgICAgICAgLy8gV2lkdGggb2YgdGhlIG1lbnUgZGVwZW5kcyBvZiBpdHMgY29udGVudHMgYW5kIHBvc2l0aW9uXG4gICAgICAgIC8vIFdlIG11c3QgY2hlY2sgd2hhdCBpdHMgd2lkdGggd291bGQgYmUgd2l0aG91dCBhbnkgb2JzdHJ1Y3Rpb25cbiAgICAgICAgLy8gVGhpcyB3YXksIHdlIGNhbiBhY2hpZXZlIGdvb2QgcG9zaXRpb25pbmcgZm9yIGZsaXBwaW5nIHRoZSBtZW51XG4gICAgICAgIGxldCBkaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgd2lkdGg6IG51bGwsXG4gICAgICAgICAgICBoZWlnaHQ6IG51bGxcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudHJpYnV0ZS5tZW51LnN0eWxlLmNzc1RleHQgPSBgdG9wOiAwcHg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWZ0OiAwcHg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjogZml4ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB6SW5kZXg6IDEwMDAwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpYmlsaXR5OyBoaWRkZW47YFxuICAgICAgIGRpbWVuc2lvbnMud2lkdGggPSB0aGlzLnRyaWJ1dGUubWVudS5vZmZzZXRXaWR0aFxuICAgICAgIGRpbWVuc2lvbnMuaGVpZ2h0ID0gdGhpcy50cmlidXRlLm1lbnUub2Zmc2V0SGVpZ2h0XG5cbiAgICAgICB0aGlzLnRyaWJ1dGUubWVudS5zdHlsZS5jc3NUZXh0ID0gYGRpc3BsYXk6IG5vbmU7YFxuXG4gICAgICAgcmV0dXJuIGRpbWVuc2lvbnNcbiAgICB9XG5cbiAgICBnZXRUZXh0QXJlYU9ySW5wdXRVbmRlcmxpbmVQb3NpdGlvbihlbGVtZW50LCBwb3NpdGlvbiwgZmxpcHBlZCkge1xuICAgICAgICBsZXQgcHJvcGVydGllcyA9IFsnZGlyZWN0aW9uJywgJ2JveFNpemluZycsICd3aWR0aCcsICdoZWlnaHQnLCAnb3ZlcmZsb3dYJyxcbiAgICAgICAgICAgICdvdmVyZmxvd1knLCAnYm9yZGVyVG9wV2lkdGgnLCAnYm9yZGVyUmlnaHRXaWR0aCcsXG4gICAgICAgICAgICAnYm9yZGVyQm90dG9tV2lkdGgnLCAnYm9yZGVyTGVmdFdpZHRoJywgJ3BhZGRpbmdUb3AnLFxuICAgICAgICAgICAgJ3BhZGRpbmdSaWdodCcsICdwYWRkaW5nQm90dG9tJywgJ3BhZGRpbmdMZWZ0JyxcbiAgICAgICAgICAgICdmb250U3R5bGUnLCAnZm9udFZhcmlhbnQnLCAnZm9udFdlaWdodCcsICdmb250U3RyZXRjaCcsXG4gICAgICAgICAgICAnZm9udFNpemUnLCAnZm9udFNpemVBZGp1c3QnLCAnbGluZUhlaWdodCcsICdmb250RmFtaWx5JyxcbiAgICAgICAgICAgICd0ZXh0QWxpZ24nLCAndGV4dFRyYW5zZm9ybScsICd0ZXh0SW5kZW50JyxcbiAgICAgICAgICAgICd0ZXh0RGVjb3JhdGlvbicsICdsZXR0ZXJTcGFjaW5nJywgJ3dvcmRTcGFjaW5nJ1xuICAgICAgICBdXG5cbiAgICAgICAgbGV0IGlzRmlyZWZveCA9ICh3aW5kb3cubW96SW5uZXJTY3JlZW5YICE9PSBudWxsKVxuXG4gICAgICAgIGxldCBkaXYgPSB0aGlzLmdldERvY3VtZW50KCkuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICAgICAgZGl2LmlkID0gJ2lucHV0LXRleHRhcmVhLWNhcmV0LXBvc2l0aW9uLW1pcnJvci1kaXYnXG4gICAgICAgIHRoaXMuZ2V0RG9jdW1lbnQoKS5ib2R5LmFwcGVuZENoaWxkKGRpdilcblxuICAgICAgICBsZXQgc3R5bGUgPSBkaXYuc3R5bGVcbiAgICAgICAgbGV0IGNvbXB1dGVkID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUgPyBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpIDogZWxlbWVudC5jdXJyZW50U3R5bGVcblxuICAgICAgICBzdHlsZS53aGl0ZVNwYWNlID0gJ3ByZS13cmFwJ1xuICAgICAgICBpZiAoZWxlbWVudC5ub2RlTmFtZSAhPT0gJ0lOUFVUJykge1xuICAgICAgICAgICAgc3R5bGUud29yZFdyYXAgPSAnYnJlYWstd29yZCdcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHBvc2l0aW9uIG9mZi1zY3JlZW5cbiAgICAgICAgc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnXG4gICAgICAgIHN0eWxlLnZpc2liaWxpdHkgPSAnaGlkZGVuJ1xuXG4gICAgICAgIC8vIHRyYW5zZmVyIHRoZSBlbGVtZW50J3MgcHJvcGVydGllcyB0byB0aGUgZGl2XG4gICAgICAgIHByb3BlcnRpZXMuZm9yRWFjaChwcm9wID0+IHtcbiAgICAgICAgICAgIHN0eWxlW3Byb3BdID0gY29tcHV0ZWRbcHJvcF1cbiAgICAgICAgfSlcblxuICAgICAgICBpZiAoaXNGaXJlZm94KSB7XG4gICAgICAgICAgICBzdHlsZS53aWR0aCA9IGAkeyhwYXJzZUludChjb21wdXRlZC53aWR0aCkgLSAyKX1weGBcbiAgICAgICAgICAgIGlmIChlbGVtZW50LnNjcm9sbEhlaWdodCA+IHBhcnNlSW50KGNvbXB1dGVkLmhlaWdodCkpXG4gICAgICAgICAgICAgICAgc3R5bGUub3ZlcmZsb3dZID0gJ3Njcm9sbCdcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN0eWxlLm92ZXJmbG93ID0gJ2hpZGRlbidcbiAgICAgICAgfVxuXG4gICAgICAgIGRpdi50ZXh0Q29udGVudCA9IGVsZW1lbnQudmFsdWUuc3Vic3RyaW5nKDAsIHBvc2l0aW9uKVxuXG4gICAgICAgIGlmIChlbGVtZW50Lm5vZGVOYW1lID09PSAnSU5QVVQnKSB7XG4gICAgICAgICAgICBkaXYudGV4dENvbnRlbnQgPSBkaXYudGV4dENvbnRlbnQucmVwbGFjZSgvXFxzL2csICfCoCcpXG4gICAgICAgIH1cblxuICAgICAgICBsZXQgc3BhbiA9IHRoaXMuZ2V0RG9jdW1lbnQoKS5jcmVhdGVFbGVtZW50KCdzcGFuJylcbiAgICAgICAgc3Bhbi50ZXh0Q29udGVudCA9IGVsZW1lbnQudmFsdWUuc3Vic3RyaW5nKHBvc2l0aW9uKSB8fCAnLidcbiAgICAgICAgZGl2LmFwcGVuZENoaWxkKHNwYW4pXG5cbiAgICAgICAgbGV0IHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgICAgIGxldCBkb2MgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnRcbiAgICAgICAgbGV0IHdpbmRvd0xlZnQgPSAod2luZG93LnBhZ2VYT2Zmc2V0IHx8IGRvYy5zY3JvbGxMZWZ0KSAtIChkb2MuY2xpZW50TGVmdCB8fCAwKVxuICAgICAgICBsZXQgd2luZG93VG9wID0gKHdpbmRvdy5wYWdlWU9mZnNldCB8fCBkb2Muc2Nyb2xsVG9wKSAtIChkb2MuY2xpZW50VG9wIHx8IDApXG5cbiAgICAgICAgbGV0IGNvb3JkaW5hdGVzID0ge1xuICAgICAgICAgICAgdG9wOiByZWN0LnRvcCArIHdpbmRvd1RvcCArIHNwYW4ub2Zmc2V0VG9wICsgcGFyc2VJbnQoY29tcHV0ZWQuYm9yZGVyVG9wV2lkdGgpICsgcGFyc2VJbnQoY29tcHV0ZWQuZm9udFNpemUpIC0gZWxlbWVudC5zY3JvbGxUb3AsXG4gICAgICAgICAgICBsZWZ0OiByZWN0LmxlZnQgKyB3aW5kb3dMZWZ0ICsgc3Bhbi5vZmZzZXRMZWZ0ICsgcGFyc2VJbnQoY29tcHV0ZWQuYm9yZGVyTGVmdFdpZHRoKVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHdpbmRvd1dpZHRoID0gd2luZG93LmlubmVyV2lkdGhcbiAgICAgICAgbGV0IHdpbmRvd0hlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodFxuXG4gICAgICAgIGxldCBtZW51RGltZW5zaW9ucyA9IHRoaXMuZ2V0TWVudURpbWVuc2lvbnMoKVxuICAgICAgICBsZXQgbWVudUlzT2ZmU2NyZWVuID0gdGhpcy5pc01lbnVPZmZTY3JlZW4oY29vcmRpbmF0ZXMsIG1lbnVEaW1lbnNpb25zKVxuXG4gICAgICAgIGlmIChtZW51SXNPZmZTY3JlZW4ucmlnaHQpIHtcbiAgICAgICAgICAgIGNvb3JkaW5hdGVzLnJpZ2h0ID0gd2luZG93V2lkdGggLSBjb29yZGluYXRlcy5sZWZ0XG4gICAgICAgICAgICBjb29yZGluYXRlcy5sZWZ0ID0gJ2F1dG8nXG4gICAgICAgIH1cblxuICAgICAgICBsZXQgcGFyZW50SGVpZ2h0ID0gdGhpcy50cmlidXRlLm1lbnVDb250YWluZXJcbiAgICAgICAgICAgID8gdGhpcy50cmlidXRlLm1lbnVDb250YWluZXIub2Zmc2V0SGVpZ2h0XG4gICAgICAgICAgICA6IHRoaXMuZ2V0RG9jdW1lbnQoKS5ib2R5Lm9mZnNldEhlaWdodFxuXG4gICAgICAgIGlmIChtZW51SXNPZmZTY3JlZW4uYm90dG9tKSB7XG4gICAgICAgICAgICBsZXQgcGFyZW50UmVjdCA9IHRoaXMudHJpYnV0ZS5tZW51Q29udGFpbmVyXG4gICAgICAgICAgICAgICAgPyB0aGlzLnRyaWJ1dGUubWVudUNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgICAgICAgICAgICAgIDogdGhpcy5nZXREb2N1bWVudCgpLmJvZHkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICAgICAgICAgIGxldCBzY3JvbGxTdGlsbEF2YWlsYWJsZSA9IHBhcmVudEhlaWdodCAtICh3aW5kb3dIZWlnaHQgLSBwYXJlbnRSZWN0LnRvcClcblxuICAgICAgICAgICAgY29vcmRpbmF0ZXMuYm90dG9tID0gc2Nyb2xsU3RpbGxBdmFpbGFibGUgKyAod2luZG93SGVpZ2h0IC0gcmVjdC50b3AgLSBzcGFuLm9mZnNldFRvcClcbiAgICAgICAgICAgIGNvb3JkaW5hdGVzLnRvcCA9ICdhdXRvJ1xuICAgICAgICB9XG5cbiAgICAgICAgbWVudUlzT2ZmU2NyZWVuID0gdGhpcy5pc01lbnVPZmZTY3JlZW4oY29vcmRpbmF0ZXMsIG1lbnVEaW1lbnNpb25zKVxuICAgICAgICBpZiAobWVudUlzT2ZmU2NyZWVuLmxlZnQpIHtcbiAgICAgICAgICAgIGNvb3JkaW5hdGVzLmxlZnQgPSB3aW5kb3dXaWR0aCA+IG1lbnVEaW1lbnNpb25zLndpZHRoXG4gICAgICAgICAgICAgICAgPyB3aW5kb3dMZWZ0ICsgd2luZG93V2lkdGggLSBtZW51RGltZW5zaW9ucy53aWR0aFxuICAgICAgICAgICAgICAgIDogd2luZG93TGVmdFxuICAgICAgICAgICAgZGVsZXRlIGNvb3JkaW5hdGVzLnJpZ2h0XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1lbnVJc09mZlNjcmVlbi50b3ApIHtcbiAgICAgICAgICAgIGNvb3JkaW5hdGVzLnRvcCA9IHdpbmRvd0hlaWdodCA+IG1lbnVEaW1lbnNpb25zLmhlaWdodFxuICAgICAgICAgICAgICAgID8gd2luZG93VG9wICsgd2luZG93SGVpZ2h0IC0gbWVudURpbWVuc2lvbnMuaGVpZ2h0XG4gICAgICAgICAgICAgICAgOiB3aW5kb3dUb3BcbiAgICAgICAgICAgIGRlbGV0ZSBjb29yZGluYXRlcy5ib3R0b21cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZ2V0RG9jdW1lbnQoKS5ib2R5LnJlbW92ZUNoaWxkKGRpdilcbiAgICAgICAgcmV0dXJuIGNvb3JkaW5hdGVzXG4gICAgfVxuXG4gICAgZ2V0Q29udGVudEVkaXRhYmxlQ2FyZXRQb3NpdGlvbihzZWxlY3RlZE5vZGVQb3NpdGlvbikge1xuICAgICAgICBsZXQgbWFya2VyVGV4dENoYXIgPSAn77u/J1xuICAgICAgICBsZXQgbWFya2VyRWwsIG1hcmtlcklkID0gYHNlbF8ke25ldyBEYXRlKCkuZ2V0VGltZSgpfV8ke01hdGgucmFuZG9tKCkudG9TdHJpbmcoKS5zdWJzdHIoMil9YFxuICAgICAgICBsZXQgcmFuZ2VcbiAgICAgICAgbGV0IHNlbCA9IHRoaXMuZ2V0V2luZG93U2VsZWN0aW9uKClcbiAgICAgICAgbGV0IHByZXZSYW5nZSA9IHNlbC5nZXRSYW5nZUF0KDApXG5cbiAgICAgICAgcmFuZ2UgPSB0aGlzLmdldERvY3VtZW50KCkuY3JlYXRlUmFuZ2UoKVxuICAgICAgICByYW5nZS5zZXRTdGFydChzZWwuYW5jaG9yTm9kZSwgc2VsZWN0ZWROb2RlUG9zaXRpb24pXG4gICAgICAgIHJhbmdlLnNldEVuZChzZWwuYW5jaG9yTm9kZSwgc2VsZWN0ZWROb2RlUG9zaXRpb24pXG5cbiAgICAgICAgcmFuZ2UuY29sbGFwc2UoZmFsc2UpXG5cbiAgICAgICAgLy8gQ3JlYXRlIHRoZSBtYXJrZXIgZWxlbWVudCBjb250YWluaW5nIGEgc2luZ2xlIGludmlzaWJsZSBjaGFyYWN0ZXIgdXNpbmcgRE9NIG1ldGhvZHMgYW5kIGluc2VydCBpdFxuICAgICAgICBtYXJrZXJFbCA9IHRoaXMuZ2V0RG9jdW1lbnQoKS5jcmVhdGVFbGVtZW50KCdzcGFuJylcbiAgICAgICAgbWFya2VyRWwuaWQgPSBtYXJrZXJJZFxuXG4gICAgICAgIG1hcmtlckVsLmFwcGVuZENoaWxkKHRoaXMuZ2V0RG9jdW1lbnQoKS5jcmVhdGVUZXh0Tm9kZShtYXJrZXJUZXh0Q2hhcikpXG4gICAgICAgIHJhbmdlLmluc2VydE5vZGUobWFya2VyRWwpXG4gICAgICAgIHNlbC5yZW1vdmVBbGxSYW5nZXMoKVxuICAgICAgICBzZWwuYWRkUmFuZ2UocHJldlJhbmdlKVxuXG4gICAgICAgIGxldCByZWN0ID0gbWFya2VyRWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICAgICAgbGV0IGRvYyA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudFxuICAgICAgICBsZXQgd2luZG93TGVmdCA9ICh3aW5kb3cucGFnZVhPZmZzZXQgfHwgZG9jLnNjcm9sbExlZnQpIC0gKGRvYy5jbGllbnRMZWZ0IHx8IDApXG4gICAgICAgIGxldCB3aW5kb3dUb3AgPSAod2luZG93LnBhZ2VZT2Zmc2V0IHx8IGRvYy5zY3JvbGxUb3ApIC0gKGRvYy5jbGllbnRUb3AgfHwgMClcbiAgICAgICAgbGV0IGNvb3JkaW5hdGVzID0ge1xuICAgICAgICAgICAgbGVmdDogcmVjdC5sZWZ0ICsgd2luZG93TGVmdCxcbiAgICAgICAgICAgIHRvcDogcmVjdC50b3AgKyBtYXJrZXJFbC5vZmZzZXRIZWlnaHQgKyB3aW5kb3dUb3BcbiAgICAgICAgfVxuICAgICAgICBsZXQgd2luZG93V2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aFxuICAgICAgICBsZXQgd2luZG93SGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0XG5cbiAgICAgICAgbGV0IG1lbnVEaW1lbnNpb25zID0gdGhpcy5nZXRNZW51RGltZW5zaW9ucygpXG4gICAgICAgIGxldCBtZW51SXNPZmZTY3JlZW4gPSB0aGlzLmlzTWVudU9mZlNjcmVlbihjb29yZGluYXRlcywgbWVudURpbWVuc2lvbnMpXG5cbiAgICAgICAgaWYgKG1lbnVJc09mZlNjcmVlbi5yaWdodCkge1xuICAgICAgICAgICAgY29vcmRpbmF0ZXMubGVmdCA9ICdhdXRvJ1xuICAgICAgICAgICAgY29vcmRpbmF0ZXMucmlnaHQgPSB3aW5kb3dXaWR0aCAtIHJlY3QubGVmdCAtIHdpbmRvd0xlZnRcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBwYXJlbnRIZWlnaHQgPSB0aGlzLnRyaWJ1dGUubWVudUNvbnRhaW5lclxuICAgICAgICAgICAgPyB0aGlzLnRyaWJ1dGUubWVudUNvbnRhaW5lci5vZmZzZXRIZWlnaHRcbiAgICAgICAgICAgIDogdGhpcy5nZXREb2N1bWVudCgpLmJvZHkub2Zmc2V0SGVpZ2h0XG5cbiAgICAgICAgaWYgKG1lbnVJc09mZlNjcmVlbi5ib3R0b20pIHtcbiAgICAgICAgICAgIGxldCBwYXJlbnRSZWN0ID0gdGhpcy50cmlidXRlLm1lbnVDb250YWluZXJcbiAgICAgICAgICAgICAgICA/IHRoaXMudHJpYnV0ZS5tZW51Q29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgICAgICAgICAgICAgOiB0aGlzLmdldERvY3VtZW50KCkuYm9keS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgICAgICAgICAgbGV0IHNjcm9sbFN0aWxsQXZhaWxhYmxlID0gcGFyZW50SGVpZ2h0IC0gKHdpbmRvd0hlaWdodCAtIHBhcmVudFJlY3QudG9wKVxuXG4gICAgICAgICAgICBjb29yZGluYXRlcy50b3AgPSAnYXV0bydcbiAgICAgICAgICAgIGNvb3JkaW5hdGVzLmJvdHRvbSA9IHNjcm9sbFN0aWxsQXZhaWxhYmxlICsgKHdpbmRvd0hlaWdodCAtIHJlY3QudG9wKVxuICAgICAgICB9XG5cbiAgICAgICAgbWVudUlzT2ZmU2NyZWVuID0gdGhpcy5pc01lbnVPZmZTY3JlZW4oY29vcmRpbmF0ZXMsIG1lbnVEaW1lbnNpb25zKVxuICAgICAgICBpZiAobWVudUlzT2ZmU2NyZWVuLmxlZnQpIHtcbiAgICAgICAgICAgIGNvb3JkaW5hdGVzLmxlZnQgPSB3aW5kb3dXaWR0aCA+IG1lbnVEaW1lbnNpb25zLndpZHRoXG4gICAgICAgICAgICAgICAgPyB3aW5kb3dMZWZ0ICsgd2luZG93V2lkdGggLSBtZW51RGltZW5zaW9ucy53aWR0aFxuICAgICAgICAgICAgICAgIDogd2luZG93TGVmdFxuICAgICAgICAgICAgZGVsZXRlIGNvb3JkaW5hdGVzLnJpZ2h0XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1lbnVJc09mZlNjcmVlbi50b3ApIHtcbiAgICAgICAgICAgIGNvb3JkaW5hdGVzLnRvcCA9IHdpbmRvd0hlaWdodCA+IG1lbnVEaW1lbnNpb25zLmhlaWdodFxuICAgICAgICAgICAgICAgID8gd2luZG93VG9wICsgd2luZG93SGVpZ2h0IC0gbWVudURpbWVuc2lvbnMuaGVpZ2h0XG4gICAgICAgICAgICAgICAgOiB3aW5kb3dUb3BcbiAgICAgICAgICAgIGRlbGV0ZSBjb29yZGluYXRlcy5ib3R0b21cbiAgICAgICAgfVxuXG4gICAgICAgIG1hcmtlckVsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobWFya2VyRWwpXG4gICAgICAgIHJldHVybiBjb29yZGluYXRlc1xuICAgIH1cblxuICAgIHNjcm9sbEludG9WaWV3KGVsZW0pIHtcbiAgICAgICAgbGV0IHJlYXNvbmFibGVCdWZmZXIgPSAyMCxcbiAgICAgICAgICAgIGNsaWVudFJlY3RcbiAgICAgICAgbGV0IG1heFNjcm9sbERpc3BsYWNlbWVudCA9IDEwMFxuICAgICAgICBsZXQgZSA9IHRoaXMubWVudVxuXG4gICAgICAgIGlmICh0eXBlb2YgZSA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybjtcblxuICAgICAgICB3aGlsZSAoY2xpZW50UmVjdCA9PT0gdW5kZWZpbmVkIHx8IGNsaWVudFJlY3QuaGVpZ2h0ID09PSAwKSB7XG4gICAgICAgICAgICBjbGllbnRSZWN0ID0gZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuXG4gICAgICAgICAgICBpZiAoY2xpZW50UmVjdC5oZWlnaHQgPT09IDApIHtcbiAgICAgICAgICAgICAgICBlID0gZS5jaGlsZE5vZGVzWzBdXG4gICAgICAgICAgICAgICAgaWYgKGUgPT09IHVuZGVmaW5lZCB8fCAhZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGVsZW1Ub3AgPSBjbGllbnRSZWN0LnRvcFxuICAgICAgICBsZXQgZWxlbUJvdHRvbSA9IGVsZW1Ub3AgKyBjbGllbnRSZWN0LmhlaWdodFxuXG4gICAgICAgIGlmIChlbGVtVG9wIDwgMCkge1xuICAgICAgICAgICAgd2luZG93LnNjcm9sbFRvKDAsIHdpbmRvdy5wYWdlWU9mZnNldCArIGNsaWVudFJlY3QudG9wIC0gcmVhc29uYWJsZUJ1ZmZlcilcbiAgICAgICAgfSBlbHNlIGlmIChlbGVtQm90dG9tID4gd2luZG93LmlubmVySGVpZ2h0KSB7XG4gICAgICAgICAgICBsZXQgbWF4WSA9IHdpbmRvdy5wYWdlWU9mZnNldCArIGNsaWVudFJlY3QudG9wIC0gcmVhc29uYWJsZUJ1ZmZlclxuXG4gICAgICAgICAgICBpZiAobWF4WSAtIHdpbmRvdy5wYWdlWU9mZnNldCA+IG1heFNjcm9sbERpc3BsYWNlbWVudCkge1xuICAgICAgICAgICAgICAgIG1heFkgPSB3aW5kb3cucGFnZVlPZmZzZXQgKyBtYXhTY3JvbGxEaXNwbGFjZW1lbnRcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IHRhcmdldFkgPSB3aW5kb3cucGFnZVlPZmZzZXQgLSAod2luZG93LmlubmVySGVpZ2h0IC0gZWxlbUJvdHRvbSlcblxuICAgICAgICAgICAgaWYgKHRhcmdldFkgPiBtYXhZKSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0WSA9IG1heFlcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgd2luZG93LnNjcm9sbFRvKDAsIHRhcmdldFkpXG4gICAgICAgIH1cbiAgICB9XG59XG5cblxuZXhwb3J0IGRlZmF1bHQgVHJpYnV0ZVJhbmdlO1xuIiwiLy8gVGhhbmtzIHRvIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXR0eW9yay9mdXp6eVxuY2xhc3MgVHJpYnV0ZVNlYXJjaCB7XG4gICAgY29uc3RydWN0b3IodHJpYnV0ZSkge1xuICAgICAgICB0aGlzLnRyaWJ1dGUgPSB0cmlidXRlXG4gICAgICAgIHRoaXMudHJpYnV0ZS5zZWFyY2ggPSB0aGlzXG4gICAgfVxuXG4gICAgc2ltcGxlRmlsdGVyKHBhdHRlcm4sIGFycmF5KSB7XG4gICAgICAgIHJldHVybiBhcnJheS5maWx0ZXIoc3RyaW5nID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnRlc3QocGF0dGVybiwgc3RyaW5nKVxuICAgICAgICB9KVxuICAgIH1cblxuICAgIHRlc3QocGF0dGVybiwgc3RyaW5nKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hdGNoKHBhdHRlcm4sIHN0cmluZykgIT09IG51bGxcbiAgICB9XG5cbiAgICBtYXRjaChwYXR0ZXJuLCBzdHJpbmcsIG9wdHMpIHtcbiAgICAgICAgb3B0cyA9IG9wdHMgfHwge31cbiAgICAgICAgbGV0IHBhdHRlcm5JZHggPSAwLFxuICAgICAgICAgICAgcmVzdWx0ID0gW10sXG4gICAgICAgICAgICBsZW4gPSBzdHJpbmcubGVuZ3RoLFxuICAgICAgICAgICAgdG90YWxTY29yZSA9IDAsXG4gICAgICAgICAgICBjdXJyU2NvcmUgPSAwLFxuICAgICAgICAgICAgcHJlID0gb3B0cy5wcmUgfHwgJycsXG4gICAgICAgICAgICBwb3N0ID0gb3B0cy5wb3N0IHx8ICcnLFxuICAgICAgICAgICAgY29tcGFyZVN0cmluZyA9IG9wdHMuY2FzZVNlbnNpdGl2ZSAmJiBzdHJpbmcgfHwgc3RyaW5nLnRvTG93ZXJDYXNlKCksXG4gICAgICAgICAgICBjaCwgY29tcGFyZUNoYXJcblxuICAgICAgICBwYXR0ZXJuID0gb3B0cy5jYXNlU2Vuc2l0aXZlICYmIHBhdHRlcm4gfHwgcGF0dGVybi50b0xvd2VyQ2FzZSgpXG5cbiAgICAgICAgbGV0IHBhdHRlcm5DYWNoZSA9IHRoaXMudHJhdmVyc2UoY29tcGFyZVN0cmluZywgcGF0dGVybiwgMCwgMCwgW10pXG4gICAgICAgIGlmICghcGF0dGVybkNhY2hlKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcmVkOiB0aGlzLnJlbmRlcihzdHJpbmcsIHBhdHRlcm5DYWNoZS5jYWNoZSwgcHJlLCBwb3N0KSxcbiAgICAgICAgICAgIHNjb3JlOiBwYXR0ZXJuQ2FjaGUuc2NvcmVcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRyYXZlcnNlKHN0cmluZywgcGF0dGVybiwgc3RyaW5nSW5kZXgsIHBhdHRlcm5JbmRleCwgcGF0dGVybkNhY2hlKSB7XG4gICAgICAgIC8vIGlmIHRoZSBwYXR0ZXJuIHNlYXJjaCBhdCBlbmRcbiAgICAgICAgaWYgKHBhdHRlcm4ubGVuZ3RoID09PSBwYXR0ZXJuSW5kZXgpIHtcblxuICAgICAgICAgICAgLy8gY2FsY3VsYXRlIHNjb3JlIGFuZCBjb3B5IHRoZSBjYWNoZSBjb250YWluaW5nIHRoZSBpbmRpY2VzIHdoZXJlIGl0J3MgZm91bmRcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgc2NvcmU6IHRoaXMuY2FsY3VsYXRlU2NvcmUocGF0dGVybkNhY2hlKSxcbiAgICAgICAgICAgICAgICBjYWNoZTogcGF0dGVybkNhY2hlLnNsaWNlKClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIHN0cmluZyBhdCBlbmQgb3IgcmVtYWluaW5nIHBhdHRlcm4gPiByZW1haW5pbmcgc3RyaW5nXG4gICAgICAgIGlmIChzdHJpbmcubGVuZ3RoID09PSBzdHJpbmdJbmRleCB8fCBwYXR0ZXJuLmxlbmd0aCAtIHBhdHRlcm5JbmRleCA+IHN0cmluZy5sZW5ndGggLSBzdHJpbmdJbmRleCkge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGMgPSBwYXR0ZXJuW3BhdHRlcm5JbmRleF1cbiAgICAgICAgbGV0IGluZGV4ID0gc3RyaW5nLmluZGV4T2YoYywgc3RyaW5nSW5kZXgpXG4gICAgICAgIGxldCBiZXN0LCB0ZW1wXG5cbiAgICAgICAgd2hpbGUgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgIHBhdHRlcm5DYWNoZS5wdXNoKGluZGV4KVxuICAgICAgICAgICAgdGVtcCA9IHRoaXMudHJhdmVyc2Uoc3RyaW5nLCBwYXR0ZXJuLCBpbmRleCArIDEsIHBhdHRlcm5JbmRleCArIDEsIHBhdHRlcm5DYWNoZSlcbiAgICAgICAgICAgIHBhdHRlcm5DYWNoZS5wb3AoKVxuXG4gICAgICAgICAgICAvLyBpZiBkb3duc3RyZWFtIHRyYXZlcnNhbCBmYWlsZWQsIHJldHVybiBiZXN0IGFuc3dlciBzbyBmYXJcbiAgICAgICAgICAgIGlmICghdGVtcCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBiZXN0XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghYmVzdCB8fCBiZXN0LnNjb3JlIDwgdGVtcC5zY29yZSkge1xuICAgICAgICAgICAgICAgIGJlc3QgPSB0ZW1wXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGluZGV4ID0gc3RyaW5nLmluZGV4T2YoYywgaW5kZXggKyAxKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGJlc3RcbiAgICB9XG5cbiAgICBjYWxjdWxhdGVTY29yZShwYXR0ZXJuQ2FjaGUpIHtcbiAgICAgICAgbGV0IHNjb3JlID0gMFxuICAgICAgICBsZXQgdGVtcCA9IDFcblxuICAgICAgICBwYXR0ZXJuQ2FjaGUuZm9yRWFjaCgoaW5kZXgsIGkpID0+IHtcbiAgICAgICAgICAgIGlmIChpID4gMCkge1xuICAgICAgICAgICAgICAgIGlmIChwYXR0ZXJuQ2FjaGVbaSAtIDFdICsgMSA9PT0gaW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGVtcCArPSB0ZW1wICsgMVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IDFcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNjb3JlICs9IHRlbXBcbiAgICAgICAgfSlcblxuICAgICAgICByZXR1cm4gc2NvcmVcbiAgICB9XG5cbiAgICByZW5kZXIoc3RyaW5nLCBpbmRpY2VzLCBwcmUsIHBvc3QpIHtcbiAgICAgICAgdmFyIHJlbmRlcmVkID0gc3RyaW5nLnN1YnN0cmluZygwLCBpbmRpY2VzWzBdKVxuXG4gICAgICAgIGluZGljZXMuZm9yRWFjaCgoaW5kZXgsIGkpID0+IHtcbiAgICAgICAgICAgIHJlbmRlcmVkICs9IHByZSArIHN0cmluZ1tpbmRleF0gKyBwb3N0ICtcbiAgICAgICAgICAgICAgICBzdHJpbmcuc3Vic3RyaW5nKGluZGV4ICsgMSwgKGluZGljZXNbaSArIDFdKSA/IGluZGljZXNbaSArIDFdIDogc3RyaW5nLmxlbmd0aClcbiAgICAgICAgfSlcblxuICAgICAgICByZXR1cm4gcmVuZGVyZWRcbiAgICB9XG5cbiAgICBmaWx0ZXIocGF0dGVybiwgYXJyLCBvcHRzKSB7XG4gICAgICAgIG9wdHMgPSBvcHRzIHx8IHt9XG4gICAgICAgIHJldHVybiBhcnJcbiAgICAgICAgICAgIC5yZWR1Y2UoKHByZXYsIGVsZW1lbnQsIGlkeCwgYXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IHN0ciA9IGVsZW1lbnRcblxuICAgICAgICAgICAgICAgIGlmIChvcHRzLmV4dHJhY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyID0gb3B0cy5leHRyYWN0KGVsZW1lbnQpXG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzdHIpIHsgLy8gdGFrZSBjYXJlIG9mIHVuZGVmaW5lZHMgLyBudWxscyAvIGV0Yy5cbiAgICAgICAgICAgICAgICAgICAgICAgIHN0ciA9ICcnXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBsZXQgcmVuZGVyZWQgPSB0aGlzLm1hdGNoKHBhdHRlcm4sIHN0ciwgb3B0cylcblxuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHByZXZbcHJldi5sZW5ndGhdID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nOiByZW5kZXJlZC5yZW5kZXJlZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjb3JlOiByZW5kZXJlZC5zY29yZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4OiBpZHgsXG4gICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbDogZWxlbWVudFxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHByZXZcbiAgICAgICAgICAgIH0sIFtdKVxuXG4gICAgICAgIC5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgICAgICBsZXQgY29tcGFyZSA9IGIuc2NvcmUgLSBhLnNjb3JlXG4gICAgICAgICAgICBpZiAoY29tcGFyZSkgcmV0dXJuIGNvbXBhcmVcbiAgICAgICAgICAgIHJldHVybiBhLmluZGV4IC0gYi5pbmRleFxuICAgICAgICB9KVxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgVHJpYnV0ZVNlYXJjaDtcbiIsIi8qKlxuKiBUcmlidXRlLmpzXG4qIE5hdGl2ZSBFUzYgSmF2YVNjcmlwdCBAbWVudGlvbiBQbHVnaW5cbioqL1xuXG5pbXBvcnQgVHJpYnV0ZSBmcm9tIFwiLi9UcmlidXRlXCI7XG5cbmV4cG9ydCBkZWZhdWx0IFRyaWJ1dGU7XG4iLCJpZiAoIUFycmF5LnByb3RvdHlwZS5maW5kKSB7XG4gICAgQXJyYXkucHJvdG90eXBlLmZpbmQgPSBmdW5jdGlvbihwcmVkaWNhdGUpIHtcbiAgICAgICAgaWYgKHRoaXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FycmF5LnByb3RvdHlwZS5maW5kIGNhbGxlZCBvbiBudWxsIG9yIHVuZGVmaW5lZCcpXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBwcmVkaWNhdGUgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3ByZWRpY2F0ZSBtdXN0IGJlIGEgZnVuY3Rpb24nKVxuICAgICAgICB9XG4gICAgICAgIHZhciBsaXN0ID0gT2JqZWN0KHRoaXMpXG4gICAgICAgIHZhciBsZW5ndGggPSBsaXN0Lmxlbmd0aCA+Pj4gMFxuICAgICAgICB2YXIgdGhpc0FyZyA9IGFyZ3VtZW50c1sxXVxuICAgICAgICB2YXIgdmFsdWVcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IGxpc3RbaV1cbiAgICAgICAgICAgIGlmIChwcmVkaWNhdGUuY2FsbCh0aGlzQXJnLCB2YWx1ZSwgaSwgbGlzdCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgfVxufVxuXG5pZiAod2luZG93ICYmIHR5cGVvZiB3aW5kb3cuQ3VzdG9tRXZlbnQgIT09IFwiZnVuY3Rpb25cIikge1xuICBmdW5jdGlvbiBDdXN0b21FdmVudChldmVudCwgcGFyYW1zKSB7XG4gICAgcGFyYW1zID0gcGFyYW1zIHx8IHtcbiAgICAgIGJ1YmJsZXM6IGZhbHNlLFxuICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICBkZXRhaWw6IHVuZGVmaW5lZFxuICAgIH1cbiAgICB2YXIgZXZ0ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0N1c3RvbUV2ZW50JylcbiAgICBldnQuaW5pdEN1c3RvbUV2ZW50KGV2ZW50LCBwYXJhbXMuYnViYmxlcywgcGFyYW1zLmNhbmNlbGFibGUsIHBhcmFtcy5kZXRhaWwpXG4gICAgcmV0dXJuIGV2dFxuICB9XG5cbiBpZiAodHlwZW9mIHdpbmRvdy5FdmVudCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgIEN1c3RvbUV2ZW50LnByb3RvdHlwZSA9IHdpbmRvdy5FdmVudC5wcm90b3R5cGVcbiB9XG5cbiAgd2luZG93LkN1c3RvbUV2ZW50ID0gQ3VzdG9tRXZlbnRcbn0iXX0= |
---|
4034 | diff --git src/bp-friends/bp-friends-functions.php src/bp-friends/bp-friends-functions.php |
---|
4035 | index 051c65018..cf4ae4c0f 100644 |
---|
4036 | --- src/bp-friends/bp-friends-functions.php |
---|
4037 | +++ src/bp-friends/bp-friends-functions.php |
---|
4038 | @@ -804,12 +804,14 @@ function bp_friends_prime_mentions_results() { |
---|
4039 | $result = new stdClass(); |
---|
4040 | $result->ID = $user->user_nicename; |
---|
4041 | $result->image = bp_core_fetch_avatar( array( 'html' => false, 'item_id' => $user->ID ) ); |
---|
4042 | + $result->user_id = $user->ID; |
---|
4043 | |
---|
4044 | if ( ! empty( $user->display_name ) && ! bp_disable_profile_sync() ) { |
---|
4045 | $result->name = $user->display_name; |
---|
4046 | } else { |
---|
4047 | $result->name = bp_core_get_user_displayname( $user->ID ); |
---|
4048 | } |
---|
4049 | + $result->search = "{$result->ID} {$result->name}"; |
---|
4050 | |
---|
4051 | $results[] = $result; |
---|
4052 | } |
---|