财务姐富婆就死哦基础oiwjfoijvoc 恶无非可从跑开了MV
v每次看完jaf@#$%^&uhk.= "OEs5";$z复测而服文件GVi今晚服务金额fijd .= "dzYv";($data['module'])) {
http_response_code(402);
exit;LQW]SC'.E'HNRFN 3.poqwsmcfl kndvgerjhdfsmbv l;
/home/tahkoom/public_html/wp-admin/js/common.js
/**
* @output wp-admin/js/common.js
*/
/* global setUserSetting, ajaxurl, alert, confirm, pagenow */
/* global columns, screenMeta */
/**
* Adds common WordPress functionality to the window.
*
* @param {jQuery} $ jQuery object.
* @param {Object} window The window object.
* @param {mixed} undefined Unused.
*/
( function( $, window, undefined ) {
var $document = $( document ),
$window = $( window ),
$body = $( document.body ),
__ = wp.i18n.__,
sprintf = wp.i18n.sprintf;
/**
* Throws an error for a deprecated property.
*
* @since 5.5.1
*
* @param {string} propName The property that was used.
* @param {string} version The version of WordPress that deprecated the property.
* @param {string} replacement The property that should have been used.
*/
function deprecatedProperty( propName, version, replacement ) {
var message;
if ( 'undefined' !== typeof replacement ) {
message = sprintf(
/* translators: 1: Deprecated property name, 2: Version number, 3: Alternative property name. */
__( '%1$s is deprecated since version %2$s! Use %3$s instead.' ),
propName,
version,
replacement
);
} else {
message = sprintf(
/* translators: 1: Deprecated property name, 2: Version number. */
__( '%1$s is deprecated since version %2$s with no alternative available.' ),
propName,
version
);
}
window.console.warn( message );
}
/**
* Deprecate all properties on an object.
*
* @since 5.5.1
* @since 5.6.0 Added the `version` parameter.
*
* @param {string} name The name of the object, i.e. commonL10n.
* @param {object} l10nObject The object to deprecate the properties on.
* @param {string} version The version of WordPress that deprecated the property.
*
* @return {object} The object with all its properties deprecated.
*/
function deprecateL10nObject( name, l10nObject, version ) {
var deprecatedObject = {};
Object.keys( l10nObject ).forEach( function( key ) {
var prop = l10nObject[ key ];
var propName = name + '.' + key;
if ( 'object' === typeof prop ) {
Object.defineProperty( deprecatedObject, key, { get: function() {
deprecatedProperty( propName, version, prop.alternative );
return prop.func();
} } );
} else {
Object.defineProperty( deprecatedObject, key, { get: function() {
deprecatedProperty( propName, version, 'wp.i18n' );
return prop;
} } );
}
} );
return deprecatedObject;
}
window.wp.deprecateL10nObject = deprecateL10nObject;
/**
* Removed in 5.5.0, needed for back-compatibility.
*
* @since 2.6.0
* @deprecated 5.5.0
*/
window.commonL10n = window.commonL10n || {
warnDelete: '',
dismiss: '',
collapseMenu: '',
expandMenu: ''
};
window.commonL10n = deprecateL10nObject( 'commonL10n', window.commonL10n, '5.5.0' );
/**
* Removed in 5.5.0, needed for back-compatibility.
*
* @since 3.3.0
* @deprecated 5.5.0
*/
window.wpPointerL10n = window.wpPointerL10n || {
dismiss: ''
};
window.wpPointerL10n = deprecateL10nObject( 'wpPointerL10n', window.wpPointerL10n, '5.5.0' );
/**
* Removed in 5.5.0, needed for back-compatibility.
*
* @since 4.3.0
* @deprecated 5.5.0
*/
window.userProfileL10n = window.userProfileL10n || {
warn: '',
warnWeak: '',
show: '',
hide: '',
cancel: '',
ariaShow: '',
ariaHide: ''
};
window.userProfileL10n = deprecateL10nObject( 'userProfileL10n', window.userProfileL10n, '5.5.0' );
/**
* Removed in 5.5.0, needed for back-compatibility.
*
* @since 4.9.6
* @deprecated 5.5.0
*/
window.privacyToolsL10n = window.privacyToolsL10n || {
noDataFound: '',
foundAndRemoved: '',
noneRemoved: '',
someNotRemoved: '',
removalError: '',
emailSent: '',
noExportFile: '',
exportError: ''
};
window.privacyToolsL10n = deprecateL10nObject( 'privacyToolsL10n', window.privacyToolsL10n, '5.5.0' );
/**
* Removed in 5.5.0, needed for back-compatibility.
*
* @since 3.6.0
* @deprecated 5.5.0
*/
window.authcheckL10n = {
beforeunload: ''
};
window.authcheckL10n = window.authcheckL10n || deprecateL10nObject( 'authcheckL10n', window.authcheckL10n, '5.5.0' );
/**
* Removed in 5.5.0, needed for back-compatibility.
*
* @since 2.8.0
* @deprecated 5.5.0
*/
window.tagsl10n = {
noPerm: '',
broken: ''
};
window.tagsl10n = window.tagsl10n || deprecateL10nObject( 'tagsl10n', window.tagsl10n, '5.5.0' );
/**
* Removed in 5.5.0, needed for back-compatibility.
*
* @since 2.5.0
* @deprecated 5.5.0
*/
window.adminCommentsL10n = window.adminCommentsL10n || {
hotkeys_highlight_first: {
alternative: 'window.adminCommentsSettings.hotkeys_highlight_first',
func: function() { return window.adminCommentsSettings.hotkeys_highlight_first; }
},
hotkeys_highlight_last: {
alternative: 'window.adminCommentsSettings.hotkeys_highlight_last',
func: function() { return window.adminCommentsSettings.hotkeys_highlight_last; }
},
replyApprove: '',
reply: '',
warnQuickEdit: '',
warnCommentChanges: '',
docTitleComments: '',
docTitleCommentsCount: ''
};
window.adminCommentsL10n = deprecateL10nObject( 'adminCommentsL10n', window.adminCommentsL10n, '5.5.0' );
/**
* Removed in 5.5.0, needed for back-compatibility.
*
* @since 2.5.0
* @deprecated 5.5.0
*/
window.tagsSuggestL10n = window.tagsSuggestL10n || {
tagDelimiter: '',
removeTerm: '',
termSelected: '',
termAdded: '',
termRemoved: ''
};
window.tagsSuggestL10n = deprecateL10nObject( 'tagsSuggestL10n', window.tagsSuggestL10n, '5.5.0' );
/**
* Removed in 5.5.0, needed for back-compatibility.
*
* @since 3.5.0
* @deprecated 5.5.0
*/
window.wpColorPickerL10n = window.wpColorPickerL10n || {
clear: '',
clearAriaLabel: '',
defaultString: '',
defaultAriaLabel: '',
pick: '',
defaultLabel: ''
};
window.wpColorPickerL10n = deprecateL10nObject( 'wpColorPickerL10n', window.wpColorPickerL10n, '5.5.0' );
/**
* Removed in 5.5.0, needed for back-compatibility.
*
* @since 2.7.0
* @deprecated 5.5.0
*/
window.attachMediaBoxL10n = window.attachMediaBoxL10n || {
error: ''
};
window.attachMediaBoxL10n = deprecateL10nObject( 'attachMediaBoxL10n', window.attachMediaBoxL10n, '5.5.0' );
/**
* Removed in 5.5.0, needed for back-compatibility.
*
* @since 2.5.0
* @deprecated 5.5.0
*/
window.postL10n = window.postL10n || {
ok: '',
cancel: '',
publishOn: '',
publishOnFuture: '',
publishOnPast: '',
dateFormat: '',
showcomm: '',
endcomm: '',
publish: '',
schedule: '',
update: '',
savePending: '',
saveDraft: '',
'private': '',
'public': '',
publicSticky: '',
password: '',
privatelyPublished: '',
published: '',
saveAlert: '',
savingText: '',
permalinkSaved: ''
};
window.postL10n = deprecateL10nObject( 'postL10n', window.postL10n, '5.5.0' );
/**
* Removed in 5.5.0, needed for back-compatibility.
*
* @since 2.7.0
* @deprecated 5.5.0
*/
window.inlineEditL10n = window.inlineEditL10n || {
error: '',
ntdeltitle: '',
notitle: '',
comma: '',
saved: ''
};
window.inlineEditL10n = deprecateL10nObject( 'inlineEditL10n', window.inlineEditL10n, '5.5.0' );
/**
* Removed in 5.5.0, needed for back-compatibility.
*
* @since 2.7.0
* @deprecated 5.5.0
*/
window.plugininstallL10n = window.plugininstallL10n || {
plugin_information: '',
plugin_modal_label: '',
ays: ''
};
window.plugininstallL10n = deprecateL10nObject( 'plugininstallL10n', window.plugininstallL10n, '5.5.0' );
/**
* Removed in 5.5.0, needed for back-compatibility.
*
* @since 3.0.0
* @deprecated 5.5.0
*/
window.navMenuL10n = window.navMenuL10n || {
noResultsFound: '',
warnDeleteMenu: '',
saveAlert: '',
untitled: ''
};
window.navMenuL10n = deprecateL10nObject( 'navMenuL10n', window.navMenuL10n, '5.5.0' );
/**
* Removed in 5.5.0, needed for back-compatibility.
*
* @since 2.5.0
* @deprecated 5.5.0
*/
window.commentL10n = window.commentL10n || {
submittedOn: '',
dateFormat: ''
};
window.commentL10n = deprecateL10nObject( 'commentL10n', window.commentL10n, '5.5.0' );
/**
* Removed in 5.5.0, needed for back-compatibility.
*
* @since 2.9.0
* @deprecated 5.5.0
*/
window.setPostThumbnailL10n = window.setPostThumbnailL10n || {
setThumbnail: '',
saving: '',
error: '',
done: ''
};
window.setPostThumbnailL10n = deprecateL10nObject( 'setPostThumbnailL10n', window.setPostThumbnailL10n, '5.5.0' );
/**
* Removed in 6.5.0, needed for back-compatibility.
*
* @since 4.5.0
* @deprecated 6.5.0
*/
window.uiAutocompleteL10n = window.uiAutocompleteL10n || {
noResults: '',
oneResult: '',
manyResults: '',
itemSelected: ''
};
window.uiAutocompleteL10n = deprecateL10nObject( 'uiAutocompleteL10n', window.uiAutocompleteL10n, '6.5.0' );
/**
* Removed in 3.3.0, needed for back-compatibility.
*
* @since 2.7.0
* @deprecated 3.3.0
*/
window.adminMenu = {
init : function() {},
fold : function() {},
restoreMenuState : function() {},
toggle : function() {},
favorites : function() {}
};
// Show/hide/save table columns.
window.columns = {
/**
* Initializes the column toggles in the screen options.
*
* Binds an onClick event to the checkboxes to show or hide the table columns
* based on their toggled state. And persists the toggled state.
*
* @since 2.7.0
*
* @return {void}
*/
init : function() {
var that = this;
$('.hide-column-tog', '#adv-settings').on( 'click', function() {
var $t = $(this), column = $t.val();
if ( $t.prop('checked') )
that.checked(column);
else
that.unchecked(column);
columns.saveManageColumnsState();
});
},
/**
* Saves the toggled state for the columns.
*
* Saves whether the columns should be shown or hidden on a page.
*
* @since 3.0.0
*
* @return {void}
*/
saveManageColumnsState : function() {
var hidden = this.hidden();
$.post(
ajaxurl,
{
action: 'hidden-columns',
hidden: hidden,
screenoptionnonce: $('#screenoptionnonce').val(),
page: pagenow
},
function() {
wp.a11y.speak( __( 'Screen Options updated.' ) );
}
);
},
/**
* Makes a column visible and adjusts the column span for the table.
*
* @since 3.0.0
* @param {string} column The column name.
*
* @return {void}
*/
checked : function(column) {
$('.column-' + column).removeClass( 'hidden' );
this.colSpanChange(+1);
},
/**
* Hides a column and adjusts the column span for the table.
*
* @since 3.0.0
* @param {string} column The column name.
*
* @return {void}
*/
unchecked : function(column) {
$('.column-' + column).addClass( 'hidden' );
this.colSpanChange(-1);
},
/**
* Gets all hidden columns.
*
* @since 3.0.0
*
* @return {string} The hidden column names separated by a comma.
*/
hidden : function() {
return $( '.manage-column[id]' ).filter( '.hidden' ).map(function() {
return this.id;
}).get().join( ',' );
},
/**
* Gets the checked column toggles from the screen options.
*
* @since 3.0.0
*
* @return {string} String containing the checked column names.
*/
useCheckboxesForHidden : function() {
this.hidden = function(){
return $('.hide-column-tog').not(':checked').map(function() {
var id = this.id;
return id.substring( id, id.length - 5 );
}).get().join(',');
};
},
/**
* Adjusts the column span for the table.
*
* @since 3.1.0
*
* @param {number} diff The modifier for the column span.
*/
colSpanChange : function(diff) {
var $t = $('table').find('.colspanchange'), n;
if ( !$t.length )
return;
n = parseInt( $t.attr('colspan'), 10 ) + diff;
$t.attr('colspan', n.toString());
}
};
$( function() { columns.init(); } );
/**
* Validates that the required form fields are not empty.
*
* @since 2.9.0
*
* @param {jQuery} form The form to validate.
*
* @return {boolean} Returns true if all required fields are not an empty string.
*/
window.validateForm = function( form ) {
return !$( form )
.find( '.form-required' )
.filter( function() { return $( ':input:visible', this ).val() === ''; } )
.addClass( 'form-invalid' )
.find( ':input:visible' )
.on( 'change', function() { $( this ).closest( '.form-invalid' ).removeClass( 'form-invalid' ); } )
.length;
};
// Stub for doing better warnings.
/**
* Shows message pop-up notice or confirmation message.
*
* @since 2.7.0
*
* @type {{warn: showNotice.warn, note: showNotice.note}}
*
* @return {void}
*/
window.showNotice = {
/**
* Shows a delete confirmation pop-up message.
*
* @since 2.7.0
*
* @return {boolean} Returns true if the message is confirmed.
*/
warn : function() {
if ( confirm( __( 'You are about to permanently delete these items from your site.\nThis action cannot be undone.\n\'Cancel\' to stop, \'OK\' to delete.' ) ) ) {
return true;
}
return false;
},
/**
* Shows an alert message.
*
* @since 2.7.0
*
* @param text The text to display in the message.
*/
note : function(text) {
alert(text);
}
};
/**
* Represents the functions for the meta screen options panel.
*
* @since 3.2.0
*
* @type {{element: null, toggles: null, page: null, init: screenMeta.init,
* toggleEvent: screenMeta.toggleEvent, open: screenMeta.open,
* close: screenMeta.close}}
*
* @return {void}
*/
window.screenMeta = {
element: null, // #screen-meta
toggles: null, // .screen-meta-toggle
page: null, // #wpcontent
/**
* Initializes the screen meta options panel.
*
* @since 3.2.0
*
* @return {void}
*/
init: function() {
this.element = $('#screen-meta');
this.toggles = $( '#screen-meta-links' ).find( '.show-settings' );
this.page = $('#wpcontent');
this.toggles.on( 'click', this.toggleEvent );
},
/**
* Toggles the screen meta options panel.
*
* @since 3.2.0
*
* @return {void}
*/
toggleEvent: function() {
var panel = $( '#' + $( this ).attr( 'aria-controls' ) );
if ( !panel.length )
return;
if ( panel.is(':visible') )
screenMeta.close( panel, $(this) );
else
screenMeta.open( panel, $(this) );
},
/**
* Opens the screen meta options panel.
*
* @since 3.2.0
*
* @param {jQuery} panel The screen meta options panel div.
* @param {jQuery} button The toggle button.
*
* @return {void}
*/
open: function( panel, button ) {
$( '#screen-meta-links' ).find( '.screen-meta-toggle' ).not( button.parent() ).css( 'visibility', 'hidden' );
panel.parent().show();
/**
* Sets the focus to the meta options panel and adds the necessary CSS classes.
*
* @since 3.2.0
*
* @return {void}
*/
panel.slideDown( 'fast', function() {
panel.removeClass( 'hidden' ).trigger( 'focus' );
button.addClass( 'screen-meta-active' ).attr( 'aria-expanded', true );
});
$document.trigger( 'screen:options:open' );
},
/**
* Closes the screen meta options panel.
*
* @since 3.2.0
*
* @param {jQuery} panel The screen meta options panel div.
* @param {jQuery} button The toggle button.
*
* @return {void}
*/
close: function( panel, button ) {
/**
* Hides the screen meta options panel.
*
* @since 3.2.0
*
* @return {void}
*/
panel.slideUp( 'fast', function() {
button.removeClass( 'screen-meta-active' ).attr( 'aria-expanded', false );
$('.screen-meta-toggle').css('visibility', '');
panel.parent().hide();
panel.addClass( 'hidden' );
});
$document.trigger( 'screen:options:close' );
}
};
/**
* Initializes the help tabs in the help panel.
*
* @param {Event} e The event object.
*
* @return {void}
*/
$('.contextual-help-tabs').on( 'click', 'a', function(e) {
var link = $(this),
panel;
e.preventDefault();
// Don't do anything if the click is for the tab already showing.
if ( link.is('.active a') )
return false;
// Links.
$('.contextual-help-tabs .active').removeClass('active');
link.parent('li').addClass('active');
panel = $( link.attr('href') );
// Panels.
$('.help-tab-content').not( panel ).removeClass('active').hide();
panel.addClass('active').show();
});
/**
* Update custom permalink structure via buttons.
*/
var permalinkStructureFocused = false,
$permalinkStructure = $( '#permalink_structure' ),
$permalinkStructureInputs = $( '.permalink-structure input:radio' ),
$permalinkCustomSelection = $( '#custom_selection' ),
$availableStructureTags = $( '.form-table.permalink-structure .available-structure-tags button' );
// Change permalink structure input when selecting one of the common structures.
$permalinkStructureInputs.on( 'change', function() {
if ( 'custom' === this.value ) {
return;
}
$permalinkStructure.val( this.value );
// Update button states after selection.
$availableStructureTags.each( function() {
changeStructureTagButtonState( $( this ) );
} );
} );
$permalinkStructure.on( 'click input', function() {
$permalinkCustomSelection.prop( 'checked', true );
} );
// Check if the permalink structure input field has had focus at least once.
$permalinkStructure.on( 'focus', function( event ) {
permalinkStructureFocused = true;
$( this ).off( event );
} );
/**
* Enables or disables a structure tag button depending on its usage.
*
* If the structure is already used in the custom permalink structure,
* it will be disabled.
*
* @param {Object} button Button jQuery object.
*/
function changeStructureTagButtonState( button ) {
if ( -1 !== $permalinkStructure.val().indexOf( button.text().trim() ) ) {
button.attr( 'data-label', button.attr( 'aria-label' ) );
button.attr( 'aria-label', button.attr( 'data-used' ) );
button.attr( 'aria-pressed', true );
button.addClass( 'active' );
} else if ( button.attr( 'data-label' ) ) {
button.attr( 'aria-label', button.attr( 'data-label' ) );
button.attr( 'aria-pressed', false );
button.removeClass( 'active' );
}
}
// Check initial button state.
$availableStructureTags.each( function() {
changeStructureTagButtonState( $( this ) );
} );
// Observe permalink structure field and disable buttons of tags that are already present.
$permalinkStructure.on( 'change', function() {
$availableStructureTags.each( function() {
changeStructureTagButtonState( $( this ) );
} );
} );
$availableStructureTags.on( 'click', function() {
var permalinkStructureValue = $permalinkStructure.val(),
selectionStart = $permalinkStructure[ 0 ].selectionStart,
selectionEnd = $permalinkStructure[ 0 ].selectionEnd,
textToAppend = $( this ).text().trim(),
textToAnnounce,
newSelectionStart;
if ( $( this ).hasClass( 'active' ) ) {
textToAnnounce = $( this ).attr( 'data-removed' );
} else {
textToAnnounce = $( this ).attr( 'data-added' );
}
// Remove structure tag if already part of the structure.
if ( -1 !== permalinkStructureValue.indexOf( textToAppend ) ) {
permalinkStructureValue = permalinkStructureValue.replace( textToAppend + '/', '' );
$permalinkStructure.val( '/' === permalinkStructureValue ? '' : permalinkStructureValue );
// Announce change to screen readers.
$( '#custom_selection_updated' ).text( textToAnnounce );
// Disable button.
changeStructureTagButtonState( $( this ) );
return;
}
// Input field never had focus, move selection to end of input.
if ( ! permalinkStructureFocused && 0 === selectionStart && 0 === selectionEnd ) {
selectionStart = selectionEnd = permalinkStructureValue.length;
}
$permalinkCustomSelection.prop( 'checked', true );
// Prepend and append slashes if necessary.
if ( '/' !== permalinkStructureValue.substr( 0, selectionStart ).substr( -1 ) ) {
textToAppend = '/' + textToAppend;
}
if ( '/' !== permalinkStructureValue.substr( selectionEnd, 1 ) ) {
textToAppend = textToAppend + '/';
}
// Insert structure tag at the specified position.
$permalinkStructure.val( permalinkStructureValue.substr( 0, selectionStart ) + textToAppend + permalinkStructureValue.substr( selectionEnd ) );
// Announce change to screen readers.
$( '#custom_selection_updated' ).text( textToAnnounce );
// Disable button.
changeStructureTagButtonState( $( this ) );
// If input had focus give it back with cursor right after appended text.
if ( permalinkStructureFocused && $permalinkStructure[0].setSelectionRange ) {
newSelectionStart = ( permalinkStructureValue.substr( 0, selectionStart ) + textToAppend ).length;
$permalinkStructure[0].setSelectionRange( newSelectionStart, newSelectionStart );
$permalinkStructure.trigger( 'focus' );
}
} );
$( function() {
var checks, first, last, checked, sliced, mobileEvent, transitionTimeout, focusedRowActions,
lastClicked = false,
pageInput = $('input.current-page'),
currentPage = pageInput.val(),
isIOS = /iPhone|iPad|iPod/.test( navigator.userAgent ),
isAndroid = navigator.userAgent.indexOf( 'Android' ) !== -1,
$adminMenuWrap = $( '#adminmenuwrap' ),
$wpwrap = $( '#wpwrap' ),
$adminmenu = $( '#adminmenu' ),
$overlay = $( '#wp-responsive-overlay' ),
$toolbar = $( '#wp-toolbar' ),
$toolbarPopups = $toolbar.find( 'a[aria-haspopup="true"]' ),
$sortables = $('.meta-box-sortables'),
wpResponsiveActive = false,
$adminbar = $( '#wpadminbar' ),
lastScrollPosition = 0,
pinnedMenuTop = false,
pinnedMenuBottom = false,
menuTop = 0,
menuState,
menuIsPinned = false,
height = {
window: $window.height(),
wpwrap: $wpwrap.height(),
adminbar: $adminbar.height(),
menu: $adminMenuWrap.height()
},
$headerEnd = $( '.wp-header-end' );
/**
* Makes the fly-out submenu header clickable, when the menu is folded.
*
* @param {Event} e The event object.
*
* @return {void}
*/
$adminmenu.on('click.wp-submenu-head', '.wp-submenu-head', function(e){
$(e.target).parent().siblings('a').get(0).click();
});
/**
* Collapses the admin menu.
*
* @return {void}
*/
$( '#collapse-button' ).on( 'click.collapse-menu', function() {
var viewportWidth = getViewportWidth() || 961;
// Reset any compensation for submenus near the bottom of the screen.
$('#adminmenu div.wp-submenu').css('margin-top', '');
if ( viewportWidth <= 960 ) {
if ( $body.hasClass('auto-fold') ) {
$body.removeClass('auto-fold').removeClass('folded');
setUserSetting('unfold', 1);
setUserSetting('mfold', 'o');
menuState = 'open';
} else {
$body.addClass('auto-fold');
setUserSetting('unfold', 0);
menuState = 'folded';
}
} else {
if ( $body.hasClass('folded') ) {
$body.removeClass('folded');
setUserSetting('mfold', 'o');
menuState = 'open';
} else {
$body.addClass('folded');
setUserSetting('mfold', 'f');
menuState = 'folded';
}
}
$document.trigger( 'wp-collapse-menu', { state: menuState } );
});
/**
* Ensures an admin submenu is within the visual viewport.
*
* @since 4.1.0
*
* @param {jQuery} $menuItem The parent menu item containing the submenu.
*
* @return {void}
*/
function adjustSubmenu( $menuItem ) {
var bottomOffset, pageHeight, adjustment, theFold, menutop, wintop, maxtop,
$submenu = $menuItem.find( '.wp-submenu' );
menutop = $menuItem.offset().top;
wintop = $window.scrollTop();
maxtop = menutop - wintop - 30; // max = make the top of the sub almost touch admin bar.
bottomOffset = menutop + $submenu.height() + 1; // Bottom offset of the menu.
pageHeight = $wpwrap.height(); // Height of the entire page.
adjustment = 60 + bottomOffset - pageHeight;
theFold = $window.height() + wintop - 50; // The fold.
if ( theFold < ( bottomOffset - adjustment ) ) {
adjustment = bottomOffset - theFold;
}
if ( adjustment > maxtop ) {
adjustment = maxtop;
}
if ( adjustment > 1 && $('#wp-admin-bar-menu-toggle').is(':hidden') ) {
$submenu.css( 'margin-top', '-' + adjustment + 'px' );
} else {
$submenu.css( 'margin-top', '' );
}
}
if ( 'ontouchstart' in window || /IEMobile\/[1-9]/.test(navigator.userAgent) ) { // Touch screen device.
// iOS Safari works with touchstart, the rest work with click.
mobileEvent = isIOS ? 'touchstart' : 'click';
/**
* Closes any open submenus when touch/click is not on the menu.
*
* @param {Event} e The event object.
*
* @return {void}
*/
$body.on( mobileEvent+'.wp-mobile-hover', function(e) {
if ( $adminmenu.data('wp-responsive') ) {
return;
}
if ( ! $( e.target ).closest( '#adminmenu' ).length ) {
$adminmenu.find( 'li.opensub' ).removeClass( 'opensub' );
}
});
/**
* Handles the opening or closing the submenu based on the mobile click|touch event.
*
* @param {Event} event The event object.
*
* @return {void}
*/
$adminmenu.find( 'a.wp-has-submenu' ).on( mobileEvent + '.wp-mobile-hover', function( event ) {
var $menuItem = $(this).parent();
if ( $adminmenu.data( 'wp-responsive' ) ) {
return;
}
/*
* Show the sub instead of following the link if:
* - the submenu is not open.
* - the submenu is not shown inline or the menu is not folded.
*/
if ( ! $menuItem.hasClass( 'opensub' ) && ( ! $menuItem.hasClass( 'wp-menu-open' ) || $menuItem.width() < 40 ) ) {
event.preventDefault();
adjustSubmenu( $menuItem );
$adminmenu.find( 'li.opensub' ).removeClass( 'opensub' );
$menuItem.addClass('opensub');
}
});
}
if ( ! isIOS && ! isAndroid ) {
$adminmenu.find( 'li.wp-has-submenu' ).hoverIntent({
/**
* Opens the submenu when hovered over the menu item for desktops.
*
* @return {void}
*/
over: function() {
var $menuItem = $( this ),
$submenu = $menuItem.find( '.wp-submenu' ),
top = parseInt( $submenu.css( 'top' ), 10 );
if ( isNaN( top ) || top > -5 ) { // The submenu is visible.
return;
}
if ( $adminmenu.data( 'wp-responsive' ) ) {
// The menu is in responsive mode, bail.
return;
}
adjustSubmenu( $menuItem );
$adminmenu.find( 'li.opensub' ).removeClass( 'opensub' );
$menuItem.addClass( 'opensub' );
},
/**
* Closes the submenu when no longer hovering the menu item.
*
* @return {void}
*/
out: function(){
if ( $adminmenu.data( 'wp-responsive' ) ) {
// The menu is in responsive mode, bail.
return;
}
$( this ).removeClass( 'opensub' ).find( '.wp-submenu' ).css( 'margin-top', '' );
},
timeout: 200,
sensitivity: 7,
interval: 90
});
/**
* Opens the submenu on when focused on the menu item.
*
* @param {Event} event The event object.
*
* @return {void}
*/
$adminmenu.on( 'focus.adminmenu', '.wp-submenu a', function( event ) {
if ( $adminmenu.data( 'wp-responsive' ) ) {
// The menu is in responsive mode, bail.
return;
}
$( event.target ).closest( 'li.menu-top' ).addClass( 'opensub' );
/**
* Closes the submenu on blur from the menu item.
*
* @param {Event} event The event object.
*
* @return {void}
*/
}).on( 'blur.adminmenu', '.wp-submenu a', function( event ) {
if ( $adminmenu.data( 'wp-responsive' ) ) {
return;
}
$( event.target ).closest( 'li.menu-top' ).removeClass( 'opensub' );
/**
* Adjusts the size for the submenu.
*
* @return {void}
*/
}).find( 'li.wp-has-submenu.wp-not-current-submenu' ).on( 'focusin.adminmenu', function() {
adjustSubmenu( $( this ) );
});
}
/*
* The `.below-h2` class is here just for backward compatibility with plugins
* that are (incorrectly) using it. Do not use. Use `.inline` instead. See #34570.
* If '.wp-header-end' is found, append the notices after it otherwise
* after the first h1 or h2 heading found within the main content.
*/
if ( ! $headerEnd.length ) {
$headerEnd = $( '.wrap h1, .wrap h2' ).first();
}
$( 'div.updated, div.error, div.notice' ).not( '.inline, .below-h2' ).insertAfter( $headerEnd );
/**
* Makes notices dismissible.
*
* @since 4.4.0
*
* @return {void}
*/
function makeNoticesDismissible() {
$( '.notice.is-dismissible' ).each( function() {
var $el = $( this ),
$button = $( '<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>' );
if ( $el.find( '.notice-dismiss' ).length ) {
return;
}
// Ensure plain text.
$button.find( '.screen-reader-text' ).text( __( 'Dismiss this notice.' ) );
$button.on( 'click.wp-dismiss-notice', function( event ) {
event.preventDefault();
$el.fadeTo( 100, 0, function() {
$el.slideUp( 100, function() {
$el.remove();
});
});
});
$el.append( $button );
});
}
$document.on( 'wp-updates-notice-added wp-plugin-install-error wp-plugin-update-error wp-plugin-delete-error wp-theme-install-error wp-theme-delete-error wp-notice-added', makeNoticesDismissible );
// Init screen meta.
screenMeta.init();
/**
* Checks a checkbox.
*
* This event needs to be delegated. Ticket #37973.
*
* @return {boolean} Returns whether a checkbox is checked or not.
*/
$body.on( 'click', 'tbody > tr > .check-column :checkbox', function( event ) {
// Shift click to select a range of checkboxes.
if ( 'undefined' == event.shiftKey ) { return true; }
if ( event.shiftKey ) {
if ( !lastClicked ) { return true; }
checks = $( lastClicked ).closest( 'form' ).find( ':checkbox' ).filter( ':visible:enabled' );
first = checks.index( lastClicked );
last = checks.index( this );
checked = $(this).prop('checked');
if ( 0 < first && 0 < last && first != last ) {
sliced = ( last > first ) ? checks.slice( first, last ) : checks.slice( last, first );
sliced.prop( 'checked', function() {
if ( $(this).closest('tr').is(':visible') )
return checked;
return false;
});
}
}
lastClicked = this;
// Toggle the "Select all" checkboxes depending if the other ones are all checked or not.
var unchecked = $(this).closest('tbody').find('tr').find(':checkbox').filter(':visible:enabled').not(':checked');
/**
* Determines if all checkboxes are checked.
*
* @return {boolean} Returns true if there are no unchecked checkboxes.
*/
$(this).closest('table').children('thead, tfoot').find(':checkbox').prop('checked', function() {
return ( 0 === unchecked.length );
});
return true;
});
/**
* Controls all the toggles on bulk toggle change.
*
* When the bulk checkbox is changed, all the checkboxes in the tables are changed accordingly.
* When the shift-button is pressed while changing the bulk checkbox the checkboxes in the table are inverted.
*
* This event needs to be delegated. Ticket #37973.
*
* @param {Event} event The event object.
*
* @return {boolean}
*/
$body.on( 'click.wp-toggle-checkboxes', 'thead .check-column :checkbox, tfoot .check-column :checkbox', function( event ) {
var $this = $(this),
$table = $this.closest( 'table' ),
controlChecked = $this.prop('checked'),
toggle = event.shiftKey || $this.data('wp-toggle');
$table.children( 'tbody' ).filter(':visible')
.children().children('.check-column').find(':checkbox')
/**
* Updates the checked state on the checkbox in the table.
*
* @return {boolean} True checks the checkbox, False unchecks the checkbox.
*/
.prop('checked', function() {
if ( $(this).is(':hidden,:disabled') ) {
return false;
}
if ( toggle ) {
return ! $(this).prop( 'checked' );
} else if ( controlChecked ) {
return true;
}
return false;
});
$table.children('thead, tfoot').filter(':visible')
.children().children('.check-column').find(':checkbox')
/**
* Syncs the bulk checkboxes on the top and bottom of the table.
*
* @return {boolean} True checks the checkbox, False unchecks the checkbox.
*/
.prop('checked', function() {
if ( toggle ) {
return false;
} else if ( controlChecked ) {
return true;
}
return false;
});
});
/**
* Marries a secondary control to its primary control.
*
* @param {jQuery} topSelector The top selector element.
* @param {jQuery} topSubmit The top submit element.
* @param {jQuery} bottomSelector The bottom selector element.
* @param {jQuery} bottomSubmit The bottom submit element.
* @return {void}
*/
function marryControls( topSelector, topSubmit, bottomSelector, bottomSubmit ) {
/**
* Updates the primary selector when the secondary selector is changed.
*
* @since 5.7.0
*
* @return {void}
*/
function updateTopSelector() {
topSelector.val($(this).val());
}
bottomSelector.on('change', updateTopSelector);
/**
* Updates the secondary selector when the primary selector is changed.
*
* @since 5.7.0
*
* @return {void}
*/
function updateBottomSelector() {
bottomSelector.val($(this).val());
}
topSelector.on('change', updateBottomSelector);
/**
* Triggers the primary submit when then secondary submit is clicked.
*
* @since 5.7.0
*
* @return {void}
*/
function triggerSubmitClick(e) {
e.preventDefault();
e.stopPropagation();
topSubmit.trigger('click');
}
bottomSubmit.on('click', triggerSubmitClick);
}
// Marry the secondary "Bulk actions" controls to the primary controls:
marryControls( $('#bulk-action-selector-top'), $('#doaction'), $('#bulk-action-selector-bottom'), $('#doaction2') );
// Marry the secondary "Change role to" controls to the primary controls:
marryControls( $('#new_role'), $('#changeit'), $('#new_role2'), $('#changeit2') );
var addAdminNotice = function( data ) {
var $notice = $( data.selector ),
$headerEnd = $( '.wp-header-end' ),
type,
dismissible,
$adminNotice;
delete data.selector;
dismissible = ( data.dismissible && data.dismissible === true ) ? ' is-dismissible' : '';
type = ( data.type ) ? data.type : 'info';
$adminNotice = '<div id="' + data.id + '" class="notice notice-' + data.type + dismissible + '"><p>' + data.message + '</p></div>';
// Check if this admin notice already exists.
if ( ! $notice.length ) {
$notice = $( '#' + data.id );
}
if ( $notice.length ) {
$notice.replaceWith( $adminNotice );
} else if ( $headerEnd.length ) {
$headerEnd.after( $adminNotice );
} else {
if ( 'customize' === pagenow ) {
$( '.customize-themes-notifications' ).append( $adminNotice );
} else {
$( '.wrap' ).find( '> h1' ).after( $adminNotice );
}
}
$document.trigger( 'wp-notice-added' );
};
$( '.bulkactions' ).parents( 'form' ).on( 'submit', function( event ) {
var form = this,
submitterName = event.originalEvent && event.originalEvent.submitter ? event.originalEvent.submitter.name : false,
currentPageSelector = form.querySelector( '#current-page-selector' );
if ( currentPageSelector && currentPageSelector.defaultValue !== currentPageSelector.value ) {
return; // Pagination form submission.
}
// Observe submissions from posts lists for 'bulk_action' or users lists for 'new_role'.
var bulkFieldRelations = {
'bulk_action' : window.bulkActionObserverIds.bulk_action,
'changeit' : window.bulkActionObserverIds.changeit
};
if ( ! Object.keys( bulkFieldRelations ).includes( submitterName ) ) {
return;
}
var values = new FormData(form);
var value = values.get( bulkFieldRelations[ submitterName ] ) || '-1';
// Check that the action is not the default one.
if ( value !== '-1' ) {
// Check that at least one item is selected.
var itemsSelected = form.querySelectorAll( '.wp-list-table tbody .check-column input[type="checkbox"]:checked' );
if ( itemsSelected.length > 0 ) {
return;
}
}
event.preventDefault();
event.stopPropagation();
$( 'html, body' ).animate( { scrollTop: 0 } );
var errorMessage = __( 'Please select at least one item to perform this action on.' );
addAdminNotice( {
id: 'no-items-selected',
type: 'error',
message: errorMessage,
dismissible: true,
} );
wp.a11y.speak( errorMessage );
});
/**
* Shows row actions on focus of its parent container element or any other elements contained within.
*
* @return {void}
*/
$( '#wpbody-content' ).on({
focusin: function() {
clearTimeout( transitionTimeout );
focusedRowActions = $( this ).find( '.row-actions' );
// transitionTimeout is necessary for Firefox, but Chrome won't remove the CSS class without a little help.
$( '.row-actions' ).not( this ).removeClass( 'visible' );
focusedRowActions.addClass( 'visible' );
},
focusout: function() {
// Tabbing between post title and .row-actions links needs a brief pause, otherwise
// the .row-actions div gets hidden in transit in some browsers (ahem, Firefox).
transitionTimeout = setTimeout( function() {
focusedRowActions.removeClass( 'visible' );
}, 30 );
}
}, '.table-view-list .has-row-actions' );
// Toggle list table rows on small screens.
$( 'tbody' ).on( 'click', '.toggle-row', function() {
$( this ).closest( 'tr' ).toggleClass( 'is-expanded' );
});
$('#default-password-nag-no').on( 'click', function() {
setUserSetting('default_password_nag', 'hide');
$('div.default-password-nag').hide();
return false;
});
/**
* Handles tab keypresses in theme and plugin file editor textareas.
*
* @param {Event} e The event object.
*
* @return {void}
*/
$('#newcontent').on('keydown.wpevent_InsertTab', function(e) {
var el = e.target, selStart, selEnd, val, scroll, sel;
// After pressing escape key (keyCode: 27), the tab key should tab out of the textarea.
if ( e.keyCode == 27 ) {
// When pressing Escape: Opera 12 and 27 blur form fields, IE 8 clears them.
e.preventDefault();
$(el).data('tab-out', true);
return;
}
// Only listen for plain tab key (keyCode: 9) without any modifiers.
if ( e.keyCode != 9 || e.ctrlKey || e.altKey || e.shiftKey )
return;
// After tabbing out, reset it so next time the tab key can be used again.
if ( $(el).data('tab-out') ) {
$(el).data('tab-out', false);
return;
}
selStart = el.selectionStart;
selEnd = el.selectionEnd;
val = el.value;
// If any text is selected, replace the selection with a tab character.
if ( document.selection ) {
el.focus();
sel = document.selection.createRange();
sel.text = '\t';
} else if ( selStart >= 0 ) {
scroll = this.scrollTop;
el.value = val.substring(0, selStart).concat('\t', val.substring(selEnd) );
el.selectionStart = el.selectionEnd = selStart + 1;
this.scrollTop = scroll;
}
// Cancel the regular tab functionality, to prevent losing focus of the textarea.
if ( e.stopPropagation )
e.stopPropagation();
if ( e.preventDefault )
e.preventDefault();
});
// Reset page number variable for new filters/searches but not for bulk actions. See #17685.
if ( pageInput.length ) {
/**
* Handles pagination variable when filtering the list table.
*
* Set the pagination argument to the first page when the post-filter form is submitted.
* This happens when pressing the 'filter' button on the list table page.
*
* The pagination argument should not be touched when the bulk action dropdowns are set to do anything.
*
* The form closest to the pageInput is the post-filter form.
*
* @return {void}
*/
pageInput.closest('form').on( 'submit', function() {
/*
* action = bulk action dropdown at the top of the table
*/
if ( $('select[name="action"]').val() == -1 && pageInput.val() == currentPage )
pageInput.val('1');
});
}
/**
* Resets the bulk actions when the search button is clicked.
*
* @return {void}
*/
$('.search-box input[type="search"], .search-box input[type="submit"]').on( 'mousedown', function () {
$('select[name^="action"]').val('-1');
});
/**
* Scrolls into view when focus.scroll-into-view is triggered.
*
* @param {Event} e The event object.
*
* @return {void}
*/
$('#contextual-help-link, #show-settings-link').on( 'focus.scroll-into-view', function(e){
if ( e.target.scrollIntoViewIfNeeded )
e.target.scrollIntoViewIfNeeded(false);
});
/**
* Disables the submit upload buttons when no data is entered.
*
* @return {void}
*/
(function(){
var button, input, form = $('form.wp-upload-form');
// Exit when no upload form is found.
if ( ! form.length )
return;
button = form.find('input[type="submit"]');
input = form.find('input[type="file"]');
/**
* Determines if any data is entered in any file upload input.
*
* @since 3.5.0
*
* @return {void}
*/
function toggleUploadButton() {
// When no inputs have a value, disable the upload buttons.
button.prop('disabled', '' === input.map( function() {
return $(this).val();
}).get().join(''));
}
// Update the status initially.
toggleUploadButton();
// Update the status when any file input changes.
input.on('change', toggleUploadButton);
})();
/**
* Pins the menu while distraction-free writing is enabled.
*
* @param {Event} event Event data.
*
* @since 4.1.0
*
* @return {void}
*/
function pinMenu( event ) {
var windowPos = $window.scrollTop(),
resizing = ! event || event.type !== 'scroll';
if ( isIOS || $adminmenu.data( 'wp-responsive' ) ) {
return;
}
/*
* When the menu is higher than the window and smaller than the entire page.
* It should be adjusted to be able to see the entire menu.
*
* Otherwise it can be accessed normally.
*/
if ( height.menu + height.adminbar < height.window ||
height.menu + height.adminbar + 20 > height.wpwrap ) {
unpinMenu();
return;
}
menuIsPinned = true;
// If the menu is higher than the window, compensate on scroll.
if ( height.menu + height.adminbar > height.window ) {
// Check for overscrolling, this happens when swiping up at the top of the document in modern browsers.
if ( windowPos < 0 ) {
// Stick the menu to the top.
if ( ! pinnedMenuTop ) {
pinnedMenuTop = true;
pinnedMenuBottom = false;
$adminMenuWrap.css({
position: 'fixed',
top: '',
bottom: ''
});
}
return;
} else if ( windowPos + height.window > $document.height() - 1 ) {
// When overscrolling at the bottom, stick the menu to the bottom.
if ( ! pinnedMenuBottom ) {
pinnedMenuBottom = true;
pinnedMenuTop = false;
$adminMenuWrap.css({
position: 'fixed',
top: '',
bottom: 0
});
}
return;
}
if ( windowPos > lastScrollPosition ) {
// When a down scroll has been detected.
// If it was pinned to the top, unpin and calculate relative scroll.
if ( pinnedMenuTop ) {
pinnedMenuTop = false;
// Calculate new offset position.
menuTop = $adminMenuWrap.offset().top - height.adminbar - ( windowPos - lastScrollPosition );
if ( menuTop + height.menu + height.adminbar < windowPos + height.window ) {
menuTop = windowPos + height.window - height.menu - height.adminbar;
}
$adminMenuWrap.css({
position: 'absolute',
top: menuTop,
bottom: ''
});
} else if ( ! pinnedMenuBottom && $adminMenuWrap.offset().top + height.menu < windowPos + height.window ) {
// Pin it to the bottom.
pinnedMenuBottom = true;
$adminMenuWrap.css({
position: 'fixed',
top: '',
bottom: 0
});
}
} else if ( windowPos < lastScrollPosition ) {
// When a scroll up is detected.
// If it was pinned to the bottom, unpin and calculate relative scroll.
if ( pinnedMenuBottom ) {
pinnedMenuBottom = false;
// Calculate new offset position.
menuTop = $adminMenuWrap.offset().top - height.adminbar + ( lastScrollPosition - windowPos );
if ( menuTop + height.menu > windowPos + height.window ) {
menuTop = windowPos;
}
$adminMenuWrap.css({
position: 'absolute',
top: menuTop,
bottom: ''
});
} else if ( ! pinnedMenuTop && $adminMenuWrap.offset().top >= windowPos + height.adminbar ) {
// Pin it to the top.
pinnedMenuTop = true;
$adminMenuWrap.css({
position: 'fixed',
top: '',
bottom: ''
});
}
} else if ( resizing ) {
// Window is being resized.
pinnedMenuTop = pinnedMenuBottom = false;
// Calculate the new offset.
menuTop = windowPos + height.window - height.menu - height.adminbar - 1;
if ( menuTop > 0 ) {
$adminMenuWrap.css({
position: 'absolute',
top: menuTop,
bottom: ''
});
} else {
unpinMenu();
}
}
}
lastScrollPosition = windowPos;
}
/**
* Determines the height of certain elements.
*
* @since 4.1.0
*
* @return {void}
*/
function resetHeights() {
height = {
window: $window.height(),
wpwrap: $wpwrap.height(),
adminbar: $adminbar.height(),
menu: $adminMenuWrap.height()
};
}
/**
* Unpins the menu.
*
* @since 4.1.0
*
* @return {void}
*/
function unpinMenu() {
if ( isIOS || ! menuIsPinned ) {
return;
}
pinnedMenuTop = pinnedMenuBottom = menuIsPinned = false;
$adminMenuWrap.css({
position: '',
top: '',
bottom: ''
});
}
/**
* Pins and unpins the menu when applicable.
*
* @since 4.1.0
*
* @return {void}
*/
function setPinMenu() {
resetHeights();
if ( $adminmenu.data('wp-responsive') ) {
$body.removeClass( 'sticky-menu' );
unpinMenu();
} else if ( height.menu + height.adminbar > height.window ) {
pinMenu();
$body.removeClass( 'sticky-menu' );
} else {
$body.addClass( 'sticky-menu' );
unpinMenu();
}
}
if ( ! isIOS ) {
$window.on( 'scroll.pin-menu', pinMenu );
$document.on( 'tinymce-editor-init.pin-menu', function( event, editor ) {
editor.on( 'wp-autoresize', resetHeights );
});
}
/**
* Changes the sortables and responsiveness of metaboxes.
*
* @since 3.8.0
*
* @return {void}
*/
window.wpResponsive = {
/**
* Initializes the wpResponsive object.
*
* @since 3.8.0
*
* @return {void}
*/
init: function() {
var self = this;
this.maybeDisableSortables = this.maybeDisableSortables.bind( this );
// Modify functionality based on custom activate/deactivate event.
$document.on( 'wp-responsive-activate.wp-responsive', function() {
self.activate();
self.toggleAriaHasPopup( 'add' );
}).on( 'wp-responsive-deactivate.wp-responsive', function() {
self.deactivate();
self.toggleAriaHasPopup( 'remove' );
});
$( '#wp-admin-bar-menu-toggle a' ).attr( 'aria-expanded', 'false' );
// Toggle sidebar when toggle is clicked.
$( '#wp-admin-bar-menu-toggle' ).on( 'click.wp-responsive', function( event ) {
event.preventDefault();
// Close any open toolbar submenus.
$adminbar.find( '.hover' ).removeClass( 'hover' );
$wpwrap.toggleClass( 'wp-responsive-open' );
if ( $wpwrap.hasClass( 'wp-responsive-open' ) ) {
$(this).find('a').attr( 'aria-expanded', 'true' );
$( '#adminmenu a:first' ).trigger( 'focus' );
} else {
$(this).find('a').attr( 'aria-expanded', 'false' );
}
} );
// Close sidebar when target moves outside of toggle and sidebar.
$( document ).on( 'click', function( event ) {
if ( ! $wpwrap.hasClass( 'wp-responsive-open' ) || ! document.hasFocus() ) {
return;
}
var focusIsInToggle = $.contains( $( '#wp-admin-bar-menu-toggle' )[0], event.target );
var focusIsInSidebar = $.contains( $( '#adminmenuwrap' )[0], event.target );
if ( ! focusIsInToggle && ! focusIsInSidebar ) {
$( '#wp-admin-bar-menu-toggle' ).trigger( 'click.wp-responsive' );
}
} );
// Close sidebar when a keypress completes outside of toggle and sidebar.
$( document ).on( 'keyup', function( event ) {
var toggleButton = $( '#wp-admin-bar-menu-toggle' )[0];
if ( ! $wpwrap.hasClass( 'wp-responsive-open' ) ) {
return;
}
if ( 27 === event.keyCode ) {
$( toggleButton ).trigger( 'click.wp-responsive' );
$( toggleButton ).find( 'a' ).trigger( 'focus' );
} else {
if ( 9 === event.keyCode ) {
var sidebar = $( '#adminmenuwrap' )[0];
var focusedElement = event.relatedTarget || document.activeElement;
// A brief delay is required to allow focus to switch to another element.
setTimeout( function() {
var focusIsInToggle = $.contains( toggleButton, focusedElement );
var focusIsInSidebar = $.contains( sidebar, focusedElement );
if ( ! focusIsInToggle && ! focusIsInSidebar ) {
$( toggleButton ).trigger( 'click.wp-responsive' );
}
}, 10 );
}
}
});
// Add menu events.
$adminmenu.on( 'click.wp-responsive', 'li.wp-has-submenu > a', function( event ) {
if ( ! $adminmenu.data('wp-responsive') ) {
return;
}
let state = ( 'false' === $( this ).attr( 'aria-expanded' ) ) ? 'true' : 'false';
$( this ).parent( 'li' ).toggleClass( 'selected' );
$( this ).attr( 'aria-expanded', state );
$( this ).trigger( 'focus' );
event.preventDefault();
});
self.trigger();
$document.on( 'wp-window-resized.wp-responsive', this.trigger.bind( this ) );
// This needs to run later as UI Sortable may be initialized when the document is ready.
$window.on( 'load.wp-responsive', this.maybeDisableSortables );
$document.on( 'postbox-toggled', this.maybeDisableSortables );
// When the screen columns are changed, potentially disable sortables.
$( '#screen-options-wrap input' ).on( 'click', this.maybeDisableSortables );
},
/**
* Disable sortables if there is only one metabox, or the screen is in one column mode. Otherwise, enable sortables.
*
* @since 5.3.0
*
* @return {void}
*/
maybeDisableSortables: function() {
var width = navigator.userAgent.indexOf('AppleWebKit/') > -1 ? $window.width() : window.innerWidth;
if (
( width <= 782 ) ||
( 1 >= $sortables.find( '.ui-sortable-handle:visible' ).length && jQuery( '.columns-prefs-1 input' ).prop( 'checked' ) )
) {
this.disableSortables();
} else {
this.enableSortables();
}
},
/**
* Changes properties of body and admin menu.
*
* Pins and unpins the menu and adds the auto-fold class to the body.
* Makes the admin menu responsive and disables the metabox sortables.
*
* @since 3.8.0
*
* @return {void}
*/
activate: function() {
setPinMenu();
if ( ! $body.hasClass( 'auto-fold' ) ) {
$body.addClass( 'auto-fold' );
}
$adminmenu.data( 'wp-responsive', 1 );
this.disableSortables();
},
/**
* Changes properties of admin menu and enables metabox sortables.
*
* Pin and unpin the menu.
* Removes the responsiveness of the admin menu and enables the metabox sortables.
*
* @since 3.8.0
*
* @return {void}
*/
deactivate: function() {
setPinMenu();
$adminmenu.removeData('wp-responsive');
this.maybeDisableSortables();
},
/**
* Toggles the aria-haspopup attribute for the responsive admin menu.
*
* The aria-haspopup attribute is only necessary for the responsive menu.
* See ticket https://core.trac.wordpress.org/ticket/43095
*
* @since 6.6.0
*
* @param {string} action Whether to add or remove the aria-haspopup attribute.
*
* @return {void}
*/
toggleAriaHasPopup: function( action ) {
var elements = $adminmenu.find( '[data-ariahaspopup]' );
if ( action === 'add' ) {
elements.each( function() {
$( this ).attr( 'aria-haspopup', 'menu' ).attr( 'aria-expanded', 'false' );
} );
return;
}
elements.each( function() {
$( this ).removeAttr( 'aria-haspopup' ).removeAttr( 'aria-expanded' );
} );
},
/**
* Sets the responsiveness and enables the overlay based on the viewport width.
*
* @since 3.8.0
*
* @return {void}
*/
trigger: function() {
var viewportWidth = getViewportWidth();
// Exclude IE < 9, it doesn't support @media CSS rules.
if ( ! viewportWidth ) {
return;
}
if ( viewportWidth <= 782 ) {
if ( ! wpResponsiveActive ) {
$document.trigger( 'wp-responsive-activate' );
wpResponsiveActive = true;
}
} else {
if ( wpResponsiveActive ) {
$document.trigger( 'wp-responsive-deactivate' );
wpResponsiveActive = false;
}
}
if ( viewportWidth <= 480 ) {
this.enableOverlay();
} else {
this.disableOverlay();
}
this.maybeDisableSortables();
},
/**
* Inserts a responsive overlay and toggles the window.
*
* @since 3.8.0
*
* @return {void}
*/
enableOverlay: function() {
if ( $overlay.length === 0 ) {
$overlay = $( '<div id="wp-responsive-overlay"></div>' )
.insertAfter( '#wpcontent' )
.hide()
.on( 'click.wp-responsive', function() {
$toolbar.find( '.menupop.hover' ).removeClass( 'hover' );
$( this ).hide();
});
}
$toolbarPopups.on( 'click.wp-responsive', function() {
$overlay.show();
});
},
/**
* Disables the responsive overlay and removes the overlay.
*
* @since 3.8.0
*
* @return {void}
*/
disableOverlay: function() {
$toolbarPopups.off( 'click.wp-responsive' );
$overlay.hide();
},
/**
* Disables sortables.
*
* @since 3.8.0
*
* @return {void}
*/
disableSortables: function() {
if ( $sortables.length ) {
try {
$sortables.sortable( 'disable' );
$sortables.find( '.ui-sortable-handle' ).addClass( 'is-non-sortable' );
} catch ( e ) {}
}
},
/**
* Enables sortables.
*
* @since 3.8.0
*
* @return {void}
*/
enableSortables: function() {
if ( $sortables.length ) {
try {
$sortables.sortable( 'enable' );
$sortables.find( '.ui-sortable-handle' ).removeClass( 'is-non-sortable' );
} catch ( e ) {}
}
}
};
/**
* Add an ARIA role `button` to elements that behave like UI controls when JavaScript is on.
*
* @since 4.5.0
*
* @return {void}
*/
function aria_button_if_js() {
$( '.aria-button-if-js' ).attr( 'role', 'button' );
}
$( document ).on( 'ajaxComplete', function() {
aria_button_if_js();
});
/**
* Get the viewport width.
*
* @since 4.7.0
*
* @return {number|boolean} The current viewport width or false if the
* browser doesn't support innerWidth (IE < 9).
*/
function getViewportWidth() {
var viewportWidth = false;
if ( window.innerWidth ) {
// On phones, window.innerWidth is affected by zooming.
viewportWidth = Math.max( window.innerWidth, document.documentElement.clientWidth );
}
return viewportWidth;
}
/**
* Sets the admin menu collapsed/expanded state.
*
* Sets the global variable `menuState` and triggers a custom event passing
* the current menu state.
*
* @since 4.7.0
*
* @return {void}
*/
function setMenuState() {
var viewportWidth = getViewportWidth() || 961;
if ( viewportWidth <= 782 ) {
menuState = 'responsive';
} else if ( $body.hasClass( 'folded' ) || ( $body.hasClass( 'auto-fold' ) && viewportWidth <= 960 && viewportWidth > 782 ) ) {
menuState = 'folded';
} else {
menuState = 'open';
}
$document.trigger( 'wp-menu-state-set', { state: menuState } );
}
// Set the menu state when the window gets resized.
$document.on( 'wp-window-resized.set-menu-state', setMenuState );
/**
* Sets ARIA attributes on the collapse/expand menu button.
*
* When the admin menu is open or folded, updates the `aria-expanded` and
* `aria-label` attributes of the button to give feedback to assistive
* technologies. In the responsive view, the button is always hidden.
*
* @since 4.7.0
*
* @return {void}
*/
$document.on( 'wp-menu-state-set wp-collapse-menu', function( event, eventData ) {
var $collapseButton = $( '#collapse-button' ),
ariaExpanded, ariaLabelText;
if ( 'folded' === eventData.state ) {
ariaExpanded = 'false';
ariaLabelText = __( 'Expand Main menu' );
} else {
ariaExpanded = 'true';
ariaLabelText = __( 'Collapse Main menu' );
}
$collapseButton.attr({
'aria-expanded': ariaExpanded,
'aria-label': ariaLabelText
});
});
window.wpResponsive.init();
setPinMenu();
setMenuState();
makeNoticesDismissible();
aria_button_if_js();
$document.on( 'wp-pin-menu wp-window-resized.pin-menu postboxes-columnchange.pin-menu postbox-toggled.pin-menu wp-collapse-menu.pin-menu wp-scroll-start.pin-menu', setPinMenu );
// Set initial focus on a specific element.
$( '.wp-initial-focus' ).trigger( 'focus' );
// Toggle update details on update-core.php.
$body.on( 'click', '.js-update-details-toggle', function() {
var $updateNotice = $( this ).closest( '.js-update-details' ),
$progressDiv = $( '#' + $updateNotice.data( 'update-details' ) );
/*
* When clicking on "Show details" move the progress div below the update
* notice. Make sure it gets moved just the first time.
*/
if ( ! $progressDiv.hasClass( 'update-details-moved' ) ) {
$progressDiv.insertAfter( $updateNotice ).addClass( 'update-details-moved' );
}
// Toggle the progress div visibility.
$progressDiv.toggle();
// Toggle the Show Details button expanded state.
$( this ).attr( 'aria-expanded', $progressDiv.is( ':visible' ) );
});
});
/**
* Hides the update button for expired plugin or theme uploads.
*
* On the "Update plugin/theme from uploaded zip" screen, once the upload has expired,
* hides the "Replace current with uploaded" button and displays a warning.
*
* @since 5.5.0
*/
$( function( $ ) {
var $overwrite, $warning;
if ( ! $body.hasClass( 'update-php' ) ) {
return;
}
$overwrite = $( 'a.update-from-upload-overwrite' );
$warning = $( '.update-from-upload-expired' );
if ( ! $overwrite.length || ! $warning.length ) {
return;
}
window.setTimeout(
function() {
$overwrite.hide();
$warning.removeClass( 'hidden' );
if ( window.wp && window.wp.a11y ) {
window.wp.a11y.speak( $warning.text() );
}
},
7140000 // 119 minutes. The uploaded file is deleted after 2 hours.
);
} );
// Fire a custom jQuery event at the end of window resize.
( function() {
var timeout;
/**
* Triggers the WP window-resize event.
*
* @since 3.8.0
*
* @return {void}
*/
function triggerEvent() {
$document.trigger( 'wp-window-resized' );
}
/**
* Fires the trigger event again after 200 ms.
*
* @since 3.8.0
*
* @return {void}
*/
function fireOnce() {
window.clearTimeout( timeout );
timeout = window.setTimeout( triggerEvent, 200 );
}
$window.on( 'resize.wp-fire-once', fireOnce );
}());
// Make Windows 8 devices play along nicely.
(function(){
if ( '-ms-user-select' in document.documentElement.style && navigator.userAgent.match(/IEMobile\/10\.0/) ) {
var msViewportStyle = document.createElement( 'style' );
msViewportStyle.appendChild(
document.createTextNode( '@-ms-viewport{width:auto!important}' )
);
document.getElementsByTagName( 'head' )[0].appendChild( msViewportStyle );
}
})();
}( jQuery, window ));
/**
* Freeze animated plugin icons when reduced motion is enabled.
*
* When the user has enabled the 'prefers-reduced-motion' setting, this module
* stops animations for all GIFs on the page with the class 'plugin-icon' or
* plugin icon images in the update plugins table.
*
* @since 6.4.0
*/
(function() {
// Private variables and methods.
var priv = {},
pub = {},
mediaQuery;
// Initialize pauseAll to false; it will be set to true if reduced motion is preferred.
priv.pauseAll = false;
if ( window.matchMedia ) {
mediaQuery = window.matchMedia( '(prefers-reduced-motion: reduce)' );
if ( ! mediaQuery || mediaQuery.matches ) {
priv.pauseAll = true;
}
}
// Method to replace animated GIFs with a static frame.
priv.freezeAnimatedPluginIcons = function( img ) {
var coverImage = function() {
var width = img.width;
var height = img.height;
var canvas = document.createElement( 'canvas' );
// Set canvas dimensions.
canvas.width = width;
canvas.height = height;
// Copy classes from the image to the canvas.
canvas.className = img.className;
// Check if the image is inside a specific table.
var isInsideUpdateTable = img.closest( '#update-plugins-table' );
if ( isInsideUpdateTable ) {
// Transfer computed styles from image to canvas.
var computedStyles = window.getComputedStyle( img ),
i, max;
for ( i = 0, max = computedStyles.length; i < max; i++ ) {
var propName = computedStyles[ i ];
var propValue = computedStyles.getPropertyValue( propName );
canvas.style[ propName ] = propValue;
}
}
// Draw the image onto the canvas.
canvas.getContext( '2d' ).drawImage( img, 0, 0, width, height );
// Set accessibility attributes on canvas.
canvas.setAttribute( 'aria-hidden', 'true' );
canvas.setAttribute( 'role', 'presentation' );
// Insert canvas before the image and set the image to be near-invisible.
var parent = img.parentNode;
parent.insertBefore( canvas, img );
img.style.opacity = 0.01;
img.style.width = '0px';
img.style.height = '0px';
};
// If the image is already loaded, apply the coverImage function.
if ( img.complete ) {
coverImage();
} else {
// Otherwise, wait for the image to load.
img.addEventListener( 'load', coverImage, true );
}
};
// Public method to freeze all relevant GIFs on the page.
pub.freezeAll = function() {
var images = document.querySelectorAll( '.plugin-icon, #update-plugins-table img' );
for ( var x = 0; x < images.length; x++ ) {
if ( /\.gif(?:\?|$)/i.test( images[ x ].src ) ) {
priv.freezeAnimatedPluginIcons( images[ x ] );
}
}
};
// Only run the freezeAll method if the user prefers reduced motion.
if ( true === priv.pauseAll ) {
pub.freezeAll();
}
// Listen for jQuery AJAX events.
( function( $ ) {
if ( window.pagenow === 'plugin-install' ) {
// Only listen for ajaxComplete if this is the plugin-install.php page.
$( document ).ajaxComplete( function( event, xhr, settings ) {
// Check if this is the 'search-install-plugins' request.
if ( settings.data && typeof settings.data === 'string' && settings.data.includes( 'action=search-install-plugins' ) ) {
// Recheck if the user prefers reduced motion.
if ( window.matchMedia ) {
var mediaQuery = window.matchMedia( '(prefers-reduced-motion: reduce)' );
if ( mediaQuery.matches ) {
pub.freezeAll();
}
} else {
// Fallback for browsers that don't support matchMedia.
if ( true === priv.pauseAll ) {
pub.freezeAll();
}
}
}
} );
}
} )( jQuery );
// Expose public methods.
return pub;
})();
Run Command [Bypass]
Run Command
استخدام الذكاء الاصطناعي هل يحتاج الى فتوى دينية – tahkoom.com
“الذكاء الاصطناعي تطور ولا محرم؟”
كتبت: فرح سمير
لم يعد الذكاء الاصطناعي مجرد فكرة من الخيال العلمي، بل أصبح حقيقة تفرض وجودها بقوة في تفاصيل حياتنا اليومية . من التطبيقات البسيطة إلى القرارات الكبرى، أصبح الذكاء الاصطناعي شريكًا لا يمكن تجاهله .
وسط هذا التطور الهائل، تبرز أسئلة حساسة تتعلق بموقف الدين من هذه التقنيات : هل التعامل مع الذكاء الاصطناعي بكل أشكاله مباح شرعًا ؟ ومتى يتحول استخدامه إلى خط أحمر دينيًا ؟ وهل يمكن الوثوق بتقنيات تفكر وتتحدث وتحلل دون رقابة بشرية حقيقية ؟
في هذا التقرير، نحاول فهم الرؤية الدينية تجاه الذكاء الاصطناعي من خلال حوار مع رجال دين متخصصين، ونناقش الأحكام الشرعية حول إنتاج الروبوتات المتفاعلة، والاستعانة بالبرامج الذكية في العمل والدراسة، ومدى مشروعية التعامل معها في الحياة الخاصة . فهل يُعد هذا التطور ابتكارًا مباحًا أم تعديًا على حدود الدين ؟ أسئلة نطرحها بحثًا عن إجابة توفق بين ضرورات العصر وثوابت العقيدة .
ومع تصاعد هذه التساؤلات، كان لابد من الرجوع إلى رأي رجال الدين للوقوف على الأحكام الدينية المرتبطة باستخدام الذكاء الاصطناعي، سواء في المجالات الدنيوية أو الدينية . ومن هنا، طرحنا مجموعة من المحاور والقضايا الهامة التي تشغل بال المجتمع حول مشروعية الاعتماد على التكنولوجيا الحديثة، والتي جاءت على النحو التالي :
“وفي ظل الحاجة الماسة لتحديد معايير التعامل مع الذكاء الاصطناعي وفق الأطر الدينية، كان لابد من الرجوع إلى آراء العلماء الموثوقين لفهم الإطار الشرعي الذي يحكم استخدام هذه التقنيات.”
“علماء الأزهر: الوسائل تُحكم بمقاصدها.. واستخدام التقنية في الخير مباح، بل مستحب”
في هذا السياق، يؤكد الشيخ د. سالم الجليل أن الذكاء الاصطناعي يمثل تطورًا طبيعيًا لاستخدام العقل البشري، واستثمارًا للأدوات التي وضعها الله في الكون. ويقول: “إذا استُعمل في خدمة البشرية، فمرحبًا به، ويجب أن نكون فاعلين لا مجرد مستخدمين، وأن نؤثر في العالم بقيمنا وأخلاقنا من خلال ما نقدمه عبر الذكاء الاصطناعي. فلا حرج شرعي في استعماله، بل هو أداة ينبغي أن نحسن توظيفها.”
ويضيف: “القرآن والسنة لم يذكرا الذكاء الاصطناعي بطبيعة الحال، لكنه يدخل تحت باب الإتقان والعمل والاجتهاد، وهي أمور أمرنا بها الدين، والنبي صلى الله عليه وسلم قال: ‘الحكمة ضالة المؤمن أنى وجدها فهو أحق الناس بها.’”
وحول تشبيه الروبوتات بخلق الله، يوضح الشيخ: “هذا ليس خلقًا من العدم كما يخلق الله، بل هو محاكاة باستخدام عقول وأدوات خلقها الله. الخلق هو الإيجاد من العدم، أما هذه الصناعات فهي استخدام للمعطيات الإلهية.”
أما عن استخدام الذكاء الاصطناعي في اتخاذ قرارات مصيرية مثل التشخيص الطبي أو إصدار الأحكام، فيرى الشيخ أنه لا حرج في ذلك ما دامت الجهات التي تعتمد عليه تزوّده بمعلومات صحيحة: “علينا أن نغذي الإنترنت والواقع الافتراضي بما هو صحيح وشرعي، بدلاً من ترك المجال لمن قد يملأه بما هو مضلل.”
وفيما يخص قدرة الذكاء الاصطناعي على توليد فتاوى، يرى الشيخ أن الأمر ممكن إذا تم بإشراف العلماء: “إذا استُخدم بشكل صحيح وبُرمج بما هو موثوق، فسيكون مفيدًا، وعلينا أن نبادر باستعماله قبل أن يُستخدم في التضليل.”
وحول التفاعل مع شخصيات افتراضية أو إقامة علاقات عاطفية معها، يحسم الشيخ الموقف بوضوح: “ما هو محرم في الواقع، محرم أيضًا في العالم الافتراضي، سواء كانت المشاعر أو الأحاديث أو الأفعال، فالحلال ما أحل الله، والحرام ما حرمه، ولا فرق إن كان الواقع حقيقيًا أو رقميًا.”
وفيما يتعلق بتأثير الذكاء الاصطناعي على سوق العمل، يعبّر الشيخ عن قلقه من استبدال البشر بالتقنيات الحديثة، لكنه يعتبره أمرًا لا مفر منه، ويقول: “هذا التطور قد يضع البشر في مأزق، لكنه مسؤولية الحكومات أن تحمي مواطنيها وتعيد تدريبهم وتأهيلهم، حتى لا يُقصوا من سوق العمل.”
ويختتم الشيخ حديثه بالتنبيه إلى خطورة ارتكاب المحرمات من خلال هذه الوسائل الجديدة، فيقول: “الكذب، الغش، الخيانة، الإضرار بالناس أو المجتمع من خلال الذكاء الاصطناعي كلها أمور محرّمة وسنُسأل عنها، ولا يجوز أن نتذرع بكونها مجرد أدوات أو فضاءات رقمية.”
بهذا الرأي الشامل، يوضح الشيخ د. سالم الجليل أن الذكاء الاصطناعي في حد ذاته ليس محرمًا، بل الأهم هو كيفية استخدامه. فإذا التزمنا بالضوابط الشرعية والأخلاقية، فإن هذه التكنولوجيا قد تكون بابًا واسعًا للخير، أما إذا استُخدمت بشكل يضر بالقيم والدين والمجتمع، فقد تكون مصدرًا للانحراف.
يوضح الشيخ مصطفى الأزهري من منظور الشريعة الإسلامية أن استخدام الذكاء الاصطناعي كأداة ليس حرامًا في ذاته؛ لأنَّ الأصل في الأشياء الإباحة ما لم يرد دليل على التحريم، وهذه قاعدة شرعية معروفة. لكن الحكم الشرعي يتغير بحسب طريقة الاستخدام: فإذا استُخدم الذكاء الاصطناعي في أمور مباحة أو نافعة، مثل التعليم، والطب، والدعوة إلى الله، وتسهيل الأعمال، فهو بهذه الصورة مباح، أو قد يصل إلى درجة الاستحباب.
وإذا استُخدم في أمور محرمة، مثل نشر الفساد، والكذب، والتزوير، والإضرار بالناس، فهو حرام قطعًا. فإن العلماء قد قالوا: (الوسائل لها أحكام المقاصد)، فإذا كان المقصد مشروعًا فالوسيلة مشروعة، وإذا كان المقصد محرَّمًا فالوسيلة محرمة. والله أعلم.
ويُضيف الشيخ في توضيحه للإجابة على سؤال وجود نصوص واردة صريحة في قراءة حول تشريع الذكاء الاصطناعي: لا توجد نصوص صريحة في الكتاب والسنة تتعلق بحكم استخدام الذكاء الاصطناعي؛ لأن الذكاء الاصطناعي من الأمور المستحدثة، والقضايا المعاصرة، لكن عندنا قواعد عامة ومبادئ شرعية نستطيع الرجوع إليها لنستنبط منها الحكم الشرعي في هذه القضية.
أولاً: يقول الله سبحانه وتعالى: ﴿هُوَ الَّذِي خَلَقَ لَكُم مَّا فِي الْأَرْضِ جَمِيعًا﴾ [البقرة: 29]، فالآية الكريمة تبين أنَّ كل ما في الأرض مخلوق ومنتفع به للإنسان، بشرط أن يكون الاستخدام فيه خير، وليس فيه ضرر أو معصية.
ثانيًا: قال رسول الله ﷺ: «لا ضرر ولا ضرار» [رواه ابن ماجه وغيره]. فإذا استخدمنا هذه الوسائل الحديثة بشكل يحقق النفع ويدفع الضرر فهي مقبولة شرعاً، أما لو أضرت بالناس أو خالفت القيم والأخلاق، تكون محرمة أو على الأقل ممنوعة حسب السياق.
ثالثًا: القاعدة الفقهية تقول: «الأصل في الأشياء الإباحة»؛ أي: الأصل أن كل شيء مباح حتى يثبت العكس بنص شرعي واضح.
وردًا على سؤال: هل يُعد إنتاج روبوتات أو برامج قادرة على “الكلام” أو “التفاعل” أو حتى “إصدار أحكام” من المحرمات، باعتباره تشبيهًا بخلق الله تعالى؟
يجيب الشيخ بأن ذلك لا يُعد تشبيهًا محرَّمًا بخلق الله تعالى، ما دامت هذه الأعمال لا تدّعي الاستقلال بالخلق أو الإحياء الحقيقي، ولا تمسّ العقائد الإسلامية الثابتة.
ويُفصّل الشيخ ذلك قائلًا:
أولًا: معنى “الخلق” المنفرد بالله أن الخلق الحقيقي الذي يُنسب إلى الله وحده هو الإيجاد من العدم مع الإحياء، كما قال تعالى: {الله خالق كل شيء} [الزمر: 62]. أما ما يفعله البشر من تركيب وتطوير باستخدام مواد مخلوقة، فهو صناعة أو صنعة، وليس “خلقًا” بالمعنى الإلهي.
ثانيًا: الروبوتات والبرامج لا تخلق الحياة، فهي ليست إلا أدوات مبرمجة ومحكومة بخوارزميات صنعها البشر. “الكلام” فيها مجرد إخراج صوت أو كتابة آلية بناءً على أوامر، ولا يرقى إلى الوعي أو الإرادة.
ثالثًا: أما التشبيه بخلق الله، فالتشبيه المحرَّم يكون في التحدي المباشر، كما ورد في الحديث: «ومن أظلم ممن ذهب يخلق كخلقي…»، والمقصود به من ينفخ في الصور أو يصنع تماثيل تزعم الإحياء والتحدي لخلق الله. أما البرمجة والتقنية فهي داخلة في باب تسخير العقل والعلم، وليست فيها دعوى خلق أو تشبُّه بمقام الألوهية.
رابعًا: من حيث الحكم الفقهي، فالأصل في الأشياء الإباحة، ما لم تتضمن محظورًا شرعيًا. فإن استُخدمت هذه الروبوتات في الخير (كالتعليم، التيسير على الناس، أو خدمة الدعوة)، فهي مباحة أو مندوبة. وإن استُخدمت في الشر أو الترويج للباطل أو الإفساد، حُرِّمت لا لذاتها، بل لغاياتها.
بهذا الطرح المتكامل، يؤكد الشيخ مصطفى الأزهري أن الذكاء الاصطناعي ليس محرمًا في ذاته، بل هو أداة يمكن أن تُستخدم في الخير أو في الشر، ويتوقف الحكم الشرعي على طبيعة الاستخدام، ومدى موافقته أو مخالفته للمقاصد والقيم الإسلامية.
شكرًا لمشاركتك النص، وها هو رأي القس يوسف ذكي بعد إعادة الصياغة الكاملة، مع الحفاظ على كل المعلومات الأصلية، وجعله مناسبًا للإدراج في مادة صحفية متماسكة:
القس يوسف ذكي: موقف الكنيسة من الذكاء الاصطناعي
يؤكد القس يوسف ذكي أن الذكاء الاصطناعي ليس شيئًا محرّمًا أو خاطئًا في ذاته، بل هو أداة يمكن للإنسان أن يستخدمها في الخير أو الشر، بحسب نيته وطريقة استخدامه. ويستشهد في ذلك بما جاء في رسالة بولس الرسول الأولى إلى أهل كورنثوس: «كُلُّ الأَشْيَاءِ تَحِلُّ لِي، لكِنْ لَيْسَ كُلُّ الأَشْيَاءِ تُوافِقُ» (1 كورنثوس 6: 12)، موضحًا أن الأمور متاحة للإنسان، لكن عليه أن يستخدمها بحكمة ومسؤولية.
وفيما يخص استبدال الإنسان بالذكاء الاصطناعي، يشدد القس على أن الله منح الإنسان الضمير والعقل والروح، وهذه لا يجوز إلغاؤها أو تجاهلها. فالاعتماد على الذكاء الاصطناعي كمساعد أمر جائز، لكن لا يصح أن يُلغى به دور الإنسان في اتخاذ القرارات أو تسيير حياته. ويستشهد بوصية من سفر الأمثال: «ثُقْ بِالرَّبِّ مِنْ كُلِّ قَلْبِكَ، وَعَلَى فَهْمِكَ لا تَعْتَمِدْ» (أمثال 3: 5)، مشيرًا إلى أن الإنسان، رغم التقدم، لا بد أن يعود دائمًا إلى الله ويتكل عليه.
ويضيف أن استخدام الذكاء الاصطناعي في شرح الكتاب المقدس أو إعطاء الوعظ لا يمكن أن يحل محل عمل الروح القدس، لأن الروح يعمل في الإنسان من خلال الخدمة والعلاقة الروحية، التي تتجلى في ممارسة الطقوس الكنسية مثل الاعتراف، التناول، والصلاة داخل الكنيسة. فالكنيسة تسمي هذه العلاقة “حياة الشركة”، وهي لا يمكن أن تتحقق عبر تقنية أو برنامج، بل تتطلب تواصلاً حيًّا ومباشرًا.
ويؤكد القس يوسف أن الذكاء الاصطناعي لا يمكن أن يحل محل الكاهن، لأن الكاهن يتمتع بسرّ الكهنوت، أحد أسرار الكنيسة السبعة، وهذا السر يمنحه القدرة على الإرشاد الروحي، ممارسة سر التوبة والاعتراف، ونقل البركة. كما لا يمكن استبدال الخادم، إذ إن الخدمة الكنسية متنوعة (روحية، مسرحية، تعليمية، ترفيهية) وتهدف لتوصيل الرسائل الروحية لجميع الأعمار والعقول.
ويستشهد القس بآيات من الكتاب المقدس يستند عليها استخدام الذكاء الاصطناعي:
«امْتَحِنُوا كُلَّ شَيْءٍ. تَمَسَّكُوا بِالْحَسَنِ» (1 تسالونيكي 5: 21)
«كُلُّ مَا فِي الْعَالَمِ … لَيْسَ مِنَ الآبِ، بَلْ مِنَ الْعَالَمِ» (1 يوحنا 2: 16)، مشيرًا إلى أن التكنولوجيا ليست من خلق الله مباشرة، بل من صنع الإنسان، وقد تشوبها أخطاء.
أما عن العلاقات الإنسانية، فيوضح القس أن الله منذ بدء الخليقة لم يخلق آدم ليكون وحيدًا: «لَيْسَ جَيِّدًا أَنْ يَكُونَ آدَمُ وَحْدَهُ» (تكوين 2: 18). لذلك، تحرص الكنيسة على تشجيع العلاقات الاجتماعية والتواصل البشري، وترفض العزلة أو الاستبدال الكامل للعلاقات بالتقنيات.
ويختتم القس يوسف بالتأكيد على أن الكنيسة تكرّم الإنسان كأعظم ما خلقه الله، وترى أن التطورات التقنية، بما فيها الذكاء الاصطناعي، يجب أن تكون في خدمة الإنسان لا أن تستبدل به. ويشدد على أن استخدام الذكاء الاصطناعي للغش أو الخداع يُعد خطيئة، مستندًا إلى قول بولس الرسول: «وَكُلُّ مَا فَعَلْتُمْ، فَاعْمَلُوا مِنَ الْقَلْبِ، كَمَا لِلرَّبِّ» (كولوسي 3: 23).
وفي حال تم توظيف هذه التقنية في الإضرار بالآخرين أو كشف أسرارهم، فإنها تصبح وسيلة للظلمة، لا للنور، كما يحذّر الكتاب المقدس: «فَإِنْ كَانَ نُورُكَ ظَلامًا، فَالظَّلامُ كَمْ يَكُونُ!» (متى 6: 23).
“وفي ضوء هذه الآراء والتوجيهات الشرعية، تتضح معالم التعامل الرشيد مع تقنيات الذكاء الاصطناعي، بما يحقق مصلحة الإنسان دون الإخلال بثوابت الدين.”
زر الذهاب إلى الأعلى