Wikipedia testwiki https://test.wikipedia.org/wiki/Main_Page MediaWiki 1.47.0-wmf.1 first-letter Media Special Talk User User talk Wikipedia Wikipedia talk File File talk MediaWiki MediaWiki talk Template Template talk Help Help talk Category Category talk Thread Thread talk Summary Summary talk Test namespace 1 Test namespace 1 talk Test namespace 2 Test namespace 2 talk Draft Draft talk Campaign Campaign talk TimedText TimedText talk Module Module talk SecurePoll SecurePoll talk CNBanner CNBanner talk Translations Translations talk Event Event talk Topic Newsletter Newsletter talk MediaWiki:Gadgets-definition 8 12894 741001 740353 2026-05-08T15:36:32Z Valcio 46860 + 741001 wikitext text/x-wiki <noinclude>{{collapse|1={{#invoke:validate gadgets|validate}}|title=Issues in gadget definitions}}</noinclude> == Twinkle == * Twinkle [ResourceLoader |dependencies=ext.gadget.morebits, ext.gadget.select2, mediawiki.api, mediawiki.language |rights=autoconfirmed |type=general |peers=Twinkle-pagestyles] |Twinkle.js |Twinkle.css |twinklearv.js |twinklewarn.js |twinkleblock.js |twinklewelcome.js |twinkletalkback.js |twinklespeedy.js |twinkleprod.js |twinklexfd.js |twinkleimage.js |twinkleprotect.js |twinkletag.js |twinklediff.js |twinkleunlink.js |twinklerollback.js |twinkledeprod.js |twinklebatchdelete.js |twinklebatchprotect.js |twinklebatchundelete.js |twinkleconfig.js * morebits [ResourceLoader |dependencies=mediawiki.user, mediawiki.util, mediawiki.Title |hidden] |morebits.js |morebits.css * Twinkle-pagestyles [hidden |skins=vector, vector-2022] |Twinkle-pagestyles.css * select2 [ResourceLoader |hidden] |select2.min.js |select2.min.css *morebitsV3[ResourceLoader|dependencies=mediawiki.user,mediawiki.util,mediawiki.Title,jquery.ui|hidden]|morebitsV3.js|morebitsV3.css *twinkle-enwiki[ResourceLoader|dependencies=ext.gadget.morebitsV3,ext.gadget.select2,mediawiki.api,mediawiki.storage,mediawiki.libs.pluralruleparser|peers=Twinkle-pagestyles]|TwinkleV3.js|TwinkleV3.css *twinkle-starter[ResourceLoader|dependencies=ext.gadget.morebitsV3,ext.gadget.select2,mediawiki.api,mediawiki.storage|peers=Twinkle-pagestyles]|Twinkle-starter.js|Twinkle-starter.css *orange-i18n [ ResourceLoader | dependencies = mediawiki.libs.pluralruleparser ] | orange-i18n.js *banana-i18n [ ResourceLoader ] | banana-i18n.js == Recent-Tests == * nomin-test[ResourceLoader|requiresES6] | nomin-test.js * regex-test[ResourceLoader]|regex-test.js * es6-test[ResourceLoader|requiresES6]|es6-test.js * throwError[ResourceLoader|dependencies=mediawiki.util]|throwError.js * tabbedwindow[ResourceLoader|default|dependencies=mediawiki.Title]|tabbedwindow.js * markblocked[ResourceLoader|dependencies=mediawiki.util,mediawiki.page.ready]|markblocked.js * djtest[ResourceLoader|skins=minerva]|djtest.js * packagefilebase[ResourceLoader|requiresES6|package|hidden]|packagefilebase-file1.js|packagefilebase-file2.js|packagefilebase-file3.json * packagefileuser[ResourceLoader|requiresES6|package|dependencies=ext.gadget.packagefilebase]|packagefileuser.js * MobileCategories[ResourceLoader|dependencies=mediawiki.api,mediawiki.util|skins=minerva]|MobileCategories.js * Sharer[ResourceLoader]|Sharer.js * citations[ResourceLoader|dependencies=mediawiki.util]|citations.js * watchlist-notice[ResourceLoader|targets=desktop,mobile|default]|watchlist-notice.js * watchlist-notice-core[ResourceLoader|targets=desktop,mobile|dependencies=mediawiki.storage|hidden]|watchlist-notice-core.js * geonotice[ResourceLoader|default]|geonotice.js * geonotice-core[ResourceLoader|package|dependencies=mediawiki.util,mediawiki.storage|hidden]|geonotice-core.js|geonotice-list.json|geonotice-core.css * legacyToolbar [ResourceLoader] |legacyToolbar.js |extra-toolbar-buttons-core.js |refToolbarLegacy.js * refToolbar[ResourceLoader|default|dependencies=mediawiki.util|actions=edit|contentModels=wikitext]|refToolbar.js * refToolbarBase[ResourceLoader|hidden]|refToolbarBase.js * contribsrange[ResourceLoader|dependencies=mediawiki.util,jquery.spinner]|contribsrange.js * another-contribsrange[ResourceLoader|dependencies=mediawiki.util,jquery.spinner]|another-contribsrange.js * charinsert[ResourceLoader]|charinsert.js * charinsert-core[ResourceLoader|hidden|dependencies=jquery.textSelection,user,mediawiki.storage]|charinsert-styles.css|charinsert-core.js * charinsert-old[ResourceLoader]|charinsert-old.js|charinsert-old.css * diffTools[ResourceLoader|dependencies=mediawiki.util]|diffTools.js|diffTools.css * ImagelessTabs[ResourceLoader]|ImagelessTabs.css * fastbuttons[ResourceLoader|dependencies=mediawiki.util]|fastbuttons.js|fastbuttons.css * ExternalTranslate[ResourceLoader|dependencies=jquery,mediawiki.api]|ExternalTranslate.js|ExternalTranslate.html|ExternalTranslate.css * destacar[ResourceLoader]|highlightsUsername.js|highlightsUsername.css * blockNotificationsButton[ResourceLoader|dependencies=mediawiki.api,ext.gadget.mediawiki.api.ptwiki,mediawiki.util,user.options|rights=block]|blockNotificationsButton.js|blockNotificationsButton.css * NewVillagePump[ResourceLoader]|NewVillagePump.js|NewVillagePump.css * mediawiki.api.ptwiki[ResourceLoader|dependencies=mediawiki.api|hidden]|mediawiki.api.ptwiki.js * NewVillagePumpCore[ResourceLoader|dependencies=mediawiki.util,jquery.placeholder,jquery.spinner,ext.gadget.mediawiki.api.ptwiki|hidden]|NewVillagePump.js/Core.js * Navigation_popups [ResourceLoader |dependencies=mediawiki.api, mediawiki.user, mediawiki.util, user.options, mediawiki.jqueryMsg |type=general] |popups.js |navpop.css * teahouse[ResourceLoader|dependencies=mediawiki.user,mediawiki.cookie]|teahouse/main.js|teahouse/config.js|teahouse/teahouse.css * teahouse-opt-in[ResourceLoader]|teahouse-opt-in/main.js * PB[ResourceLoader|dependencies=mediawiki.api,mediawiki.util]|PB.js * Wikimedia Learning Survey[ResourceLoader]|WikimediaL.js * formWizard [ResourceLoader |default |rights=minoredit] |formWizard.js * formWizard-core [ResourceLoader |hidden |dependencies=mediawiki.api, mediawiki.cookie, mediawiki.ui, mediawiki.user, jquery.chosen, jquery.ui, user.options] |formWizard-core.js |formWizard.css * requestForAdminship[ResourceLoader]|requestForAdminship.js * watchUserContribs[ResourceLoader|dependencies=jquery.ui,mediawiki.util,mediawiki.ui.button,ext.gadget.TipsyDeprecated]|watchUserContribs.js|watchUserContribs.css * WatchlistGreenIndicators[ResourceLoader|skins=vector]|WatchlistGreenIndicators.css * WatchlistChangesBold[ResourceLoader]|WatchlistChangesBold.css * Hotcat[ResourceLoader|rights=edit]|HotCat.js * RevisionSlider[ResourceLoader|dependencies=jquery.ui,mediawiki.api,mediawiki.util]|revisionslider.js|revisionslider.css * toolbartocnav[ResourceLoader|dependencies=ext.wikiEditor]|toolbartocnav.css|toolbartocnav.js * purgetab[ResourceLoader|dependencies=mediawiki.util,mediawiki.api]|purgetab.js * databoxEditor[ResourceLoader|dependencies=jquery.client,jquery.mwEmbedUtil,mw.MwEmbedSupport,jquery.ui]|databoxeditor.js * wikEd[ResourceLoader]|wikEd.js * revisionsSysopsActions[ResourceLoader|dependencies=mediawiki.util,ext.gadget.mediawiki.api.ptwiki,jquery.placeholder]|revisionsSysopsActions.js * validateBlockRollbackers[ResourceLoader]|validateBlockRollbackers.js * watchlist[ResourceLoader|top]|watchlist.js * addsection-plus[ResourceLoader|skins=monobook,vector]|addsection-plus.css * CleanDeleteReasons[ResourceLoader|default|rights=delete]|CleanDeleteReasons.js * contentFeatured[ResourceLoader|dependencies=mediawiki.util,ext.gadget.mediawiki.api.ptwiki,jquery.ui]|contentFeatured.js|contentFeatured.css * easyPeerReview[ResourceLoader|rights=review|dependencies=mediawiki.util]|easyPeerReview.js * UTCLiveClock[ResourceLoader|type=general|dependencies=mediawiki.util,mediawiki.api|peers=UTCLiveClock-pagestyles]|UTCLiveClock.js|UTCLiveClock.css * UTCLiveClock-pagestyles[hidden|skins=vector,monobook]|UTCLiveClock-pagestyles.css * afchelper [ResourceLoader |dependencies=mediawiki.api, mediawiki.util, mediawiki.user, jquery.chosen, jquery.spinner, jquery.ui |namespaces=2, 118] |afchelper.js |afchelper.css * Shortdesc-helper-loader[ResourceLoader|dependencies=mediawiki.api,user.options,mediawiki.util|skins=vector,monobook,modern,timeless|peers=Shortdesc-helper-pagestyles-vector]|Shortdesc-helper.js * Shortdesc-helper-pagestyles-vector[hidden|skins=vector]|Shortdesc-helper-pagestyles-vector.css * MoreMenu-local[ResourceLoader|dependencies=mediawiki.api,mediawiki.util,mediawiki.Title,user.options|peers=MoreMenu-local-pagestyles]|MoreMenu.js * MoreMenu-local-pagestyles[hidden]|MoreMenu-pagestyles.css * scribe[ResourceLoader|dependencies=ext.visualEditor.core,mediawiki.api]| scribe.js|scribe.css * scribe-v2[ResourceLoader|dependencies=ext.visualEditor.core,mediawiki.api]| scribe-v2.js|scribe-v2.css * XFDcloser[ResourceLoader|dependencies=mediawiki.user|type=general]|XFDcloser.js * XFDcloser-core[ResourceLoader|dependencies=mediawiki.util,mediawiki.api,mediawiki.Title,oojs-ui-core,oojs-ui-widgets,oojs-ui-windows,oojs-ui.styles.icons-interactions,oojs-ui.styles.icons-content,oojs-ui.styles.icons-moderation,oojs-ui.styles.icons-alerts|hidden|type=general]|XFDcloser-core.js|XFDcloser-core.css * XFDcloser-core-beta[ResourceLoader|dependencies=mediawiki.util,mediawiki.api,mediawiki.Title,oojs-ui-core,oojs-ui-widgets,oojs-ui-windows,oojs-ui.styles.icons-interactions,oojs-ui.styles.icons-content,oojs-ui.styles.icons-moderation,oojs-ui.styles.icons-alerts|hidden|type=general]|XFDcloser-core-beta.js|XFDcloser-core-beta.css * libExtraUtil[ResourceLoader|hidden]|libExtraUtil.js * GoogleImagesTineye [ResourceLoader|dependencies=mediawiki.util]|GoogleImagesTineye.js * ShowJavascriptErrors[ResourceLoader|type=general]|ShowJavascriptErrors.js * lastEditUser[ResourceLoader|dependencies=mediawiki.util]|lastEditUser.js * dark-mode-toggle[ResourceLoader|targets=desktop,mobile|dependencies=mediawiki.util,mediawiki.api,mediawiki.Uri,mediawiki.storage|peers=dark-mode-toggle-pagestyles]|dark-mode-toggle.js * dark-mode-toggle-pagestyles[hidden|targets=desktop,mobile|skins=vector,vector-2022,minerva,monobook]|dark-mode-toggle-pagestyles.css * dark-mode[ResourceLoader|supportsUrlLoad|targets=desktop,mobile|skins=vector,vector-2022,monobook,modern,minerva,timeless]|dark-mode.css * addMe[ResourceLoader|default|dependencies=oojs-ui,mediawiki.api,mediawiki.util,mediawiki.jqueryMsg]|addMe.js * AutosuggestSitelink-local[ResourceLoader|dependencies=mediawiki.action.view.postEdit,mediawiki.ForeignApi,mediawiki.Title,oojs-ui-core,oojs-ui-windows]|AutosuggestSitelink.js * WpLibExtraDev[ResourceLoader|hidden]|WpLibExtraDev.js * MarkBLocked-core[ResourceLoader|hidden|dependencies=mediawiki.user,mediawiki.api,mediawiki.ForeignApi,mediawiki.storage,mediawiki.util,jquery.ui,oojs-ui,oojs-ui.styles.icons-moderation]|MarkBLocked-core.js|MarkBLocked-core.css * MarkBLocked[ResourceLoader|supportsUrlLoad|package|dependencies=mediawiki.user,mediawiki.api,mediawiki.ForeignApi,mediawiki.storage,mediawiki.util,jquery.ui,oojs-ui,oojs-ui.styles.icons-moderation]|MarkBLocked.js|MarkBLocked-core.js|MarkBLocked-core.css * MassRevisionDelete[ResourceLoader|rights=deleterevision|dependencies=jquery.makeCollapsible,oojs-ui,oojs-ui.styles.icons-movement,mediawiki.api]|MassRevisionDelete.js * edit-styles[ResourceLoader| actions=edit|type=styles]|edit-styles.css * firstedit-test[ResourceLoader]|firstedit-test.js * firstedit-short-test[ResourceLoader]|firstedit-short-test.js * section-share[ResourceLoader|default]|section-share.js ==Wikivoyage-Experimental== * Carousel[ResourceLoader|type=general|dependencies=mediawiki.util|targets=desktop,mobile]|Carousel.js|Carousel.css == modules == * fastButtonsCore[ResourceLoader|dependencies=mediawiki.api,ext.gadget.mediawiki.api.ptwiki,mediawiki.page.ready,jquery.ui,mediawiki.cookie]|fastbuttons.js/core.js * diffToolsCore[ResourceLoader|dependencies=mediawiki.api,mediawiki.util,user.options,ext.gadget.mediawiki.api.ptwiki,jquery.ui]|diffTools.js/core.js * validateBlockRollbackersCore[ResourceLoader|dependencies=mediawiki.util]|validateBlockRollbackers.js/core.js * requestForAdminshipCore[ResourceLoader|dependencies=ext.gadget.mediawiki.api.ptwiki,jquery.ui]|requestForAdminship.js/core.js|requestForAdminship.css * TipsyDeprecated[ResourceLoader|hidden]|tipsyDeprecated.js == arwiki == * changlist[ResourceLoader]|changlist.css == Old-tests == * backgroundTest[ResourceLoader|top|type=styles]|backgroundTest.css == ruwiki == * ruwiki-test[ResourceLoader]|ruwiki-test.js * ruwiki-core[ResourceLoader]|ruwiki-core.js * ruwiki-common-action-edit[ResourceLoader|dependencies=user.options]|ruwiki-common-action-edit.js * ruwiki-common-namespace-file[ResourceLoader|hidden]|ruwiki-common-namespace-file.js * ruwiki-common-action-history[ResourceLoader|hidden]|ruwiki-common-action-history.js * ruwiki-common-special-delete[ResourceLoader]|ruwiki-common-special-delete.js‎ * ruwiki-common-special-block[ResourceLoader|type=general]|ruwiki-common-special-block.js‎|ruwiki-common-special-block.css * ruwiki-common-special-log[ResourceLoader]|ruwiki-common-special-log.js‎ * ruwiki-common-special-newpages[ResourceLoader]|ruwiki-common-special-newpages.js‎ * ruwiki-common-special-movepage[ResourceLoader]|ruwiki-common-special-movepage.js‎ * ruwiki-common-special-watchlist[ResourceLoader]|ruwiki-common-special-watchlist.js‎ * ruwiki-common-special-search[ResourceLoader]|ruwiki-common-special-search.js‎ * ruwiki-common-special-upload[ResourceLoader]|ruwiki-common-special-upload.js‎ * ruwiki-wikificator[ResourceLoader|dependencies=user.options,jquery.textSelection,ext.gadget.ruwiki-registerTool]|ruwiki-wikificator.js * ruwiki-summaryButtons[ResourceLoader|type=general|hidden]|ruwiki-summaryButtons.js|ruwiki-summaryButtons.css * ruwiki-registerTool[ResourceLoader|hidden|dependencies=user.options]|ruwiki-registerTool.js * ruwiki-urldecoder[ResourceLoader|dependencies=ext.gadget.ruwiki-registerTool]|ruwiki-urldecoder.js === ruwiki-iw === * ruwiki-iwcore[ResourceLoader|hidden|type=general]|ruwiki-iwcore.js|ruwiki-iwcore.css * ruwiki-iwlocalnames[ResourceLoader|dependencies=ext.gadget.ruwiki-iwcore]|ruwiki-iwlocalnames.js * ruwiki-iwhints[ResourceLoader|dependencies=ext.gadget.ruwiki-iwcore]|ruwiki-iwhints.js * ruwiki-iwen[ResourceLoader|dependencies=ext.gadget.ruwiki-iwcore]|ruwiki-iwen.js * ruwiki-iwrussia[ResourceLoader|dependencies=ext.gadget.ruwiki-iwcore]|ruwiki-iwrussia.js == nowiki == * template-wizzard[ResourceLoader|rights=edit|type=general]|template-wizzard.js == azwiki == * Katalitik[ResourceLoader]|Katalitik.js * XTools-ArticleInfo[ResourceLoader]|XTools-ArticleInfo.js * addsection-plus[ResourceLoader]|addsection-plus.js * markAdmins[ResourceLoader|dependencies=mediawiki.util]|markAdmins.js * directLinkToCommons[ResourceLoader|dependencies=mediawiki.util]|directLinkToCommons.js * switcher[ResourceLoader|targets=desktop,mobile]|switcher.js * patrolRevisions[ResourceLoader|dependencies=mediawiki.api,mediawiki.util|rights=patrol]|patrolRevisions.js == fawiki == * ScriptOne[ResourceLoader]|ScriptOne.js * ScriptTwo[ResourceLoader]|ScriptTwo.js|ScriptTwo.css * ScriptHidden[hidden]|ScriptHidden.css * ScriptThree[ResourceLoader|dependencies=mediawiki.api|peers=ScriptHidden]|ScriptThree.js * Morebits-i18n[ResourceLoader|dependencies=ext.gadget.morebitsV3,jquery.i18n]|Morebits-i18n.js == bnwiki == *markAdmins[ResourceLoader|dependencies=mediawiki.util]|markAdmins.js * DiscussionCloser[ResourceLoader|dependencies=mediawiki.util]|DiscussionCloser.js|DiscussionCloser.css * Twinkle-bn[ResourceLoader|dependencies=ext.gadget.morebits-bn,ext.gadget.select2-bn|rights=autoconfirmed|type=general|peers=Twinkle-pagestyles-bn]|Twinkle-bn.js|twinkleprod-bn.js|twinkleimage-bn.js|twinklebatchundelete-bn.js|twinklewarn-bn.js|twinklespeedy-bn.js|friendlyshared-bn.js|twinklediff-bn.js|twinkleunlink-bn.js|friendlytag-bn.js|twinkledeprod-bn.js|friendlywelcome-bn.js|twinklexfd-bn.js|twinklebatchdelete-bn.js|twinklebatchprotect-bn.js|twinkleconfig-bn.js|twinklefluff-bn.js|twinkleprotect-bn.js|twinklearv-bn.js|twinkleblock-bn.js|friendlytalkback-bn.js|Twinkle-bn.css * morebits-bn[ResourceLoader|dependencies=mediawiki.user,mediawiki.util,jquery.ui|hidden]|morebits-bn.js|morebits-bn.css * Twinkle-pagestyles-bn[hidden|skins=vector]|Twinkle-pagestyles-bn.css * select2-bn[ResourceLoader|hidden]|select2.min-bn.js|select2.min-bn.css ==bnwiktionary== * Rep2Ad[ResourceLoader]|Rep2Ad.js ==ukwiki== * Wikificator[ResourceLoader|hidden]|Wikificator.js * Onlyifediting[ResourceLoader|action=edit|dependencies=ext.visualEditor.desktopArticleTarget.init,ext.gadget.Wikificator]|Onlyifediting.js * PostBlockActions[ResourceLoader|namespaces=-1]|PostBlockActions.js * ImgsCleanUp[ResourceLoader|package|dependencies=mediawiki.util,vue,@wikimedia/codex|rights=autoconfirmed|namespaces=6]|ImgsCleanUp.js|ImgsCleanUp-main.vue * valcio[ResourceLoader|dependencies=vue,codex]|valcio.js jcw7e6gmp163dc1l2dg0twxele3h7ui 741002 741001 2026-05-08T15:39:39Z Valcio 46860 test 741002 wikitext text/x-wiki <noinclude>{{collapse|1={{#invoke:validate gadgets|validate}}|title=Issues in gadget definitions}}</noinclude> == Twinkle == * Twinkle [ResourceLoader |dependencies=ext.gadget.morebits, ext.gadget.select2, mediawiki.api, mediawiki.language |rights=autoconfirmed |type=general |peers=Twinkle-pagestyles] |Twinkle.js |Twinkle.css |twinklearv.js |twinklewarn.js |twinkleblock.js |twinklewelcome.js |twinkletalkback.js |twinklespeedy.js |twinkleprod.js |twinklexfd.js |twinkleimage.js |twinkleprotect.js |twinkletag.js |twinklediff.js |twinkleunlink.js |twinklerollback.js |twinkledeprod.js |twinklebatchdelete.js |twinklebatchprotect.js |twinklebatchundelete.js |twinkleconfig.js * morebits [ResourceLoader |dependencies=mediawiki.user, mediawiki.util, mediawiki.Title |hidden] |morebits.js |morebits.css * Twinkle-pagestyles [hidden |skins=vector, vector-2022] |Twinkle-pagestyles.css * select2 [ResourceLoader |hidden] |select2.min.js |select2.min.css *morebitsV3[ResourceLoader|dependencies=mediawiki.user,mediawiki.util,mediawiki.Title,jquery.ui|hidden]|morebitsV3.js|morebitsV3.css *twinkle-enwiki[ResourceLoader|dependencies=ext.gadget.morebitsV3,ext.gadget.select2,mediawiki.api,mediawiki.storage,mediawiki.libs.pluralruleparser|peers=Twinkle-pagestyles]|TwinkleV3.js|TwinkleV3.css *twinkle-starter[ResourceLoader|dependencies=ext.gadget.morebitsV3,ext.gadget.select2,mediawiki.api,mediawiki.storage|peers=Twinkle-pagestyles]|Twinkle-starter.js|Twinkle-starter.css *orange-i18n [ ResourceLoader | dependencies = mediawiki.libs.pluralruleparser ] | orange-i18n.js *banana-i18n [ ResourceLoader ] | banana-i18n.js == Recent-Tests == * nomin-test[ResourceLoader|requiresES6] | nomin-test.js * regex-test[ResourceLoader]|regex-test.js * es6-test[ResourceLoader|requiresES6]|es6-test.js * throwError[ResourceLoader|dependencies=mediawiki.util]|throwError.js * tabbedwindow[ResourceLoader|default|dependencies=mediawiki.Title]|tabbedwindow.js * markblocked[ResourceLoader|dependencies=mediawiki.util,mediawiki.page.ready]|markblocked.js * djtest[ResourceLoader|skins=minerva]|djtest.js * packagefilebase[ResourceLoader|requiresES6|package|hidden]|packagefilebase-file1.js|packagefilebase-file2.js|packagefilebase-file3.json * packagefileuser[ResourceLoader|requiresES6|package|dependencies=ext.gadget.packagefilebase]|packagefileuser.js * MobileCategories[ResourceLoader|dependencies=mediawiki.api,mediawiki.util|skins=minerva]|MobileCategories.js * Sharer[ResourceLoader]|Sharer.js * citations[ResourceLoader|dependencies=mediawiki.util]|citations.js * watchlist-notice[ResourceLoader|targets=desktop,mobile|default]|watchlist-notice.js * watchlist-notice-core[ResourceLoader|targets=desktop,mobile|dependencies=mediawiki.storage|hidden]|watchlist-notice-core.js * geonotice[ResourceLoader|default]|geonotice.js * geonotice-core[ResourceLoader|package|dependencies=mediawiki.util,mediawiki.storage|hidden]|geonotice-core.js|geonotice-list.json|geonotice-core.css * legacyToolbar [ResourceLoader] |legacyToolbar.js |extra-toolbar-buttons-core.js |refToolbarLegacy.js * refToolbar[ResourceLoader|default|dependencies=mediawiki.util|actions=edit|contentModels=wikitext]|refToolbar.js * refToolbarBase[ResourceLoader|hidden]|refToolbarBase.js * contribsrange[ResourceLoader|dependencies=mediawiki.util,jquery.spinner]|contribsrange.js * another-contribsrange[ResourceLoader|dependencies=mediawiki.util,jquery.spinner]|another-contribsrange.js * charinsert[ResourceLoader]|charinsert.js * charinsert-core[ResourceLoader|hidden|dependencies=jquery.textSelection,user,mediawiki.storage]|charinsert-styles.css|charinsert-core.js * charinsert-old[ResourceLoader]|charinsert-old.js|charinsert-old.css * diffTools[ResourceLoader|dependencies=mediawiki.util]|diffTools.js|diffTools.css * ImagelessTabs[ResourceLoader]|ImagelessTabs.css * fastbuttons[ResourceLoader|dependencies=mediawiki.util]|fastbuttons.js|fastbuttons.css * ExternalTranslate[ResourceLoader|dependencies=jquery,mediawiki.api]|ExternalTranslate.js|ExternalTranslate.html|ExternalTranslate.css * destacar[ResourceLoader]|highlightsUsername.js|highlightsUsername.css * blockNotificationsButton[ResourceLoader|dependencies=mediawiki.api,ext.gadget.mediawiki.api.ptwiki,mediawiki.util,user.options|rights=block]|blockNotificationsButton.js|blockNotificationsButton.css * NewVillagePump[ResourceLoader]|NewVillagePump.js|NewVillagePump.css * mediawiki.api.ptwiki[ResourceLoader|dependencies=mediawiki.api|hidden]|mediawiki.api.ptwiki.js * NewVillagePumpCore[ResourceLoader|dependencies=mediawiki.util,jquery.placeholder,jquery.spinner,ext.gadget.mediawiki.api.ptwiki|hidden]|NewVillagePump.js/Core.js * Navigation_popups [ResourceLoader |dependencies=mediawiki.api, mediawiki.user, mediawiki.util, user.options, mediawiki.jqueryMsg |type=general] |popups.js |navpop.css * teahouse[ResourceLoader|dependencies=mediawiki.user,mediawiki.cookie]|teahouse/main.js|teahouse/config.js|teahouse/teahouse.css * teahouse-opt-in[ResourceLoader]|teahouse-opt-in/main.js * PB[ResourceLoader|dependencies=mediawiki.api,mediawiki.util]|PB.js * Wikimedia Learning Survey[ResourceLoader]|WikimediaL.js * formWizard [ResourceLoader |default |rights=minoredit] |formWizard.js * formWizard-core [ResourceLoader |hidden |dependencies=mediawiki.api, mediawiki.cookie, mediawiki.ui, mediawiki.user, jquery.chosen, jquery.ui, user.options] |formWizard-core.js |formWizard.css * requestForAdminship[ResourceLoader]|requestForAdminship.js * watchUserContribs[ResourceLoader|dependencies=jquery.ui,mediawiki.util,mediawiki.ui.button,ext.gadget.TipsyDeprecated]|watchUserContribs.js|watchUserContribs.css * WatchlistGreenIndicators[ResourceLoader|skins=vector]|WatchlistGreenIndicators.css * WatchlistChangesBold[ResourceLoader]|WatchlistChangesBold.css * Hotcat[ResourceLoader|rights=edit]|HotCat.js * RevisionSlider[ResourceLoader|dependencies=jquery.ui,mediawiki.api,mediawiki.util]|revisionslider.js|revisionslider.css * toolbartocnav[ResourceLoader|dependencies=ext.wikiEditor]|toolbartocnav.css|toolbartocnav.js * purgetab[ResourceLoader|dependencies=mediawiki.util,mediawiki.api]|purgetab.js * databoxEditor[ResourceLoader|dependencies=jquery.client,jquery.mwEmbedUtil,mw.MwEmbedSupport,jquery.ui]|databoxeditor.js * wikEd[ResourceLoader]|wikEd.js * revisionsSysopsActions[ResourceLoader|dependencies=mediawiki.util,ext.gadget.mediawiki.api.ptwiki,jquery.placeholder]|revisionsSysopsActions.js * validateBlockRollbackers[ResourceLoader]|validateBlockRollbackers.js * watchlist[ResourceLoader|top]|watchlist.js * addsection-plus[ResourceLoader|skins=monobook,vector]|addsection-plus.css * CleanDeleteReasons[ResourceLoader|default|rights=delete]|CleanDeleteReasons.js * contentFeatured[ResourceLoader|dependencies=mediawiki.util,ext.gadget.mediawiki.api.ptwiki,jquery.ui]|contentFeatured.js|contentFeatured.css * easyPeerReview[ResourceLoader|rights=review|dependencies=mediawiki.util]|easyPeerReview.js * UTCLiveClock[ResourceLoader|type=general|dependencies=mediawiki.util,mediawiki.api|peers=UTCLiveClock-pagestyles]|UTCLiveClock.js|UTCLiveClock.css * UTCLiveClock-pagestyles[hidden|skins=vector,monobook]|UTCLiveClock-pagestyles.css * afchelper [ResourceLoader |dependencies=mediawiki.api, mediawiki.util, mediawiki.user, jquery.chosen, jquery.spinner, jquery.ui |namespaces=2, 118] |afchelper.js |afchelper.css * Shortdesc-helper-loader[ResourceLoader|dependencies=mediawiki.api,user.options,mediawiki.util|skins=vector,monobook,modern,timeless|peers=Shortdesc-helper-pagestyles-vector]|Shortdesc-helper.js * Shortdesc-helper-pagestyles-vector[hidden|skins=vector]|Shortdesc-helper-pagestyles-vector.css * MoreMenu-local[ResourceLoader|dependencies=mediawiki.api,mediawiki.util,mediawiki.Title,user.options|peers=MoreMenu-local-pagestyles]|MoreMenu.js * MoreMenu-local-pagestyles[hidden]|MoreMenu-pagestyles.css * scribe[ResourceLoader|dependencies=ext.visualEditor.core,mediawiki.api]| scribe.js|scribe.css * scribe-v2[ResourceLoader|dependencies=ext.visualEditor.core,mediawiki.api]| scribe-v2.js|scribe-v2.css * XFDcloser[ResourceLoader|dependencies=mediawiki.user|type=general]|XFDcloser.js * XFDcloser-core[ResourceLoader|dependencies=mediawiki.util,mediawiki.api,mediawiki.Title,oojs-ui-core,oojs-ui-widgets,oojs-ui-windows,oojs-ui.styles.icons-interactions,oojs-ui.styles.icons-content,oojs-ui.styles.icons-moderation,oojs-ui.styles.icons-alerts|hidden|type=general]|XFDcloser-core.js|XFDcloser-core.css * XFDcloser-core-beta[ResourceLoader|dependencies=mediawiki.util,mediawiki.api,mediawiki.Title,oojs-ui-core,oojs-ui-widgets,oojs-ui-windows,oojs-ui.styles.icons-interactions,oojs-ui.styles.icons-content,oojs-ui.styles.icons-moderation,oojs-ui.styles.icons-alerts|hidden|type=general]|XFDcloser-core-beta.js|XFDcloser-core-beta.css * libExtraUtil[ResourceLoader|hidden]|libExtraUtil.js * GoogleImagesTineye [ResourceLoader|dependencies=mediawiki.util]|GoogleImagesTineye.js * ShowJavascriptErrors[ResourceLoader|type=general]|ShowJavascriptErrors.js * lastEditUser[ResourceLoader|dependencies=mediawiki.util]|lastEditUser.js * dark-mode-toggle[ResourceLoader|targets=desktop,mobile|dependencies=mediawiki.util,mediawiki.api,mediawiki.Uri,mediawiki.storage|peers=dark-mode-toggle-pagestyles]|dark-mode-toggle.js * dark-mode-toggle-pagestyles[hidden|targets=desktop,mobile|skins=vector,vector-2022,minerva,monobook]|dark-mode-toggle-pagestyles.css * dark-mode[ResourceLoader|supportsUrlLoad|targets=desktop,mobile|skins=vector,vector-2022,monobook,modern,minerva,timeless]|dark-mode.css * addMe[ResourceLoader|default|dependencies=oojs-ui,mediawiki.api,mediawiki.util,mediawiki.jqueryMsg]|addMe.js * AutosuggestSitelink-local[ResourceLoader|dependencies=mediawiki.action.view.postEdit,mediawiki.ForeignApi,mediawiki.Title,oojs-ui-core,oojs-ui-windows]|AutosuggestSitelink.js * WpLibExtraDev[ResourceLoader|hidden]|WpLibExtraDev.js * MarkBLocked-core[ResourceLoader|hidden|dependencies=mediawiki.user,mediawiki.api,mediawiki.ForeignApi,mediawiki.storage,mediawiki.util,jquery.ui,oojs-ui,oojs-ui.styles.icons-moderation]|MarkBLocked-core.js|MarkBLocked-core.css * MarkBLocked[ResourceLoader|supportsUrlLoad|package|dependencies=mediawiki.user,mediawiki.api,mediawiki.ForeignApi,mediawiki.storage,mediawiki.util,jquery.ui,oojs-ui,oojs-ui.styles.icons-moderation]|MarkBLocked.js|MarkBLocked-core.js|MarkBLocked-core.css * MassRevisionDelete[ResourceLoader|rights=deleterevision|dependencies=jquery.makeCollapsible,oojs-ui,oojs-ui.styles.icons-movement,mediawiki.api]|MassRevisionDelete.js * edit-styles[ResourceLoader| actions=edit|type=styles]|edit-styles.css * firstedit-test[ResourceLoader]|firstedit-test.js * firstedit-short-test[ResourceLoader]|firstedit-short-test.js * section-share[ResourceLoader|default]|section-share.js ==Wikivoyage-Experimental== * Carousel[ResourceLoader|type=general|dependencies=mediawiki.util|targets=desktop,mobile]|Carousel.js|Carousel.css == modules == * fastButtonsCore[ResourceLoader|dependencies=mediawiki.api,ext.gadget.mediawiki.api.ptwiki,mediawiki.page.ready,jquery.ui,mediawiki.cookie]|fastbuttons.js/core.js * diffToolsCore[ResourceLoader|dependencies=mediawiki.api,mediawiki.util,user.options,ext.gadget.mediawiki.api.ptwiki,jquery.ui]|diffTools.js/core.js * validateBlockRollbackersCore[ResourceLoader|dependencies=mediawiki.util]|validateBlockRollbackers.js/core.js * requestForAdminshipCore[ResourceLoader|dependencies=ext.gadget.mediawiki.api.ptwiki,jquery.ui]|requestForAdminship.js/core.js|requestForAdminship.css * TipsyDeprecated[ResourceLoader|hidden]|tipsyDeprecated.js == arwiki == * changlist[ResourceLoader]|changlist.css == Old-tests == * backgroundTest[ResourceLoader|top|type=styles]|backgroundTest.css == ruwiki == * ruwiki-test[ResourceLoader]|ruwiki-test.js * ruwiki-core[ResourceLoader]|ruwiki-core.js * ruwiki-common-action-edit[ResourceLoader|dependencies=user.options]|ruwiki-common-action-edit.js * ruwiki-common-namespace-file[ResourceLoader|hidden]|ruwiki-common-namespace-file.js * ruwiki-common-action-history[ResourceLoader|hidden]|ruwiki-common-action-history.js * ruwiki-common-special-delete[ResourceLoader]|ruwiki-common-special-delete.js‎ * ruwiki-common-special-block[ResourceLoader|type=general]|ruwiki-common-special-block.js‎|ruwiki-common-special-block.css * ruwiki-common-special-log[ResourceLoader]|ruwiki-common-special-log.js‎ * ruwiki-common-special-newpages[ResourceLoader]|ruwiki-common-special-newpages.js‎ * ruwiki-common-special-movepage[ResourceLoader]|ruwiki-common-special-movepage.js‎ * ruwiki-common-special-watchlist[ResourceLoader]|ruwiki-common-special-watchlist.js‎ * ruwiki-common-special-search[ResourceLoader]|ruwiki-common-special-search.js‎ * ruwiki-common-special-upload[ResourceLoader]|ruwiki-common-special-upload.js‎ * ruwiki-wikificator[ResourceLoader|dependencies=user.options,jquery.textSelection,ext.gadget.ruwiki-registerTool]|ruwiki-wikificator.js * ruwiki-summaryButtons[ResourceLoader|type=general|hidden]|ruwiki-summaryButtons.js|ruwiki-summaryButtons.css * ruwiki-registerTool[ResourceLoader|hidden|dependencies=user.options]|ruwiki-registerTool.js * ruwiki-urldecoder[ResourceLoader|dependencies=ext.gadget.ruwiki-registerTool]|ruwiki-urldecoder.js === ruwiki-iw === * ruwiki-iwcore[ResourceLoader|hidden|type=general]|ruwiki-iwcore.js|ruwiki-iwcore.css * ruwiki-iwlocalnames[ResourceLoader|dependencies=ext.gadget.ruwiki-iwcore]|ruwiki-iwlocalnames.js * ruwiki-iwhints[ResourceLoader|dependencies=ext.gadget.ruwiki-iwcore]|ruwiki-iwhints.js * ruwiki-iwen[ResourceLoader|dependencies=ext.gadget.ruwiki-iwcore]|ruwiki-iwen.js * ruwiki-iwrussia[ResourceLoader|dependencies=ext.gadget.ruwiki-iwcore]|ruwiki-iwrussia.js == nowiki == * template-wizzard[ResourceLoader|rights=edit|type=general]|template-wizzard.js == azwiki == * Katalitik[ResourceLoader]|Katalitik.js * XTools-ArticleInfo[ResourceLoader]|XTools-ArticleInfo.js * addsection-plus[ResourceLoader]|addsection-plus.js * markAdmins[ResourceLoader|dependencies=mediawiki.util]|markAdmins.js * directLinkToCommons[ResourceLoader|dependencies=mediawiki.util]|directLinkToCommons.js * switcher[ResourceLoader|targets=desktop,mobile]|switcher.js * patrolRevisions[ResourceLoader|dependencies=mediawiki.api,mediawiki.util|rights=patrol]|patrolRevisions.js == fawiki == * ScriptOne[ResourceLoader]|ScriptOne.js * ScriptTwo[ResourceLoader]|ScriptTwo.js|ScriptTwo.css * ScriptHidden[hidden]|ScriptHidden.css * ScriptThree[ResourceLoader|dependencies=mediawiki.api|peers=ScriptHidden]|ScriptThree.js * Morebits-i18n[ResourceLoader|dependencies=ext.gadget.morebitsV3,jquery.i18n]|Morebits-i18n.js == bnwiki == *markAdmins[ResourceLoader|dependencies=mediawiki.util]|markAdmins.js * DiscussionCloser[ResourceLoader|dependencies=mediawiki.util]|DiscussionCloser.js|DiscussionCloser.css * Twinkle-bn[ResourceLoader|dependencies=ext.gadget.morebits-bn,ext.gadget.select2-bn|rights=autoconfirmed|type=general|peers=Twinkle-pagestyles-bn]|Twinkle-bn.js|twinkleprod-bn.js|twinkleimage-bn.js|twinklebatchundelete-bn.js|twinklewarn-bn.js|twinklespeedy-bn.js|friendlyshared-bn.js|twinklediff-bn.js|twinkleunlink-bn.js|friendlytag-bn.js|twinkledeprod-bn.js|friendlywelcome-bn.js|twinklexfd-bn.js|twinklebatchdelete-bn.js|twinklebatchprotect-bn.js|twinkleconfig-bn.js|twinklefluff-bn.js|twinkleprotect-bn.js|twinklearv-bn.js|twinkleblock-bn.js|friendlytalkback-bn.js|Twinkle-bn.css * morebits-bn[ResourceLoader|dependencies=mediawiki.user,mediawiki.util,jquery.ui|hidden]|morebits-bn.js|morebits-bn.css * Twinkle-pagestyles-bn[hidden|skins=vector]|Twinkle-pagestyles-bn.css * select2-bn[ResourceLoader|hidden]|select2.min-bn.js|select2.min-bn.css ==bnwiktionary== * Rep2Ad[ResourceLoader]|Rep2Ad.js ==ukwiki== * Wikificator[ResourceLoader|hidden]|Wikificator.js * Onlyifediting[ResourceLoader|action=edit|dependencies=ext.visualEditor.desktopArticleTarget.init,ext.gadget.Wikificator]|Onlyifediting.js * PostBlockActions[ResourceLoader|namespaces=-1]|PostBlockActions.js * ImgsCleanUp[ResourceLoader|package|dependencies=mediawiki.util,vue,@wikimedia/codex|rights=autoconfirmed|namespaces=6]|ImgsCleanUp.js|ImgsCleanUp-main.vue * valcio[ResourceLoader|dependencies=vue,codex]|valcio.js * codexTableBuilder [ResourceLoader | dependencies=vue,@wikimedia/codex | rights=edit] | codexTableBuilder.js | codexTableBuilder.css 5xsxp44n4nkctrg0j0icu4qezfbu8sv 741003 741002 2026-05-08T15:42:07Z Valcio 46860 + 741003 wikitext text/x-wiki <noinclude>{{collapse|1={{#invoke:validate gadgets|validate}}|title=Issues in gadget definitions}}</noinclude> == Twinkle == * Twinkle [ResourceLoader |dependencies=ext.gadget.morebits, ext.gadget.select2, mediawiki.api, mediawiki.language |rights=autoconfirmed |type=general |peers=Twinkle-pagestyles] |Twinkle.js |Twinkle.css |twinklearv.js |twinklewarn.js |twinkleblock.js |twinklewelcome.js |twinkletalkback.js |twinklespeedy.js |twinkleprod.js |twinklexfd.js |twinkleimage.js |twinkleprotect.js |twinkletag.js |twinklediff.js |twinkleunlink.js |twinklerollback.js |twinkledeprod.js |twinklebatchdelete.js |twinklebatchprotect.js |twinklebatchundelete.js |twinkleconfig.js * morebits [ResourceLoader |dependencies=mediawiki.user, mediawiki.util, mediawiki.Title |hidden] |morebits.js |morebits.css * Twinkle-pagestyles [hidden |skins=vector, vector-2022] |Twinkle-pagestyles.css * select2 [ResourceLoader |hidden] |select2.min.js |select2.min.css *morebitsV3[ResourceLoader|dependencies=mediawiki.user,mediawiki.util,mediawiki.Title,jquery.ui|hidden]|morebitsV3.js|morebitsV3.css *twinkle-enwiki[ResourceLoader|dependencies=ext.gadget.morebitsV3,ext.gadget.select2,mediawiki.api,mediawiki.storage,mediawiki.libs.pluralruleparser|peers=Twinkle-pagestyles]|TwinkleV3.js|TwinkleV3.css *twinkle-starter[ResourceLoader|dependencies=ext.gadget.morebitsV3,ext.gadget.select2,mediawiki.api,mediawiki.storage|peers=Twinkle-pagestyles]|Twinkle-starter.js|Twinkle-starter.css *orange-i18n [ ResourceLoader | dependencies = mediawiki.libs.pluralruleparser ] | orange-i18n.js *banana-i18n [ ResourceLoader ] | banana-i18n.js == Recent-Tests == * nomin-test[ResourceLoader|requiresES6] | nomin-test.js * regex-test[ResourceLoader]|regex-test.js * es6-test[ResourceLoader|requiresES6]|es6-test.js * throwError[ResourceLoader|dependencies=mediawiki.util]|throwError.js * tabbedwindow[ResourceLoader|default|dependencies=mediawiki.Title]|tabbedwindow.js * markblocked[ResourceLoader|dependencies=mediawiki.util,mediawiki.page.ready]|markblocked.js * djtest[ResourceLoader|skins=minerva]|djtest.js * packagefilebase[ResourceLoader|requiresES6|package|hidden]|packagefilebase-file1.js|packagefilebase-file2.js|packagefilebase-file3.json * packagefileuser[ResourceLoader|requiresES6|package|dependencies=ext.gadget.packagefilebase]|packagefileuser.js * MobileCategories[ResourceLoader|dependencies=mediawiki.api,mediawiki.util|skins=minerva]|MobileCategories.js * Sharer[ResourceLoader]|Sharer.js * citations[ResourceLoader|dependencies=mediawiki.util]|citations.js * watchlist-notice[ResourceLoader|targets=desktop,mobile|default]|watchlist-notice.js * watchlist-notice-core[ResourceLoader|targets=desktop,mobile|dependencies=mediawiki.storage|hidden]|watchlist-notice-core.js * geonotice[ResourceLoader|default]|geonotice.js * geonotice-core[ResourceLoader|package|dependencies=mediawiki.util,mediawiki.storage|hidden]|geonotice-core.js|geonotice-list.json|geonotice-core.css * legacyToolbar [ResourceLoader] |legacyToolbar.js |extra-toolbar-buttons-core.js |refToolbarLegacy.js * refToolbar[ResourceLoader|default|dependencies=mediawiki.util|actions=edit|contentModels=wikitext]|refToolbar.js * refToolbarBase[ResourceLoader|hidden]|refToolbarBase.js * contribsrange[ResourceLoader|dependencies=mediawiki.util,jquery.spinner]|contribsrange.js * another-contribsrange[ResourceLoader|dependencies=mediawiki.util,jquery.spinner]|another-contribsrange.js * charinsert[ResourceLoader]|charinsert.js * charinsert-core[ResourceLoader|hidden|dependencies=jquery.textSelection,user,mediawiki.storage]|charinsert-styles.css|charinsert-core.js * charinsert-old[ResourceLoader]|charinsert-old.js|charinsert-old.css * diffTools[ResourceLoader|dependencies=mediawiki.util]|diffTools.js|diffTools.css * ImagelessTabs[ResourceLoader]|ImagelessTabs.css * fastbuttons[ResourceLoader|dependencies=mediawiki.util]|fastbuttons.js|fastbuttons.css * ExternalTranslate[ResourceLoader|dependencies=jquery,mediawiki.api]|ExternalTranslate.js|ExternalTranslate.html|ExternalTranslate.css * destacar[ResourceLoader]|highlightsUsername.js|highlightsUsername.css * blockNotificationsButton[ResourceLoader|dependencies=mediawiki.api,ext.gadget.mediawiki.api.ptwiki,mediawiki.util,user.options|rights=block]|blockNotificationsButton.js|blockNotificationsButton.css * NewVillagePump[ResourceLoader]|NewVillagePump.js|NewVillagePump.css * mediawiki.api.ptwiki[ResourceLoader|dependencies=mediawiki.api|hidden]|mediawiki.api.ptwiki.js * NewVillagePumpCore[ResourceLoader|dependencies=mediawiki.util,jquery.placeholder,jquery.spinner,ext.gadget.mediawiki.api.ptwiki|hidden]|NewVillagePump.js/Core.js * Navigation_popups [ResourceLoader |dependencies=mediawiki.api, mediawiki.user, mediawiki.util, user.options, mediawiki.jqueryMsg |type=general] |popups.js |navpop.css * teahouse[ResourceLoader|dependencies=mediawiki.user,mediawiki.cookie]|teahouse/main.js|teahouse/config.js|teahouse/teahouse.css * teahouse-opt-in[ResourceLoader]|teahouse-opt-in/main.js * PB[ResourceLoader|dependencies=mediawiki.api,mediawiki.util]|PB.js * Wikimedia Learning Survey[ResourceLoader]|WikimediaL.js * formWizard [ResourceLoader |default |rights=minoredit] |formWizard.js * formWizard-core [ResourceLoader |hidden |dependencies=mediawiki.api, mediawiki.cookie, mediawiki.ui, mediawiki.user, jquery.chosen, jquery.ui, user.options] |formWizard-core.js |formWizard.css * requestForAdminship[ResourceLoader]|requestForAdminship.js * watchUserContribs[ResourceLoader|dependencies=jquery.ui,mediawiki.util,mediawiki.ui.button,ext.gadget.TipsyDeprecated]|watchUserContribs.js|watchUserContribs.css * WatchlistGreenIndicators[ResourceLoader|skins=vector]|WatchlistGreenIndicators.css * WatchlistChangesBold[ResourceLoader]|WatchlistChangesBold.css * Hotcat[ResourceLoader|rights=edit]|HotCat.js * RevisionSlider[ResourceLoader|dependencies=jquery.ui,mediawiki.api,mediawiki.util]|revisionslider.js|revisionslider.css * toolbartocnav[ResourceLoader|dependencies=ext.wikiEditor]|toolbartocnav.css|toolbartocnav.js * purgetab[ResourceLoader|dependencies=mediawiki.util,mediawiki.api]|purgetab.js * databoxEditor[ResourceLoader|dependencies=jquery.client,jquery.mwEmbedUtil,mw.MwEmbedSupport,jquery.ui]|databoxeditor.js * wikEd[ResourceLoader]|wikEd.js * revisionsSysopsActions[ResourceLoader|dependencies=mediawiki.util,ext.gadget.mediawiki.api.ptwiki,jquery.placeholder]|revisionsSysopsActions.js * validateBlockRollbackers[ResourceLoader]|validateBlockRollbackers.js * watchlist[ResourceLoader|top]|watchlist.js * addsection-plus[ResourceLoader|skins=monobook,vector]|addsection-plus.css * CleanDeleteReasons[ResourceLoader|default|rights=delete]|CleanDeleteReasons.js * contentFeatured[ResourceLoader|dependencies=mediawiki.util,ext.gadget.mediawiki.api.ptwiki,jquery.ui]|contentFeatured.js|contentFeatured.css * easyPeerReview[ResourceLoader|rights=review|dependencies=mediawiki.util]|easyPeerReview.js * UTCLiveClock[ResourceLoader|type=general|dependencies=mediawiki.util,mediawiki.api|peers=UTCLiveClock-pagestyles]|UTCLiveClock.js|UTCLiveClock.css * UTCLiveClock-pagestyles[hidden|skins=vector,monobook]|UTCLiveClock-pagestyles.css * afchelper [ResourceLoader |dependencies=mediawiki.api, mediawiki.util, mediawiki.user, jquery.chosen, jquery.spinner, jquery.ui |namespaces=2, 118] |afchelper.js |afchelper.css * Shortdesc-helper-loader[ResourceLoader|dependencies=mediawiki.api,user.options,mediawiki.util|skins=vector,monobook,modern,timeless|peers=Shortdesc-helper-pagestyles-vector]|Shortdesc-helper.js * Shortdesc-helper-pagestyles-vector[hidden|skins=vector]|Shortdesc-helper-pagestyles-vector.css * MoreMenu-local[ResourceLoader|dependencies=mediawiki.api,mediawiki.util,mediawiki.Title,user.options|peers=MoreMenu-local-pagestyles]|MoreMenu.js * MoreMenu-local-pagestyles[hidden]|MoreMenu-pagestyles.css * scribe[ResourceLoader|dependencies=ext.visualEditor.core,mediawiki.api]| scribe.js|scribe.css * scribe-v2[ResourceLoader|dependencies=ext.visualEditor.core,mediawiki.api]| scribe-v2.js|scribe-v2.css * XFDcloser[ResourceLoader|dependencies=mediawiki.user|type=general]|XFDcloser.js * XFDcloser-core[ResourceLoader|dependencies=mediawiki.util,mediawiki.api,mediawiki.Title,oojs-ui-core,oojs-ui-widgets,oojs-ui-windows,oojs-ui.styles.icons-interactions,oojs-ui.styles.icons-content,oojs-ui.styles.icons-moderation,oojs-ui.styles.icons-alerts|hidden|type=general]|XFDcloser-core.js|XFDcloser-core.css * XFDcloser-core-beta[ResourceLoader|dependencies=mediawiki.util,mediawiki.api,mediawiki.Title,oojs-ui-core,oojs-ui-widgets,oojs-ui-windows,oojs-ui.styles.icons-interactions,oojs-ui.styles.icons-content,oojs-ui.styles.icons-moderation,oojs-ui.styles.icons-alerts|hidden|type=general]|XFDcloser-core-beta.js|XFDcloser-core-beta.css * libExtraUtil[ResourceLoader|hidden]|libExtraUtil.js * GoogleImagesTineye [ResourceLoader|dependencies=mediawiki.util]|GoogleImagesTineye.js * ShowJavascriptErrors[ResourceLoader|type=general]|ShowJavascriptErrors.js * lastEditUser[ResourceLoader|dependencies=mediawiki.util]|lastEditUser.js * dark-mode-toggle[ResourceLoader|targets=desktop,mobile|dependencies=mediawiki.util,mediawiki.api,mediawiki.Uri,mediawiki.storage|peers=dark-mode-toggle-pagestyles]|dark-mode-toggle.js * dark-mode-toggle-pagestyles[hidden|targets=desktop,mobile|skins=vector,vector-2022,minerva,monobook]|dark-mode-toggle-pagestyles.css * dark-mode[ResourceLoader|supportsUrlLoad|targets=desktop,mobile|skins=vector,vector-2022,monobook,modern,minerva,timeless]|dark-mode.css * addMe[ResourceLoader|default|dependencies=oojs-ui,mediawiki.api,mediawiki.util,mediawiki.jqueryMsg]|addMe.js * AutosuggestSitelink-local[ResourceLoader|dependencies=mediawiki.action.view.postEdit,mediawiki.ForeignApi,mediawiki.Title,oojs-ui-core,oojs-ui-windows]|AutosuggestSitelink.js * WpLibExtraDev[ResourceLoader|hidden]|WpLibExtraDev.js * MarkBLocked-core[ResourceLoader|hidden|dependencies=mediawiki.user,mediawiki.api,mediawiki.ForeignApi,mediawiki.storage,mediawiki.util,jquery.ui,oojs-ui,oojs-ui.styles.icons-moderation]|MarkBLocked-core.js|MarkBLocked-core.css * MarkBLocked[ResourceLoader|supportsUrlLoad|package|dependencies=mediawiki.user,mediawiki.api,mediawiki.ForeignApi,mediawiki.storage,mediawiki.util,jquery.ui,oojs-ui,oojs-ui.styles.icons-moderation]|MarkBLocked.js|MarkBLocked-core.js|MarkBLocked-core.css * MassRevisionDelete[ResourceLoader|rights=deleterevision|dependencies=jquery.makeCollapsible,oojs-ui,oojs-ui.styles.icons-movement,mediawiki.api]|MassRevisionDelete.js * edit-styles[ResourceLoader| actions=edit|type=styles]|edit-styles.css * firstedit-test[ResourceLoader]|firstedit-test.js * firstedit-short-test[ResourceLoader]|firstedit-short-test.js * section-share[ResourceLoader|default]|section-share.js ==Wikivoyage-Experimental== * Carousel[ResourceLoader|type=general|dependencies=mediawiki.util|targets=desktop,mobile]|Carousel.js|Carousel.css == modules == * fastButtonsCore[ResourceLoader|dependencies=mediawiki.api,ext.gadget.mediawiki.api.ptwiki,mediawiki.page.ready,jquery.ui,mediawiki.cookie]|fastbuttons.js/core.js * diffToolsCore[ResourceLoader|dependencies=mediawiki.api,mediawiki.util,user.options,ext.gadget.mediawiki.api.ptwiki,jquery.ui]|diffTools.js/core.js * validateBlockRollbackersCore[ResourceLoader|dependencies=mediawiki.util]|validateBlockRollbackers.js/core.js * requestForAdminshipCore[ResourceLoader|dependencies=ext.gadget.mediawiki.api.ptwiki,jquery.ui]|requestForAdminship.js/core.js|requestForAdminship.css * TipsyDeprecated[ResourceLoader|hidden]|tipsyDeprecated.js == arwiki == * changlist[ResourceLoader]|changlist.css == Old-tests == * backgroundTest[ResourceLoader|top|type=styles]|backgroundTest.css == ruwiki == * ruwiki-test[ResourceLoader]|ruwiki-test.js * ruwiki-core[ResourceLoader]|ruwiki-core.js * ruwiki-common-action-edit[ResourceLoader|dependencies=user.options]|ruwiki-common-action-edit.js * ruwiki-common-namespace-file[ResourceLoader|hidden]|ruwiki-common-namespace-file.js * ruwiki-common-action-history[ResourceLoader|hidden]|ruwiki-common-action-history.js * ruwiki-common-special-delete[ResourceLoader]|ruwiki-common-special-delete.js‎ * ruwiki-common-special-block[ResourceLoader|type=general]|ruwiki-common-special-block.js‎|ruwiki-common-special-block.css * ruwiki-common-special-log[ResourceLoader]|ruwiki-common-special-log.js‎ * ruwiki-common-special-newpages[ResourceLoader]|ruwiki-common-special-newpages.js‎ * ruwiki-common-special-movepage[ResourceLoader]|ruwiki-common-special-movepage.js‎ * ruwiki-common-special-watchlist[ResourceLoader]|ruwiki-common-special-watchlist.js‎ * ruwiki-common-special-search[ResourceLoader]|ruwiki-common-special-search.js‎ * ruwiki-common-special-upload[ResourceLoader]|ruwiki-common-special-upload.js‎ * ruwiki-wikificator[ResourceLoader|dependencies=user.options,jquery.textSelection,ext.gadget.ruwiki-registerTool]|ruwiki-wikificator.js * ruwiki-summaryButtons[ResourceLoader|type=general|hidden]|ruwiki-summaryButtons.js|ruwiki-summaryButtons.css * ruwiki-registerTool[ResourceLoader|hidden|dependencies=user.options]|ruwiki-registerTool.js * ruwiki-urldecoder[ResourceLoader|dependencies=ext.gadget.ruwiki-registerTool]|ruwiki-urldecoder.js === ruwiki-iw === * ruwiki-iwcore[ResourceLoader|hidden|type=general]|ruwiki-iwcore.js|ruwiki-iwcore.css * ruwiki-iwlocalnames[ResourceLoader|dependencies=ext.gadget.ruwiki-iwcore]|ruwiki-iwlocalnames.js * ruwiki-iwhints[ResourceLoader|dependencies=ext.gadget.ruwiki-iwcore]|ruwiki-iwhints.js * ruwiki-iwen[ResourceLoader|dependencies=ext.gadget.ruwiki-iwcore]|ruwiki-iwen.js * ruwiki-iwrussia[ResourceLoader|dependencies=ext.gadget.ruwiki-iwcore]|ruwiki-iwrussia.js == nowiki == * template-wizzard[ResourceLoader|rights=edit|type=general]|template-wizzard.js == azwiki == * Katalitik[ResourceLoader]|Katalitik.js * XTools-ArticleInfo[ResourceLoader]|XTools-ArticleInfo.js * addsection-plus[ResourceLoader]|addsection-plus.js * markAdmins[ResourceLoader|dependencies=mediawiki.util]|markAdmins.js * directLinkToCommons[ResourceLoader|dependencies=mediawiki.util]|directLinkToCommons.js * switcher[ResourceLoader|targets=desktop,mobile]|switcher.js * patrolRevisions[ResourceLoader|dependencies=mediawiki.api,mediawiki.util|rights=patrol]|patrolRevisions.js == fawiki == * ScriptOne[ResourceLoader]|ScriptOne.js * ScriptTwo[ResourceLoader]|ScriptTwo.js|ScriptTwo.css * ScriptHidden[hidden]|ScriptHidden.css * ScriptThree[ResourceLoader|dependencies=mediawiki.api|peers=ScriptHidden]|ScriptThree.js * Morebits-i18n[ResourceLoader|dependencies=ext.gadget.morebitsV3,jquery.i18n]|Morebits-i18n.js == bnwiki == *markAdmins[ResourceLoader|dependencies=mediawiki.util]|markAdmins.js * DiscussionCloser[ResourceLoader|dependencies=mediawiki.util]|DiscussionCloser.js|DiscussionCloser.css * Twinkle-bn[ResourceLoader|dependencies=ext.gadget.morebits-bn,ext.gadget.select2-bn|rights=autoconfirmed|type=general|peers=Twinkle-pagestyles-bn]|Twinkle-bn.js|twinkleprod-bn.js|twinkleimage-bn.js|twinklebatchundelete-bn.js|twinklewarn-bn.js|twinklespeedy-bn.js|friendlyshared-bn.js|twinklediff-bn.js|twinkleunlink-bn.js|friendlytag-bn.js|twinkledeprod-bn.js|friendlywelcome-bn.js|twinklexfd-bn.js|twinklebatchdelete-bn.js|twinklebatchprotect-bn.js|twinkleconfig-bn.js|twinklefluff-bn.js|twinkleprotect-bn.js|twinklearv-bn.js|twinkleblock-bn.js|friendlytalkback-bn.js|Twinkle-bn.css * morebits-bn[ResourceLoader|dependencies=mediawiki.user,mediawiki.util,jquery.ui|hidden]|morebits-bn.js|morebits-bn.css * Twinkle-pagestyles-bn[hidden|skins=vector]|Twinkle-pagestyles-bn.css * select2-bn[ResourceLoader|hidden]|select2.min-bn.js|select2.min-bn.css ==bnwiktionary== * Rep2Ad[ResourceLoader]|Rep2Ad.js ==ukwiki== * Wikificator[ResourceLoader|hidden]|Wikificator.js * Onlyifediting[ResourceLoader|action=edit|dependencies=ext.visualEditor.desktopArticleTarget.init,ext.gadget.Wikificator]|Onlyifediting.js * PostBlockActions[ResourceLoader|namespaces=-1]|PostBlockActions.js * ImgsCleanUp[ResourceLoader|package|dependencies=mediawiki.util,vue,@wikimedia/codex|rights=autoconfirmed|namespaces=6]|ImgsCleanUp.js|ImgsCleanUp-main.vue * valcio[ResourceLoader|dependencies=vue,codex]|valcio.js * codexTableBuilder[ResourceLoader|package|dependencies=vue,@wikimedia/codex|actions=edit,submit|rights=edit]|codexTableBuilder.js|codexTableBuilder.vue b4ee4xmpoi7sn4t67ek5js2n45dk0es 741006 741003 2026-05-08T15:46:01Z Valcio 46860 + 741006 wikitext text/x-wiki <noinclude>{{collapse|1={{#invoke:validate gadgets|validate}}|title=Issues in gadget definitions}}</noinclude> == Twinkle == * Twinkle [ResourceLoader |dependencies=ext.gadget.morebits, ext.gadget.select2, mediawiki.api, mediawiki.language |rights=autoconfirmed |type=general |peers=Twinkle-pagestyles] |Twinkle.js |Twinkle.css |twinklearv.js |twinklewarn.js |twinkleblock.js |twinklewelcome.js |twinkletalkback.js |twinklespeedy.js |twinkleprod.js |twinklexfd.js |twinkleimage.js |twinkleprotect.js |twinkletag.js |twinklediff.js |twinkleunlink.js |twinklerollback.js |twinkledeprod.js |twinklebatchdelete.js |twinklebatchprotect.js |twinklebatchundelete.js |twinkleconfig.js * morebits [ResourceLoader |dependencies=mediawiki.user, mediawiki.util, mediawiki.Title |hidden] |morebits.js |morebits.css * Twinkle-pagestyles [hidden |skins=vector, vector-2022] |Twinkle-pagestyles.css * select2 [ResourceLoader |hidden] |select2.min.js |select2.min.css *morebitsV3[ResourceLoader|dependencies=mediawiki.user,mediawiki.util,mediawiki.Title,jquery.ui|hidden]|morebitsV3.js|morebitsV3.css *twinkle-enwiki[ResourceLoader|dependencies=ext.gadget.morebitsV3,ext.gadget.select2,mediawiki.api,mediawiki.storage,mediawiki.libs.pluralruleparser|peers=Twinkle-pagestyles]|TwinkleV3.js|TwinkleV3.css *twinkle-starter[ResourceLoader|dependencies=ext.gadget.morebitsV3,ext.gadget.select2,mediawiki.api,mediawiki.storage|peers=Twinkle-pagestyles]|Twinkle-starter.js|Twinkle-starter.css *orange-i18n [ ResourceLoader | dependencies = mediawiki.libs.pluralruleparser ] | orange-i18n.js *banana-i18n [ ResourceLoader ] | banana-i18n.js == Recent-Tests == * nomin-test[ResourceLoader|requiresES6] | nomin-test.js * regex-test[ResourceLoader]|regex-test.js * es6-test[ResourceLoader|requiresES6]|es6-test.js * throwError[ResourceLoader|dependencies=mediawiki.util]|throwError.js * tabbedwindow[ResourceLoader|default|dependencies=mediawiki.Title]|tabbedwindow.js * markblocked[ResourceLoader|dependencies=mediawiki.util,mediawiki.page.ready]|markblocked.js * djtest[ResourceLoader|skins=minerva]|djtest.js * packagefilebase[ResourceLoader|requiresES6|package|hidden]|packagefilebase-file1.js|packagefilebase-file2.js|packagefilebase-file3.json * packagefileuser[ResourceLoader|requiresES6|package|dependencies=ext.gadget.packagefilebase]|packagefileuser.js * MobileCategories[ResourceLoader|dependencies=mediawiki.api,mediawiki.util|skins=minerva]|MobileCategories.js * Sharer[ResourceLoader]|Sharer.js * citations[ResourceLoader|dependencies=mediawiki.util]|citations.js * watchlist-notice[ResourceLoader|targets=desktop,mobile|default]|watchlist-notice.js * watchlist-notice-core[ResourceLoader|targets=desktop,mobile|dependencies=mediawiki.storage|hidden]|watchlist-notice-core.js * geonotice[ResourceLoader|default]|geonotice.js * geonotice-core[ResourceLoader|package|dependencies=mediawiki.util,mediawiki.storage|hidden]|geonotice-core.js|geonotice-list.json|geonotice-core.css * legacyToolbar [ResourceLoader] |legacyToolbar.js |extra-toolbar-buttons-core.js |refToolbarLegacy.js * refToolbar[ResourceLoader|default|dependencies=mediawiki.util|actions=edit|contentModels=wikitext]|refToolbar.js * refToolbarBase[ResourceLoader|hidden]|refToolbarBase.js * contribsrange[ResourceLoader|dependencies=mediawiki.util,jquery.spinner]|contribsrange.js * another-contribsrange[ResourceLoader|dependencies=mediawiki.util,jquery.spinner]|another-contribsrange.js * charinsert[ResourceLoader]|charinsert.js * charinsert-core[ResourceLoader|hidden|dependencies=jquery.textSelection,user,mediawiki.storage]|charinsert-styles.css|charinsert-core.js * charinsert-old[ResourceLoader]|charinsert-old.js|charinsert-old.css * diffTools[ResourceLoader|dependencies=mediawiki.util]|diffTools.js|diffTools.css * ImagelessTabs[ResourceLoader]|ImagelessTabs.css * fastbuttons[ResourceLoader|dependencies=mediawiki.util]|fastbuttons.js|fastbuttons.css * ExternalTranslate[ResourceLoader|dependencies=jquery,mediawiki.api]|ExternalTranslate.js|ExternalTranslate.html|ExternalTranslate.css * destacar[ResourceLoader]|highlightsUsername.js|highlightsUsername.css * blockNotificationsButton[ResourceLoader|dependencies=mediawiki.api,ext.gadget.mediawiki.api.ptwiki,mediawiki.util,user.options|rights=block]|blockNotificationsButton.js|blockNotificationsButton.css * NewVillagePump[ResourceLoader]|NewVillagePump.js|NewVillagePump.css * mediawiki.api.ptwiki[ResourceLoader|dependencies=mediawiki.api|hidden]|mediawiki.api.ptwiki.js * NewVillagePumpCore[ResourceLoader|dependencies=mediawiki.util,jquery.placeholder,jquery.spinner,ext.gadget.mediawiki.api.ptwiki|hidden]|NewVillagePump.js/Core.js * Navigation_popups [ResourceLoader |dependencies=mediawiki.api, mediawiki.user, mediawiki.util, user.options, mediawiki.jqueryMsg |type=general] |popups.js |navpop.css * teahouse[ResourceLoader|dependencies=mediawiki.user,mediawiki.cookie]|teahouse/main.js|teahouse/config.js|teahouse/teahouse.css * teahouse-opt-in[ResourceLoader]|teahouse-opt-in/main.js * PB[ResourceLoader|dependencies=mediawiki.api,mediawiki.util]|PB.js * Wikimedia Learning Survey[ResourceLoader]|WikimediaL.js * formWizard [ResourceLoader |default |rights=minoredit] |formWizard.js * formWizard-core [ResourceLoader |hidden |dependencies=mediawiki.api, mediawiki.cookie, mediawiki.ui, mediawiki.user, jquery.chosen, jquery.ui, user.options] |formWizard-core.js |formWizard.css * requestForAdminship[ResourceLoader]|requestForAdminship.js * watchUserContribs[ResourceLoader|dependencies=jquery.ui,mediawiki.util,mediawiki.ui.button,ext.gadget.TipsyDeprecated]|watchUserContribs.js|watchUserContribs.css * WatchlistGreenIndicators[ResourceLoader|skins=vector]|WatchlistGreenIndicators.css * WatchlistChangesBold[ResourceLoader]|WatchlistChangesBold.css * Hotcat[ResourceLoader|rights=edit]|HotCat.js * RevisionSlider[ResourceLoader|dependencies=jquery.ui,mediawiki.api,mediawiki.util]|revisionslider.js|revisionslider.css * toolbartocnav[ResourceLoader|dependencies=ext.wikiEditor]|toolbartocnav.css|toolbartocnav.js * purgetab[ResourceLoader|dependencies=mediawiki.util,mediawiki.api]|purgetab.js * databoxEditor[ResourceLoader|dependencies=jquery.client,jquery.mwEmbedUtil,mw.MwEmbedSupport,jquery.ui]|databoxeditor.js * wikEd[ResourceLoader]|wikEd.js * revisionsSysopsActions[ResourceLoader|dependencies=mediawiki.util,ext.gadget.mediawiki.api.ptwiki,jquery.placeholder]|revisionsSysopsActions.js * validateBlockRollbackers[ResourceLoader]|validateBlockRollbackers.js * watchlist[ResourceLoader|top]|watchlist.js * addsection-plus[ResourceLoader|skins=monobook,vector]|addsection-plus.css * CleanDeleteReasons[ResourceLoader|default|rights=delete]|CleanDeleteReasons.js * contentFeatured[ResourceLoader|dependencies=mediawiki.util,ext.gadget.mediawiki.api.ptwiki,jquery.ui]|contentFeatured.js|contentFeatured.css * easyPeerReview[ResourceLoader|rights=review|dependencies=mediawiki.util]|easyPeerReview.js * UTCLiveClock[ResourceLoader|type=general|dependencies=mediawiki.util,mediawiki.api|peers=UTCLiveClock-pagestyles]|UTCLiveClock.js|UTCLiveClock.css * UTCLiveClock-pagestyles[hidden|skins=vector,monobook]|UTCLiveClock-pagestyles.css * afchelper [ResourceLoader |dependencies=mediawiki.api, mediawiki.util, mediawiki.user, jquery.chosen, jquery.spinner, jquery.ui |namespaces=2, 118] |afchelper.js |afchelper.css * Shortdesc-helper-loader[ResourceLoader|dependencies=mediawiki.api,user.options,mediawiki.util|skins=vector,monobook,modern,timeless|peers=Shortdesc-helper-pagestyles-vector]|Shortdesc-helper.js * Shortdesc-helper-pagestyles-vector[hidden|skins=vector]|Shortdesc-helper-pagestyles-vector.css * MoreMenu-local[ResourceLoader|dependencies=mediawiki.api,mediawiki.util,mediawiki.Title,user.options|peers=MoreMenu-local-pagestyles]|MoreMenu.js * MoreMenu-local-pagestyles[hidden]|MoreMenu-pagestyles.css * scribe[ResourceLoader|dependencies=ext.visualEditor.core,mediawiki.api]| scribe.js|scribe.css * scribe-v2[ResourceLoader|dependencies=ext.visualEditor.core,mediawiki.api]| scribe-v2.js|scribe-v2.css * XFDcloser[ResourceLoader|dependencies=mediawiki.user|type=general]|XFDcloser.js * XFDcloser-core[ResourceLoader|dependencies=mediawiki.util,mediawiki.api,mediawiki.Title,oojs-ui-core,oojs-ui-widgets,oojs-ui-windows,oojs-ui.styles.icons-interactions,oojs-ui.styles.icons-content,oojs-ui.styles.icons-moderation,oojs-ui.styles.icons-alerts|hidden|type=general]|XFDcloser-core.js|XFDcloser-core.css * XFDcloser-core-beta[ResourceLoader|dependencies=mediawiki.util,mediawiki.api,mediawiki.Title,oojs-ui-core,oojs-ui-widgets,oojs-ui-windows,oojs-ui.styles.icons-interactions,oojs-ui.styles.icons-content,oojs-ui.styles.icons-moderation,oojs-ui.styles.icons-alerts|hidden|type=general]|XFDcloser-core-beta.js|XFDcloser-core-beta.css * libExtraUtil[ResourceLoader|hidden]|libExtraUtil.js * GoogleImagesTineye [ResourceLoader|dependencies=mediawiki.util]|GoogleImagesTineye.js * ShowJavascriptErrors[ResourceLoader|type=general]|ShowJavascriptErrors.js * lastEditUser[ResourceLoader|dependencies=mediawiki.util]|lastEditUser.js * dark-mode-toggle[ResourceLoader|targets=desktop,mobile|dependencies=mediawiki.util,mediawiki.api,mediawiki.Uri,mediawiki.storage|peers=dark-mode-toggle-pagestyles]|dark-mode-toggle.js * dark-mode-toggle-pagestyles[hidden|targets=desktop,mobile|skins=vector,vector-2022,minerva,monobook]|dark-mode-toggle-pagestyles.css * dark-mode[ResourceLoader|supportsUrlLoad|targets=desktop,mobile|skins=vector,vector-2022,monobook,modern,minerva,timeless]|dark-mode.css * addMe[ResourceLoader|default|dependencies=oojs-ui,mediawiki.api,mediawiki.util,mediawiki.jqueryMsg]|addMe.js * AutosuggestSitelink-local[ResourceLoader|dependencies=mediawiki.action.view.postEdit,mediawiki.ForeignApi,mediawiki.Title,oojs-ui-core,oojs-ui-windows]|AutosuggestSitelink.js * WpLibExtraDev[ResourceLoader|hidden]|WpLibExtraDev.js * MarkBLocked-core[ResourceLoader|hidden|dependencies=mediawiki.user,mediawiki.api,mediawiki.ForeignApi,mediawiki.storage,mediawiki.util,jquery.ui,oojs-ui,oojs-ui.styles.icons-moderation]|MarkBLocked-core.js|MarkBLocked-core.css * MarkBLocked[ResourceLoader|supportsUrlLoad|package|dependencies=mediawiki.user,mediawiki.api,mediawiki.ForeignApi,mediawiki.storage,mediawiki.util,jquery.ui,oojs-ui,oojs-ui.styles.icons-moderation]|MarkBLocked.js|MarkBLocked-core.js|MarkBLocked-core.css * MassRevisionDelete[ResourceLoader|rights=deleterevision|dependencies=jquery.makeCollapsible,oojs-ui,oojs-ui.styles.icons-movement,mediawiki.api]|MassRevisionDelete.js * edit-styles[ResourceLoader| actions=edit|type=styles]|edit-styles.css * firstedit-test[ResourceLoader]|firstedit-test.js * firstedit-short-test[ResourceLoader]|firstedit-short-test.js * section-share[ResourceLoader|default]|section-share.js ==Wikivoyage-Experimental== * Carousel[ResourceLoader|type=general|dependencies=mediawiki.util|targets=desktop,mobile]|Carousel.js|Carousel.css == modules == * fastButtonsCore[ResourceLoader|dependencies=mediawiki.api,ext.gadget.mediawiki.api.ptwiki,mediawiki.page.ready,jquery.ui,mediawiki.cookie]|fastbuttons.js/core.js * diffToolsCore[ResourceLoader|dependencies=mediawiki.api,mediawiki.util,user.options,ext.gadget.mediawiki.api.ptwiki,jquery.ui]|diffTools.js/core.js * validateBlockRollbackersCore[ResourceLoader|dependencies=mediawiki.util]|validateBlockRollbackers.js/core.js * requestForAdminshipCore[ResourceLoader|dependencies=ext.gadget.mediawiki.api.ptwiki,jquery.ui]|requestForAdminship.js/core.js|requestForAdminship.css * TipsyDeprecated[ResourceLoader|hidden]|tipsyDeprecated.js == arwiki == * changlist[ResourceLoader]|changlist.css == Old-tests == * backgroundTest[ResourceLoader|top|type=styles]|backgroundTest.css == ruwiki == * ruwiki-test[ResourceLoader]|ruwiki-test.js * ruwiki-core[ResourceLoader]|ruwiki-core.js * ruwiki-common-action-edit[ResourceLoader|dependencies=user.options]|ruwiki-common-action-edit.js * ruwiki-common-namespace-file[ResourceLoader|hidden]|ruwiki-common-namespace-file.js * ruwiki-common-action-history[ResourceLoader|hidden]|ruwiki-common-action-history.js * ruwiki-common-special-delete[ResourceLoader]|ruwiki-common-special-delete.js‎ * ruwiki-common-special-block[ResourceLoader|type=general]|ruwiki-common-special-block.js‎|ruwiki-common-special-block.css * ruwiki-common-special-log[ResourceLoader]|ruwiki-common-special-log.js‎ * ruwiki-common-special-newpages[ResourceLoader]|ruwiki-common-special-newpages.js‎ * ruwiki-common-special-movepage[ResourceLoader]|ruwiki-common-special-movepage.js‎ * ruwiki-common-special-watchlist[ResourceLoader]|ruwiki-common-special-watchlist.js‎ * ruwiki-common-special-search[ResourceLoader]|ruwiki-common-special-search.js‎ * ruwiki-common-special-upload[ResourceLoader]|ruwiki-common-special-upload.js‎ * ruwiki-wikificator[ResourceLoader|dependencies=user.options,jquery.textSelection,ext.gadget.ruwiki-registerTool]|ruwiki-wikificator.js * ruwiki-summaryButtons[ResourceLoader|type=general|hidden]|ruwiki-summaryButtons.js|ruwiki-summaryButtons.css * ruwiki-registerTool[ResourceLoader|hidden|dependencies=user.options]|ruwiki-registerTool.js * ruwiki-urldecoder[ResourceLoader|dependencies=ext.gadget.ruwiki-registerTool]|ruwiki-urldecoder.js === ruwiki-iw === * ruwiki-iwcore[ResourceLoader|hidden|type=general]|ruwiki-iwcore.js|ruwiki-iwcore.css * ruwiki-iwlocalnames[ResourceLoader|dependencies=ext.gadget.ruwiki-iwcore]|ruwiki-iwlocalnames.js * ruwiki-iwhints[ResourceLoader|dependencies=ext.gadget.ruwiki-iwcore]|ruwiki-iwhints.js * ruwiki-iwen[ResourceLoader|dependencies=ext.gadget.ruwiki-iwcore]|ruwiki-iwen.js * ruwiki-iwrussia[ResourceLoader|dependencies=ext.gadget.ruwiki-iwcore]|ruwiki-iwrussia.js == nowiki == * template-wizzard[ResourceLoader|rights=edit|type=general]|template-wizzard.js == azwiki == * Katalitik[ResourceLoader]|Katalitik.js * XTools-ArticleInfo[ResourceLoader]|XTools-ArticleInfo.js * addsection-plus[ResourceLoader]|addsection-plus.js * markAdmins[ResourceLoader|dependencies=mediawiki.util]|markAdmins.js * directLinkToCommons[ResourceLoader|dependencies=mediawiki.util]|directLinkToCommons.js * switcher[ResourceLoader|targets=desktop,mobile]|switcher.js * patrolRevisions[ResourceLoader|dependencies=mediawiki.api,mediawiki.util|rights=patrol]|patrolRevisions.js == fawiki == * ScriptOne[ResourceLoader]|ScriptOne.js * ScriptTwo[ResourceLoader]|ScriptTwo.js|ScriptTwo.css * ScriptHidden[hidden]|ScriptHidden.css * ScriptThree[ResourceLoader|dependencies=mediawiki.api|peers=ScriptHidden]|ScriptThree.js * Morebits-i18n[ResourceLoader|dependencies=ext.gadget.morebitsV3,jquery.i18n]|Morebits-i18n.js == bnwiki == *markAdmins[ResourceLoader|dependencies=mediawiki.util]|markAdmins.js * DiscussionCloser[ResourceLoader|dependencies=mediawiki.util]|DiscussionCloser.js|DiscussionCloser.css * Twinkle-bn[ResourceLoader|dependencies=ext.gadget.morebits-bn,ext.gadget.select2-bn|rights=autoconfirmed|type=general|peers=Twinkle-pagestyles-bn]|Twinkle-bn.js|twinkleprod-bn.js|twinkleimage-bn.js|twinklebatchundelete-bn.js|twinklewarn-bn.js|twinklespeedy-bn.js|friendlyshared-bn.js|twinklediff-bn.js|twinkleunlink-bn.js|friendlytag-bn.js|twinkledeprod-bn.js|friendlywelcome-bn.js|twinklexfd-bn.js|twinklebatchdelete-bn.js|twinklebatchprotect-bn.js|twinkleconfig-bn.js|twinklefluff-bn.js|twinkleprotect-bn.js|twinklearv-bn.js|twinkleblock-bn.js|friendlytalkback-bn.js|Twinkle-bn.css * morebits-bn[ResourceLoader|dependencies=mediawiki.user,mediawiki.util,jquery.ui|hidden]|morebits-bn.js|morebits-bn.css * Twinkle-pagestyles-bn[hidden|skins=vector]|Twinkle-pagestyles-bn.css * select2-bn[ResourceLoader|hidden]|select2.min-bn.js|select2.min-bn.css ==bnwiktionary== * Rep2Ad[ResourceLoader]|Rep2Ad.js ==ukwiki== * Wikificator[ResourceLoader|hidden]|Wikificator.js * Onlyifediting[ResourceLoader|action=edit|dependencies=ext.visualEditor.desktopArticleTarget.init,ext.gadget.Wikificator]|Onlyifediting.js * PostBlockActions[ResourceLoader|namespaces=-1]|PostBlockActions.js * ImgsCleanUp[ResourceLoader|package|dependencies=mediawiki.util,vue,@wikimedia/codex|rights=autoconfirmed|namespaces=6]|ImgsCleanUp.js|ImgsCleanUp-main.vue * valcio[ResourceLoader|dependencies=vue,codex]|valcio.js * codexTableBuilder[ResourceLoader|package|dependencies=vue,@wikimedia/codex|actions=edit,submit|rights=edit]|codexTableBuilder.js|codexTableBuilder.vue * codexTabs[ResourceLoader|package|default|dependencies=vue,@wikimedia/codex|type=general]|codexTabs.js|codexTabs.vue|codexTabs.css 7fre679ry4hc2bcpo9rv43lvva4fam7 ¿How to get open air with best clothing? 0 91854 741076 690885 2026-05-09T00:03:55Z InternetArchiveBot 34092 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 741076 wikitext text/x-wiki You can wear clothing and accessories and then leave your home or apartment and go outdoors where has more oxygen and higher air pressure and then indoors. == Tips: == # You could wear these kolored T-shirts and have logos and text, and size varies with personal size. ## Image galleries (man) [http://cdn02.shopclues.net/images/detailed/39957/blwhnavyredyel14115696971444491226_1466902941.jpg]{{Dead link|date=September 2022 |bot=InternetArchiveBot |fix-attempted=yes }} [http://www.zimruh.com/image/cache/data/A%20Main/shirt%20t-602x411.jpg] {{Webarchive|url=https://web.archive.org/web/20160911015741/http://www.zimruh.com/image/cache/data/A%20Main/shirt%20t-602x411.jpg |date=2016-09-11 }} [https://sishssc.files.wordpress.com/2009/08/screen-shot-2012-08-26-at-11-51-55-pm.png] [http://static5.shop.indiatimes.com/images/products/additional/original/B927743_View_1/fashion/t-shirts/red-white-kings-xi-punjab-kids-t-shirt.jpg]{{Dead link|date=September 2022 |bot=InternetArchiveBot |fix-attempted=yes }} [http://ecx.images-amazon.com/images/I/81aLMfpwMJL._SL1500_.jpg] [http://d3u67r7pp2lrq5.cloudfront.net/product_photos/950972/Raffa_20Short_20sleeve_20unisex_20kids_20T_20shirt_20new_original.jpg] {{Webarchive|url=https://web.archive.org/web/20160423173402/http://d3u67r7pp2lrq5.cloudfront.net/product_photos/950972/Raffa_20Short_20sleeve_20unisex_20kids_20T_20shirt_20new_original.jpg |date=2016-04-23 }} [http://resize5.indiatvnews.com/en/resize/gallery/860_-/2016/04/kings-xi-punjab-kxip-jersey-2016-1460122829.jpg] [http://images.sportsdirect.com/images/imgzoom/45/45197503_xxl.jpg] {{Webarchive|url=https://web.archive.org/web/20161027083431/http://images.sportsdirect.com/images/imgzoom/45/45197503_xxl.jpg |date=2016-10-27 }} [http://i.imgur.com/HDBTJ.jpg] [http://www.crcracewear.com/images/t-shirt2.png] [http://www.uwosh.edu/deptblogs/career/files/12_13CFotF_shirtA.jpg] {{Webarchive|url=https://web.archive.org/web/20150928225856/http://www.uwosh.edu/deptblogs/career/files/12_13CFotF_shirtA.jpg |date=2015-09-28 }} [http://www.toyzany.com/media/catalog/product/8/4/840285100473.jpg]{{Dead link|date=September 2022 |bot=InternetArchiveBot |fix-attempted=yes }} [http://www.ghlimited.com/shop/images/detailed/0/2235050004_15606_png_zoom_1136264892551385f5d1b883.jpg]{{Dead link|date=September 2022 |bot=InternetArchiveBot |fix-attempted=yes }} [http://www.truffleshuffle.co.uk/store/images_high_res/Mens_Red_Batman_Graffiti_Logo_T_Shirt_hi_res.jpg] {{Webarchive|url=https://web.archive.org/web/20151001233806/http://www.truffleshuffle.co.uk/store/images_high_res/Mens_Red_Batman_Graffiti_Logo_T_Shirt_hi_res.jpg |date=2015-10-01 }} [http://www.loopnorth.com/image/2012/marina_city_band_tshirts_sm.jpg] [http://www.thinkgeek.com/images/products/frontsquare/16d9_star_trek_tng_uniform_tee.jpg] [http://i.ebayimg.com/t/Star-Trek-Enterprise-Crew-Uniform-T-Shirt-Maenner-Men-Fasching-Kostuem-Halloween-/00/s/MTYwMFgxNjAw/z/PHcAAOSwBahVPQYt/$_35.JPG] [http://www.wigglestatic.com/product-media/5360093880/Castelli-Advantage-T-Shirt-T-shirts-Grey-Melange-AW14-CS140740061.jpg?w=1600&h=1600&a=7]{{Dead link|date=August 2023 |bot=InternetArchiveBot |fix-attempted=yes }} [http://www.theadairgroup.com/images/Assorted_Bright_T_Shirts_large.jpg] ### Image galleries (woman) [http://shop.visitlondon.com/ImageCache/Products/987.1.1000.1000.FFFFFF.0.jpeg]{{Dead link|date=September 2022 |bot=InternetArchiveBot |fix-attempted=yes }} [https://www.areswear.com/Image/Lib/UA-Womens-UA-Zone-T-Shirt--red-white-?w=350&h=350&iid=6018913]{{Dead link|date=September 2022 |bot=InternetArchiveBot |fix-attempted=yes }} #Get jeans (mostly blue or black) lo5c7arct3cfycwow5xrgk6hdjegajd User:SongVĩ.Bot II 2 124239 741032 740911 2026-05-08T17:00:15Z SongVĩ.Bot II 52414 [[User:SongVĩ.Bot II|Task 0]]: Đã 1593 ngày... 741032 wikitext text/x-wiki Cập nhật lần cuối: 09-05-2026 Đã 1593 ngày... a5zcr35fhwqzzff68tkdrmv5ul8hyjj Aiuto:Pagina di discussione 0 145659 741034 688337 2026-05-08T17:52:49Z Valcio 46860 Rb 741034 wikitext text/x-wiki Le '''pagine di discussione''' (a volte chiamate col nome inglese '''''talk''''') sono spazi utilizzati per il dialogo e il coordinamento tra gli utenti di Wikipedia. Eccetto le [[Aiuto:Pagine speciali|pagine speciali]] che hanno funzioni tecniche, tutte le altre pagine di Wikipedia ([[aiuto:voce|voci]], [[Wikipedia:pagina utente|pagine utente]], [[Wikipedia:Progetto|progetti tematici]], [[Aiuto:Categorie|categorie]]) dispongono di una relativa pagina di discussione nella quale chiunque può inserire commenti o fare proposte utili per la redazione o modifica dei contenuti relativi. Ad esempio, in "[[Discussione:Ignazio Silone]]" si discutono i contenuti della voce "[[Ignazio Silone]]". Le pagine di discussione fungono anche da luogo di confronto tra gli utenti per discutere problemi e trovare soluzioni, soprattutto nel caso di argomenti controversi. Quando vi sono pareri discordanti o interpretazioni differenti sul contenuto di una pagina, gli utenti non devono ingaggiare una [[Wikipedia:Guerra di modifiche|guerra di modifiche]], ma devono utilizzare la pagina di discussione per dialogare e stabilire il [[wp:consenso|consenso]] necessario a raggiungere una versione condivisa. Si badi bene: una pagina di discussione '''non è un forum''', ma serve solo a discutere i contenuti e a coordinare lo sviluppo di una determinata pagina. == Le principali pagine di discussione == {{tl|Vedi anche|Aiuto:Dove fare una domanda}} Su Wikipedia vi sono molte pagine di discussione, ciascuna con scopi precisi. Le più importanti tipologie sono: * [[#Le pagine di discussione delle voci|pagine di discussione delle voci]], dove si discutono le modifiche relative a ciascuna [[Aiuto:Voce|voce]] di Wikipedia. Lo stesso vale per i template e le categorie; * [[#Le pagine di discussione dei progetti|pagine di discussione dei progetti]], comunemente chiamate "bar tematici", dove si discute di argomenti generali relativi a insiemi di voci che trattano lo stesso tema (come in [[Discussioni progetto:Cinema]]) oppure di questioni relative al funzionamento di Wikipedia (è il caso dei molti "[[:categoria:Progetti di servizio|progetti di servizio]]"); * [[#Le pagine di discussione degli utenti|pagine di discussione degli utenti]], impiegate dai wikipediani per scambiarsi tra loro messaggi inerenti alle proprie attività su Wikipedia, inviando e ricevendo messaggi. Vi sono anche altri spazi dedicati al dialogo tra gli utenti i quali, pur avendo una funzione simile, non sono pagine di discussione in senso stretto, ma hanno comunque un utilizzo simile. Ad esempio: * per discussioni e segnalazioni di interesse generale su Wikipedia c'è il [[#Il bar di Wikipedia|bar di Wikipedia]]; * per informazioni su "come fare qualcosa" su Wikipedia c'è lo [[Aiuto:Sportello informazioni|sportello informazioni]]; * per domande su qualsiasi argomento non sia inerente al funzionamento di Wikipedia c'è l'[[Wikipedia:Oracolo|oracolo]]; * per proporre voci per la vetrina ci sono le [[Wikipedia:Riconoscimenti di qualità/Segnalazioni|segnalazioni per i riconoscimenti di qualità]]; * per le richieste di revisioni dettagliate sulle voci, c'è la [[Wikipedia:Vaglio|pagina dei vagli]]. == Dove si trova la pagina di discussione? == <div class="mw-gadget-tabbedwindow"> ===Desktop (default)=== [[File:Itwiki_help_discusssion_vector2022_1.png|thumb|upright=1.7|left|link=|La linguetta su cui cliccare per entrare nella pagina di discussione in cima alla pagina]] [[File:Itwiki_help_discusssion_vector2022_2.png|thumb|upright=1.7|right|link=|Il pulsante su cui cliccare per entrare nella pagina di discussione dalla barra di navigazione]] {{clear}} In qualunque pagina di Wikipedia ci si trovi (ad eccezione delle pagine speciali), nella parte alta della schermata c'è una linguetta che reca la scritta <tvar name="1">"'''{{Int|talk|lang=it}}'''"</tvar>. In alternativa, quando ci si sposta verso il basso comparirà una barra di navigazione statica, che contiene il pulsante <tvar name=1>'''[[File:OOjs_UI_icon_speechBubbles-ltr.svg|link=|alt={{int|talk|lang=it}}]] {{int|talk|lang=it}}'''</tvar> Questi sono i pulsanti da cliccare per accedere alla pagina di discussione. Per tornare alla pagina principale basterà cliccare sulla prima linguetta, posta subito prima della linguetta "Discussione" (il suo nome sarà diverso a seconda di dove ci si trova: "Voce", "Progetto", "Categoria" ecc). Se il testo "<span style="color:BA0000;">Discussione</span>" è rosso significa che la pagina di discussione non è ancora stata creata. Se si desidera crearla, basterà cliccare sul link e inserire il testo desiderato. ===Desktop (Vector legacy)=== [[File:Pulsante Discussione.png|thumb|upright=2.7|center|link=|La linguetta su cui cliccare per entrare nella pagina di discussione di una voce]] In qualunque pagina di Wikipedia ci si trovi (ad eccezione delle pagine speciali), nella parte alta della schermata c'è una linguetta che reca la scritta "'''Discussione'''". Quello è il link da cliccare per accedere alla pagina di discussione. Per tornare alla pagina principale basterà cliccare sulla prima linguetta, posta subito prima della linguetta "Discussione" (il suo nome sarà diverso a seconda di dove ci si trova: "Voce", "Progetto", "Categoria" ecc). Se il testo "<span style="color:BA0000;">Discussione</span>" è rosso significa che la pagina di discussione non è ancora stata creata. Se si desidera crearla, basterà cliccare sul link e inserire il testo desiderato. ===Mobile=== [[File:Itwiki_help_discusssion_mobile.jpg|thumb|upright=1.7|center|link=|La linguetta su cui cliccare per entrare nella pagina di discussione di una voce]] In qualunque pagina di Wikipedia ci si trovi (ad eccezione delle pagine speciali), nella parte alta della schermata c'è una linguetta che reca la scritta "'''Discussione'''". Quello è il link da cliccare per accedere alla pagina di discussione. '''È necessario essere [[Aiuto:Registrazione|registrati]] per visualizzarla.''' Per tornare alla pagina principale basterà cliccare sulla prima linguetta, posta subito prima della linguetta "Discussione" (il suo nome sarà diverso a seconda di dove ci si trova: "Voce", "Progetto", "Categoria" ecc). Se il testo "<span style="color:BA0000;">Discussione</span>" è rosso significa che la pagina di discussione non è ancora stata creata. Se si desidera crearla, basterà cliccare sul link e inserire il testo desiderato. </div> === Indirizzo === {{Tipi di pagina}} L'indirizzo della discussione dipende dal [[Aiuto:namespace|tipo di pagina]] a cui la discussione fa riferimento (si veda il box a lato). * Per una [[Aiuto:voce|voce]] titolata "XXXX", l'indirizzo è <code><nowiki>[[Discussione:XXXX]]</nowiki></code>; : (esempio: [[Comunicazione]] e [[Discussione:Comunicazione]]). * Per una pagina di servizio (come Categoria, Progetto, Wikipedia, Aiuto ecc.) quale ad esempio "Categoria:YYY", la discussione si trova a <code><nowiki>[[Discussioni Categoria:YYY]]</nowiki></code> : (esempi: [[Aiuto:Tabelle]] e [[Discussioni Aiuto:Tabelle]]; [[Wikipedia:Vetrina]] e [[Discussioni Wikipedia:Vetrina]]). Per ricercare o linkare direttamente una pagina di discussione basta copiarne direttamente il titolo. Per linkare una specifica [[Aiuto:Sezione|sezione o paragrafo]] all'interno di una pagina di discussione, si deve usare questo codice: <code><nowiki>[[Titolo della pagina di discussione#titolo della sezione]]</nowiki></code>. Esempio (clicca per provare): [[Discussioni aiuto:Pagina di discussione#Esempio di paragrafo]]. {{Avviso|tipo=contenuto|immagine=[[File:Bombilla amarilla - yellow Edison lamp.svg|40px|!]]|testo='''Lo sapevi che''' quando una pagina viene seguita attraverso la funzione [[Aiuto:Osservati speciali|osservati speciali]], viene automaticamente seguita anche la relativa pagina di discussione?}} === Abbreviazioni === Per linkare pagine di discussione relative ad alcuni [[Aiuto:namespace|namespace]] come Progetto e Wikipedia è possibile usare abbreviazioni, ad esempio: * [[dp:Roma]] invece di [[Discussioni progetto:Roma]]. * [[dw:Vetrina]] invece di [[Discussioni wikipedia:Vetrina]] * ecc. Inoltre, per tutte le pagine di discussione si possono usare i nomi originali inglesi con il breve ''Talk'', ad esempio: * [[talk:Mary Poppins (serie di romanzi)]] * [[template talk:Cita]]. == Come si partecipa a una discussione == === Rispetta sempre i tuoi interlocutori === {{Vedi anche|Wikipedia:Wikiquette|Wikipedia: Niente attacchi personali}} [[file:Diskussion-Icon XY.svg|thumb|75px|L'enciclopedia si arricchisce grazie alle diversità di pensiero]] Prima di intervenire in qualunque pagina di discussione, si ricordino due principi fondamentali. * Gli interventi sulle pagine di discussione devono sempre rispettare la [[Aiuto:Wikiquette|'''Wikiquette''']]: ciò significa anche aderire allo spirito di collaborazione e mutua comprensione di Wikipedia (il cosiddetto [[Aiuto:Wikilove|'''Wikilove''']]). * Le discussioni servono a discutere temi di interesse per Wikipedia. Utenti diversi possono avere punti di vista differenti su un dato argomento, ma nelle discussioni si commentano e confrontano sempre e soltanto i contenuti, mai gli autori dei messaggi. Negli spazi di discussione non sono ammesse provocazioni, ''[[Flame (Internet)|flame]]'' (risse verbali) e men che meno [[Wikipedia:Niente attacchi personali|'''attacchi personali''']] contro altri utenti. È indispensabile accettare il fatto che siamo tutti parte della stessa comunità. Siamo tutti wikipediani: tu lo sei ugualmente a come lo sono tutti gli altri, '''qualunque sia il tuo bagaglio culturale o personale'''. Su Wikipedia non esistono ''esperti'', ma solo fonti attendibili e terze. Non squalificare il tuo operato su Wikipedia attraverso atteggiamenti e toni poco consoni ad un progetto collaborativo! === Organizzazione della pagina === Le pagine di discussione sono organizzate secondo pochi semplici criteri: * Ogni argomento si discute all'interno di una [[aiuto:sezione|sezione]] apposita. * Per inserire un ''nuovo'' argomento, clicca sulla linguetta "'''Aggiungi discussione'''" posta in alto nella schermata<ref>Se usi la [[wikipedia:Skin|skin monobook]] sarà quella contrassegnata con un "+".</ref>. Comparirà allora una nuova finestra con una riga denominata "Oggetto/intestazione", dove inserire ''il titolo'' della nuova discussione, e una finestra più grande in cui inserire il testo del proprio messaggio. * Tutti i messaggi vanno sempre '''[[aiuto:Firma|firmati]]'''. * Non si cancellano i messaggi degli altri utenti. * Ogni nuovo intervento va inserito in fondo alla discussione in corso, in modo che la discussione sia organizzata automaticamente in ordine cronologico, dall'intervento più vecchio a quello più recente. === Scrivere un messaggio === <div class="mw-gadget-tabbedwindow"> ===Strumenti di discussione (desktop, default)=== [[File:Itwiki_help_reply_tools.png|thumb|upright=1.7|center|link=|Esempio di utilizzo degli strumenti di discussione]] Utilizzando gli '''strumenti di discussione''', attivati di default per tutte le utenze e attivabile/disattivabile dalla sezione ''Pagine di discussione'' nelle [[Speciale:Preferenze#mw-prefsection-editing|preferenze sulla casella di modifica]] e dalla sezione ''Strumenti di discussione'' delle [[Speciale:Preferenze#mw-prefsection-betafeatures|funzionalità beta]], è possibile: * Rispondere a dei messaggi premendo il pulsante <code>'''[rispondi]'''</code> posto in seguito ad ogni messaggio; nel caso il messaggio non sia firmato, il pulsante non apparirà e dunque sarà necessario procedere con la [[#Modifica manuale (desktop)|modifica manuale]]. * Creare nuove discussioni premendo la linguetta "'''Aggiungi discussione'''" o aprendo una pagina di discussione non esistente. * Ricevere una notifica ogni volta che viene aggiunto un messaggio in una discussione premendo il pulsante <code>'''[iscriviti]'''</code>, situato all'estremo destro dello schermo, alla stessa altezza del titolo della sezione. ===Modifica manuale (desktop)=== [[File:Itwiki_help_reply_desktop.png|thumb|upright=1.7|right|link=|Esempio di risposta attraverso la modifica manuale]] [[File:Itwiki help newsection desktop.png|thumb|upright=1.7|left|link=|Dimostrazione di come si aggiunge una nuova discussione]] {{Avviso |testo = '''Lo sapevi che''' su Wikipedia esiste un [[Aiuto:Tour guidato|Tour guidato]] per imparare in fretta ad usare le pagine di discussione? '''[[Aiuto:Tour_guidato/Tutorial_2-1|Clicca qui per provare!]]''' |tipo = contenuto |immagine = [[File:Bombilla amarilla - yellow Edison lamp.svg|40px|!]] }} Per partecipare ad una discussione utilizzando il '''metodo manuale''', bisogna [[Aiuto:Modifica|modificare]] la pagina di discussione. Ciò avviene in modo identico ad una pagina tradizionale, attraverso la linguetta "'''{{MediaWiki:Visualeditor-ca-editsource}}'''" posta nella parte alta della schermata, oppure utilizzando il pulsante "<code>[modifica]</code>" posto fianco del titolo di una delle sezioni che compongono la pagina. Si può iniziare una nuova discussione premendo la linguetta "'''Aggiungi discussione'''" o aprendo una pagina di discussione non esistente. Per facilitare la lettura della pagina, si raccomanda di usare i seguenti accorgimenti: * Lasciare sempre una riga orizzontale vuota tra un messaggio e l'altro; * [[Indentazione|indentare]] ogni nuovo messaggio verso destra, inserendo uno o più segni di "<code>:</code>" (due punti) ''all'inizio del paragrafo''. (vedi la sezione [[#Indentazione della discussione]] qui sotto). '''Chiunque''' scriva in una pagina di discussione '''deve sempre firmare''' il proprio messaggio prima di salvare la pagina. {{vedi anche|Aiuto:Firma}} Solo quando si risponde utilizzando il metodo manuale è opportuno inserire manualmente la firma. [[File:Per firmare.png|thumb|upright=2.7|Clicca sempre '''questo bottone''' quando hai finito di scrivere il tuo intervento e prima di salvare la pagina.]] Ci sono due modi per scrivere la propria firma: * Finito di scrivere, clicca sul pulsante raffigurante una penna, posizionato in alto nella finestra di modifica. * Finito di scrivere, aggiungi manualmente <code><nowiki>"--~~~~"</nowiki></code> alla fine del tuo messaggio. Dopo aver salvato la pagina, al posto di <nowiki>"--~~~~"</nowiki> compariranno il nome utente di chi ha scritto il messaggio, insieme alla data e all'ora di salvataggio della pagina. Se non sei un utente registrato, non hai effettuato il [[Aiuto:Login|login]] o la tua sessione non è più attiva, al posto del nome utente comparirà il tuo indirizzo IP. Per verificare di essere connessi con la propria utenza basta premere il pulsante [[Aiuto:Anteprima|anteprima]] della pagina prima di salvarla e verificare che al posto della firma <nowiki>"~~~~"</nowiki> appaia il proprio nome utente. {{Avviso |tipo = importante |immagine = [[File:Emblem-important-red.svg|40px|Smile]] | testo = Usa la firma sempre soltanto nelle pagine di discussione, '''MAI''' nelle voci di Wikipedia. ''(Le voci sono prodotti comunitari, non vanno mai firmate!)'' }} ===Mobile=== [[File:Itwiki_help_reply_mobile.jpg|thumb|upright=1|right|link=|Esempio di risposta da mobile]] Per partecipare ad una discussione utilizzando '''dispositivi mobili''', bisogna aprire la pagina di discussione, premere sul titolo della sezione interessata e scrivere la risposta nel box in fondo alla pagina. Si può iniziare una nuova discussione premendo il pulsante "'''Aggiungi argomento'''" posto in cima alla pagina di discussione o aprendo una pagina di discussione non esistente. Per facilitare la lettura della pagina, si raccomanda di [[Indentazione|indentare]] ogni nuovo messaggio verso destra, inserendo uno o più segni di "<code>:</code>" (due punti) ''all'inizio del paragrafo''. (vedi la sezione [[#Indentazione della discussione]] qui sotto). Oppure selezionando l'opzione "Leggi come pagina Wiki" è possibile, cliccando sul simbolo della matita '''[[File:OOjs_UI_icon_edit-ltr.svg|link=|alt={{int|vector-view-edit|lang=it}}]]''', aggiungere il commento come spiegato in [[#Modifica manuale (desktop)|modifica manuale]]. Se non si accede a Wikipedia dal web ma dall'applicazione per dispositivi mobili, il pulsante per accedere alle pagine di discussione sarà situato in fondo alle voci. </div> '' [ommiss] '' CC-BY-SA 4.0 [[:it:Aiuto:Pagina di discussione]] ey8upm1k1cv40lnhpskbep4erfo0jbm 741035 741034 2026-05-08T17:54:22Z Valcio 46860 /* Dove si trova la pagina di discussione? */ fix 741035 wikitext text/x-wiki Le '''pagine di discussione''' (a volte chiamate col nome inglese '''''talk''''') sono spazi utilizzati per il dialogo e il coordinamento tra gli utenti di Wikipedia. Eccetto le [[Aiuto:Pagine speciali|pagine speciali]] che hanno funzioni tecniche, tutte le altre pagine di Wikipedia ([[aiuto:voce|voci]], [[Wikipedia:pagina utente|pagine utente]], [[Wikipedia:Progetto|progetti tematici]], [[Aiuto:Categorie|categorie]]) dispongono di una relativa pagina di discussione nella quale chiunque può inserire commenti o fare proposte utili per la redazione o modifica dei contenuti relativi. Ad esempio, in "[[Discussione:Ignazio Silone]]" si discutono i contenuti della voce "[[Ignazio Silone]]". Le pagine di discussione fungono anche da luogo di confronto tra gli utenti per discutere problemi e trovare soluzioni, soprattutto nel caso di argomenti controversi. Quando vi sono pareri discordanti o interpretazioni differenti sul contenuto di una pagina, gli utenti non devono ingaggiare una [[Wikipedia:Guerra di modifiche|guerra di modifiche]], ma devono utilizzare la pagina di discussione per dialogare e stabilire il [[wp:consenso|consenso]] necessario a raggiungere una versione condivisa. Si badi bene: una pagina di discussione '''non è un forum''', ma serve solo a discutere i contenuti e a coordinare lo sviluppo di una determinata pagina. == Le principali pagine di discussione == {{tl|Vedi anche|Aiuto:Dove fare una domanda}} Su Wikipedia vi sono molte pagine di discussione, ciascuna con scopi precisi. Le più importanti tipologie sono: * [[#Le pagine di discussione delle voci|pagine di discussione delle voci]], dove si discutono le modifiche relative a ciascuna [[Aiuto:Voce|voce]] di Wikipedia. Lo stesso vale per i template e le categorie; * [[#Le pagine di discussione dei progetti|pagine di discussione dei progetti]], comunemente chiamate "bar tematici", dove si discute di argomenti generali relativi a insiemi di voci che trattano lo stesso tema (come in [[Discussioni progetto:Cinema]]) oppure di questioni relative al funzionamento di Wikipedia (è il caso dei molti "[[:categoria:Progetti di servizio|progetti di servizio]]"); * [[#Le pagine di discussione degli utenti|pagine di discussione degli utenti]], impiegate dai wikipediani per scambiarsi tra loro messaggi inerenti alle proprie attività su Wikipedia, inviando e ricevendo messaggi. Vi sono anche altri spazi dedicati al dialogo tra gli utenti i quali, pur avendo una funzione simile, non sono pagine di discussione in senso stretto, ma hanno comunque un utilizzo simile. Ad esempio: * per discussioni e segnalazioni di interesse generale su Wikipedia c'è il [[#Il bar di Wikipedia|bar di Wikipedia]]; * per informazioni su "come fare qualcosa" su Wikipedia c'è lo [[Aiuto:Sportello informazioni|sportello informazioni]]; * per domande su qualsiasi argomento non sia inerente al funzionamento di Wikipedia c'è l'[[Wikipedia:Oracolo|oracolo]]; * per proporre voci per la vetrina ci sono le [[Wikipedia:Riconoscimenti di qualità/Segnalazioni|segnalazioni per i riconoscimenti di qualità]]; * per le richieste di revisioni dettagliate sulle voci, c'è la [[Wikipedia:Vaglio|pagina dei vagli]]. == Dove si trova la pagina di discussione? == <div class="codex-tabs-sections"> ===Desktop (default)=== [[File:Itwiki_help_discusssion_vector2022_1.png|thumb|upright=1.7|left|link=|La linguetta su cui cliccare per entrare nella pagina di discussione in cima alla pagina]] [[File:Itwiki_help_discusssion_vector2022_2.png|thumb|upright=1.7|right|link=|Il pulsante su cui cliccare per entrare nella pagina di discussione dalla barra di navigazione]] {{clear}} In qualunque pagina di Wikipedia ci si trovi (ad eccezione delle pagine speciali), nella parte alta della schermata c'è una linguetta che reca la scritta <tvar name="1">"'''{{Int|talk|lang=it}}'''"</tvar>. In alternativa, quando ci si sposta verso il basso comparirà una barra di navigazione statica, che contiene il pulsante <tvar name=1>'''[[File:OOjs_UI_icon_speechBubbles-ltr.svg|link=|alt={{int|talk|lang=it}}]] {{int|talk|lang=it}}'''</tvar> Questi sono i pulsanti da cliccare per accedere alla pagina di discussione. Per tornare alla pagina principale basterà cliccare sulla prima linguetta, posta subito prima della linguetta "Discussione" (il suo nome sarà diverso a seconda di dove ci si trova: "Voce", "Progetto", "Categoria" ecc). Se il testo "<span style="color:BA0000;">Discussione</span>" è rosso significa che la pagina di discussione non è ancora stata creata. Se si desidera crearla, basterà cliccare sul link e inserire il testo desiderato. ===Desktop (Vector legacy)=== [[File:Pulsante Discussione.png|thumb|upright=2.7|center|link=|La linguetta su cui cliccare per entrare nella pagina di discussione di una voce]] In qualunque pagina di Wikipedia ci si trovi (ad eccezione delle pagine speciali), nella parte alta della schermata c'è una linguetta che reca la scritta "'''Discussione'''". Quello è il link da cliccare per accedere alla pagina di discussione. Per tornare alla pagina principale basterà cliccare sulla prima linguetta, posta subito prima della linguetta "Discussione" (il suo nome sarà diverso a seconda di dove ci si trova: "Voce", "Progetto", "Categoria" ecc). Se il testo "<span style="color:BA0000;">Discussione</span>" è rosso significa che la pagina di discussione non è ancora stata creata. Se si desidera crearla, basterà cliccare sul link e inserire il testo desiderato. ===Mobile=== [[File:Itwiki_help_discusssion_mobile.jpg|thumb|upright=1.7|center|link=|La linguetta su cui cliccare per entrare nella pagina di discussione di una voce]] In qualunque pagina di Wikipedia ci si trovi (ad eccezione delle pagine speciali), nella parte alta della schermata c'è una linguetta che reca la scritta "'''Discussione'''". Quello è il link da cliccare per accedere alla pagina di discussione. '''È necessario essere [[Aiuto:Registrazione|registrati]] per visualizzarla.''' Per tornare alla pagina principale basterà cliccare sulla prima linguetta, posta subito prima della linguetta "Discussione" (il suo nome sarà diverso a seconda di dove ci si trova: "Voce", "Progetto", "Categoria" ecc). Se il testo "<span style="color:BA0000;">Discussione</span>" è rosso significa che la pagina di discussione non è ancora stata creata. Se si desidera crearla, basterà cliccare sul link e inserire il testo desiderato. </div> === Indirizzo === {{Tipi di pagina}} L'indirizzo della discussione dipende dal [[Aiuto:namespace|tipo di pagina]] a cui la discussione fa riferimento (si veda il box a lato). * Per una [[Aiuto:voce|voce]] titolata "XXXX", l'indirizzo è <code><nowiki>[[Discussione:XXXX]]</nowiki></code>; : (esempio: [[Comunicazione]] e [[Discussione:Comunicazione]]). * Per una pagina di servizio (come Categoria, Progetto, Wikipedia, Aiuto ecc.) quale ad esempio "Categoria:YYY", la discussione si trova a <code><nowiki>[[Discussioni Categoria:YYY]]</nowiki></code> : (esempi: [[Aiuto:Tabelle]] e [[Discussioni Aiuto:Tabelle]]; [[Wikipedia:Vetrina]] e [[Discussioni Wikipedia:Vetrina]]). Per ricercare o linkare direttamente una pagina di discussione basta copiarne direttamente il titolo. Per linkare una specifica [[Aiuto:Sezione|sezione o paragrafo]] all'interno di una pagina di discussione, si deve usare questo codice: <code><nowiki>[[Titolo della pagina di discussione#titolo della sezione]]</nowiki></code>. Esempio (clicca per provare): [[Discussioni aiuto:Pagina di discussione#Esempio di paragrafo]]. {{Avviso|tipo=contenuto|immagine=[[File:Bombilla amarilla - yellow Edison lamp.svg|40px|!]]|testo='''Lo sapevi che''' quando una pagina viene seguita attraverso la funzione [[Aiuto:Osservati speciali|osservati speciali]], viene automaticamente seguita anche la relativa pagina di discussione?}} === Abbreviazioni === Per linkare pagine di discussione relative ad alcuni [[Aiuto:namespace|namespace]] come Progetto e Wikipedia è possibile usare abbreviazioni, ad esempio: * [[dp:Roma]] invece di [[Discussioni progetto:Roma]]. * [[dw:Vetrina]] invece di [[Discussioni wikipedia:Vetrina]] * ecc. Inoltre, per tutte le pagine di discussione si possono usare i nomi originali inglesi con il breve ''Talk'', ad esempio: * [[talk:Mary Poppins (serie di romanzi)]] * [[template talk:Cita]]. == Come si partecipa a una discussione == === Rispetta sempre i tuoi interlocutori === {{Vedi anche|Wikipedia:Wikiquette|Wikipedia: Niente attacchi personali}} [[file:Diskussion-Icon XY.svg|thumb|75px|L'enciclopedia si arricchisce grazie alle diversità di pensiero]] Prima di intervenire in qualunque pagina di discussione, si ricordino due principi fondamentali. * Gli interventi sulle pagine di discussione devono sempre rispettare la [[Aiuto:Wikiquette|'''Wikiquette''']]: ciò significa anche aderire allo spirito di collaborazione e mutua comprensione di Wikipedia (il cosiddetto [[Aiuto:Wikilove|'''Wikilove''']]). * Le discussioni servono a discutere temi di interesse per Wikipedia. Utenti diversi possono avere punti di vista differenti su un dato argomento, ma nelle discussioni si commentano e confrontano sempre e soltanto i contenuti, mai gli autori dei messaggi. Negli spazi di discussione non sono ammesse provocazioni, ''[[Flame (Internet)|flame]]'' (risse verbali) e men che meno [[Wikipedia:Niente attacchi personali|'''attacchi personali''']] contro altri utenti. È indispensabile accettare il fatto che siamo tutti parte della stessa comunità. Siamo tutti wikipediani: tu lo sei ugualmente a come lo sono tutti gli altri, '''qualunque sia il tuo bagaglio culturale o personale'''. Su Wikipedia non esistono ''esperti'', ma solo fonti attendibili e terze. Non squalificare il tuo operato su Wikipedia attraverso atteggiamenti e toni poco consoni ad un progetto collaborativo! === Organizzazione della pagina === Le pagine di discussione sono organizzate secondo pochi semplici criteri: * Ogni argomento si discute all'interno di una [[aiuto:sezione|sezione]] apposita. * Per inserire un ''nuovo'' argomento, clicca sulla linguetta "'''Aggiungi discussione'''" posta in alto nella schermata<ref>Se usi la [[wikipedia:Skin|skin monobook]] sarà quella contrassegnata con un "+".</ref>. Comparirà allora una nuova finestra con una riga denominata "Oggetto/intestazione", dove inserire ''il titolo'' della nuova discussione, e una finestra più grande in cui inserire il testo del proprio messaggio. * Tutti i messaggi vanno sempre '''[[aiuto:Firma|firmati]]'''. * Non si cancellano i messaggi degli altri utenti. * Ogni nuovo intervento va inserito in fondo alla discussione in corso, in modo che la discussione sia organizzata automaticamente in ordine cronologico, dall'intervento più vecchio a quello più recente. === Scrivere un messaggio === <div class="mw-gadget-tabbedwindow"> ===Strumenti di discussione (desktop, default)=== [[File:Itwiki_help_reply_tools.png|thumb|upright=1.7|center|link=|Esempio di utilizzo degli strumenti di discussione]] Utilizzando gli '''strumenti di discussione''', attivati di default per tutte le utenze e attivabile/disattivabile dalla sezione ''Pagine di discussione'' nelle [[Speciale:Preferenze#mw-prefsection-editing|preferenze sulla casella di modifica]] e dalla sezione ''Strumenti di discussione'' delle [[Speciale:Preferenze#mw-prefsection-betafeatures|funzionalità beta]], è possibile: * Rispondere a dei messaggi premendo il pulsante <code>'''[rispondi]'''</code> posto in seguito ad ogni messaggio; nel caso il messaggio non sia firmato, il pulsante non apparirà e dunque sarà necessario procedere con la [[#Modifica manuale (desktop)|modifica manuale]]. * Creare nuove discussioni premendo la linguetta "'''Aggiungi discussione'''" o aprendo una pagina di discussione non esistente. * Ricevere una notifica ogni volta che viene aggiunto un messaggio in una discussione premendo il pulsante <code>'''[iscriviti]'''</code>, situato all'estremo destro dello schermo, alla stessa altezza del titolo della sezione. ===Modifica manuale (desktop)=== [[File:Itwiki_help_reply_desktop.png|thumb|upright=1.7|right|link=|Esempio di risposta attraverso la modifica manuale]] [[File:Itwiki help newsection desktop.png|thumb|upright=1.7|left|link=|Dimostrazione di come si aggiunge una nuova discussione]] {{Avviso |testo = '''Lo sapevi che''' su Wikipedia esiste un [[Aiuto:Tour guidato|Tour guidato]] per imparare in fretta ad usare le pagine di discussione? '''[[Aiuto:Tour_guidato/Tutorial_2-1|Clicca qui per provare!]]''' |tipo = contenuto |immagine = [[File:Bombilla amarilla - yellow Edison lamp.svg|40px|!]] }} Per partecipare ad una discussione utilizzando il '''metodo manuale''', bisogna [[Aiuto:Modifica|modificare]] la pagina di discussione. Ciò avviene in modo identico ad una pagina tradizionale, attraverso la linguetta "'''{{MediaWiki:Visualeditor-ca-editsource}}'''" posta nella parte alta della schermata, oppure utilizzando il pulsante "<code>[modifica]</code>" posto fianco del titolo di una delle sezioni che compongono la pagina. Si può iniziare una nuova discussione premendo la linguetta "'''Aggiungi discussione'''" o aprendo una pagina di discussione non esistente. Per facilitare la lettura della pagina, si raccomanda di usare i seguenti accorgimenti: * Lasciare sempre una riga orizzontale vuota tra un messaggio e l'altro; * [[Indentazione|indentare]] ogni nuovo messaggio verso destra, inserendo uno o più segni di "<code>:</code>" (due punti) ''all'inizio del paragrafo''. (vedi la sezione [[#Indentazione della discussione]] qui sotto). '''Chiunque''' scriva in una pagina di discussione '''deve sempre firmare''' il proprio messaggio prima di salvare la pagina. {{vedi anche|Aiuto:Firma}} Solo quando si risponde utilizzando il metodo manuale è opportuno inserire manualmente la firma. [[File:Per firmare.png|thumb|upright=2.7|Clicca sempre '''questo bottone''' quando hai finito di scrivere il tuo intervento e prima di salvare la pagina.]] Ci sono due modi per scrivere la propria firma: * Finito di scrivere, clicca sul pulsante raffigurante una penna, posizionato in alto nella finestra di modifica. * Finito di scrivere, aggiungi manualmente <code><nowiki>"--~~~~"</nowiki></code> alla fine del tuo messaggio. Dopo aver salvato la pagina, al posto di <nowiki>"--~~~~"</nowiki> compariranno il nome utente di chi ha scritto il messaggio, insieme alla data e all'ora di salvataggio della pagina. Se non sei un utente registrato, non hai effettuato il [[Aiuto:Login|login]] o la tua sessione non è più attiva, al posto del nome utente comparirà il tuo indirizzo IP. Per verificare di essere connessi con la propria utenza basta premere il pulsante [[Aiuto:Anteprima|anteprima]] della pagina prima di salvarla e verificare che al posto della firma <nowiki>"~~~~"</nowiki> appaia il proprio nome utente. {{Avviso |tipo = importante |immagine = [[File:Emblem-important-red.svg|40px|Smile]] | testo = Usa la firma sempre soltanto nelle pagine di discussione, '''MAI''' nelle voci di Wikipedia. ''(Le voci sono prodotti comunitari, non vanno mai firmate!)'' }} ===Mobile=== [[File:Itwiki_help_reply_mobile.jpg|thumb|upright=1|right|link=|Esempio di risposta da mobile]] Per partecipare ad una discussione utilizzando '''dispositivi mobili''', bisogna aprire la pagina di discussione, premere sul titolo della sezione interessata e scrivere la risposta nel box in fondo alla pagina. Si può iniziare una nuova discussione premendo il pulsante "'''Aggiungi argomento'''" posto in cima alla pagina di discussione o aprendo una pagina di discussione non esistente. Per facilitare la lettura della pagina, si raccomanda di [[Indentazione|indentare]] ogni nuovo messaggio verso destra, inserendo uno o più segni di "<code>:</code>" (due punti) ''all'inizio del paragrafo''. (vedi la sezione [[#Indentazione della discussione]] qui sotto). Oppure selezionando l'opzione "Leggi come pagina Wiki" è possibile, cliccando sul simbolo della matita '''[[File:OOjs_UI_icon_edit-ltr.svg|link=|alt={{int|vector-view-edit|lang=it}}]]''', aggiungere il commento come spiegato in [[#Modifica manuale (desktop)|modifica manuale]]. Se non si accede a Wikipedia dal web ma dall'applicazione per dispositivi mobili, il pulsante per accedere alle pagine di discussione sarà situato in fondo alle voci. </div> '' [ommiss] '' CC-BY-SA 4.0 [[:it:Aiuto:Pagina di discussione]] l4m9f4h11mf09mj91oxljjd8zdiggwp 741036 741035 2026-05-08T17:56:38Z Valcio 46860 Fix 741036 wikitext text/x-wiki Le '''pagine di discussione''' (a volte chiamate col nome inglese '''''talk''''') sono spazi utilizzati per il dialogo e il coordinamento tra gli utenti di Wikipedia. Eccetto le [[Aiuto:Pagine speciali|pagine speciali]] che hanno funzioni tecniche, tutte le altre pagine di Wikipedia ([[aiuto:voce|voci]], [[Wikipedia:pagina utente|pagine utente]], [[Wikipedia:Progetto|progetti tematici]], [[Aiuto:Categorie|categorie]]) dispongono di una relativa pagina di discussione nella quale chiunque può inserire commenti o fare proposte utili per la redazione o modifica dei contenuti relativi. Ad esempio, in "[[Discussione:Ignazio Silone]]" si discutono i contenuti della voce "[[Ignazio Silone]]". Le pagine di discussione fungono anche da luogo di confronto tra gli utenti per discutere problemi e trovare soluzioni, soprattutto nel caso di argomenti controversi. Quando vi sono pareri discordanti o interpretazioni differenti sul contenuto di una pagina, gli utenti non devono ingaggiare una [[Wikipedia:Guerra di modifiche|guerra di modifiche]], ma devono utilizzare la pagina di discussione per dialogare e stabilire il [[wp:consenso|consenso]] necessario a raggiungere una versione condivisa. Si badi bene: una pagina di discussione '''non è un forum''', ma serve solo a discutere i contenuti e a coordinare lo sviluppo di una determinata pagina. == Le principali pagine di discussione == {{tl|Vedi anche|Aiuto:Dove fare una domanda}} Su Wikipedia vi sono molte pagine di discussione, ciascuna con scopi precisi. Le più importanti tipologie sono: * [[#Le pagine di discussione delle voci|pagine di discussione delle voci]], dove si discutono le modifiche relative a ciascuna [[Aiuto:Voce|voce]] di Wikipedia. Lo stesso vale per i template e le categorie; * [[#Le pagine di discussione dei progetti|pagine di discussione dei progetti]], comunemente chiamate "bar tematici", dove si discute di argomenti generali relativi a insiemi di voci che trattano lo stesso tema (come in [[Discussioni progetto:Cinema]]) oppure di questioni relative al funzionamento di Wikipedia (è il caso dei molti "[[:categoria:Progetti di servizio|progetti di servizio]]"); * [[#Le pagine di discussione degli utenti|pagine di discussione degli utenti]], impiegate dai wikipediani per scambiarsi tra loro messaggi inerenti alle proprie attività su Wikipedia, inviando e ricevendo messaggi. Vi sono anche altri spazi dedicati al dialogo tra gli utenti i quali, pur avendo una funzione simile, non sono pagine di discussione in senso stretto, ma hanno comunque un utilizzo simile. Ad esempio: * per discussioni e segnalazioni di interesse generale su Wikipedia c'è il [[#Il bar di Wikipedia|bar di Wikipedia]]; * per informazioni su "come fare qualcosa" su Wikipedia c'è lo [[Aiuto:Sportello informazioni|sportello informazioni]]; * per domande su qualsiasi argomento non sia inerente al funzionamento di Wikipedia c'è l'[[Wikipedia:Oracolo|oracolo]]; * per proporre voci per la vetrina ci sono le [[Wikipedia:Riconoscimenti di qualità/Segnalazioni|segnalazioni per i riconoscimenti di qualità]]; * per le richieste di revisioni dettagliate sulle voci, c'è la [[Wikipedia:Vaglio|pagina dei vagli]]. == Dove si trova la pagina di discussione? == <div class="codex-tabs-sections"> ==Desktop (default)== [[File:Itwiki_help_discusssion_vector2022_1.png|thumb|upright=1.7|left|link=|La linguetta su cui cliccare per entrare nella pagina di discussione in cima alla pagina]] [[File:Itwiki_help_discusssion_vector2022_2.png|thumb|upright=1.7|right|link=|Il pulsante su cui cliccare per entrare nella pagina di discussione dalla barra di navigazione]] {{clear}} In qualunque pagina di Wikipedia ci si trovi (ad eccezione delle pagine speciali), nella parte alta della schermata c'è una linguetta che reca la scritta <tvar name="1">"'''{{Int|talk|lang=it}}'''"</tvar>. In alternativa, quando ci si sposta verso il basso comparirà una barra di navigazione statica, che contiene il pulsante <tvar name=1>'''[[File:OOjs_UI_icon_speechBubbles-ltr.svg|link=|alt={{int|talk|lang=it}}]] {{int|talk|lang=it}}'''</tvar> Questi sono i pulsanti da cliccare per accedere alla pagina di discussione. Per tornare alla pagina principale basterà cliccare sulla prima linguetta, posta subito prima della linguetta "Discussione" (il suo nome sarà diverso a seconda di dove ci si trova: "Voce", "Progetto", "Categoria" ecc). Se il testo "<span style="color:BA0000;">Discussione</span>" è rosso significa che la pagina di discussione non è ancora stata creata. Se si desidera crearla, basterà cliccare sul link e inserire il testo desiderato. ==Desktop (Vector legacy)== [[File:Pulsante Discussione.png|thumb|upright=2.7|center|link=|La linguetta su cui cliccare per entrare nella pagina di discussione di una voce]] In qualunque pagina di Wikipedia ci si trovi (ad eccezione delle pagine speciali), nella parte alta della schermata c'è una linguetta che reca la scritta "'''Discussione'''". Quello è il link da cliccare per accedere alla pagina di discussione. Per tornare alla pagina principale basterà cliccare sulla prima linguetta, posta subito prima della linguetta "Discussione" (il suo nome sarà diverso a seconda di dove ci si trova: "Voce", "Progetto", "Categoria" ecc). Se il testo "<span style="color:BA0000;">Discussione</span>" è rosso significa che la pagina di discussione non è ancora stata creata. Se si desidera crearla, basterà cliccare sul link e inserire il testo desiderato. ==Mobile== [[File:Itwiki_help_discusssion_mobile.jpg|thumb|upright=1.7|center|link=|La linguetta su cui cliccare per entrare nella pagina di discussione di una voce]] In qualunque pagina di Wikipedia ci si trovi (ad eccezione delle pagine speciali), nella parte alta della schermata c'è una linguetta che reca la scritta "'''Discussione'''". Quello è il link da cliccare per accedere alla pagina di discussione. '''È necessario essere [[Aiuto:Registrazione|registrati]] per visualizzarla.''' Per tornare alla pagina principale basterà cliccare sulla prima linguetta, posta subito prima della linguetta "Discussione" (il suo nome sarà diverso a seconda di dove ci si trova: "Voce", "Progetto", "Categoria" ecc). Se il testo "<span style="color:BA0000;">Discussione</span>" è rosso significa che la pagina di discussione non è ancora stata creata. Se si desidera crearla, basterà cliccare sul link e inserire il testo desiderato. </div> === Indirizzo === {{Tipi di pagina}} L'indirizzo della discussione dipende dal [[Aiuto:namespace|tipo di pagina]] a cui la discussione fa riferimento (si veda il box a lato). * Per una [[Aiuto:voce|voce]] titolata "XXXX", l'indirizzo è <code><nowiki>[[Discussione:XXXX]]</nowiki></code>; : (esempio: [[Comunicazione]] e [[Discussione:Comunicazione]]). * Per una pagina di servizio (come Categoria, Progetto, Wikipedia, Aiuto ecc.) quale ad esempio "Categoria:YYY", la discussione si trova a <code><nowiki>[[Discussioni Categoria:YYY]]</nowiki></code> : (esempi: [[Aiuto:Tabelle]] e [[Discussioni Aiuto:Tabelle]]; [[Wikipedia:Vetrina]] e [[Discussioni Wikipedia:Vetrina]]). Per ricercare o linkare direttamente una pagina di discussione basta copiarne direttamente il titolo. Per linkare una specifica [[Aiuto:Sezione|sezione o paragrafo]] all'interno di una pagina di discussione, si deve usare questo codice: <code><nowiki>[[Titolo della pagina di discussione#titolo della sezione]]</nowiki></code>. Esempio (clicca per provare): [[Discussioni aiuto:Pagina di discussione#Esempio di paragrafo]]. {{Avviso|tipo=contenuto|immagine=[[File:Bombilla amarilla - yellow Edison lamp.svg|40px|!]]|testo='''Lo sapevi che''' quando una pagina viene seguita attraverso la funzione [[Aiuto:Osservati speciali|osservati speciali]], viene automaticamente seguita anche la relativa pagina di discussione?}} === Abbreviazioni === Per linkare pagine di discussione relative ad alcuni [[Aiuto:namespace|namespace]] come Progetto e Wikipedia è possibile usare abbreviazioni, ad esempio: * [[dp:Roma]] invece di [[Discussioni progetto:Roma]]. * [[dw:Vetrina]] invece di [[Discussioni wikipedia:Vetrina]] * ecc. Inoltre, per tutte le pagine di discussione si possono usare i nomi originali inglesi con il breve ''Talk'', ad esempio: * [[talk:Mary Poppins (serie di romanzi)]] * [[template talk:Cita]]. == Come si partecipa a una discussione == === Rispetta sempre i tuoi interlocutori === {{Vedi anche|Wikipedia:Wikiquette|Wikipedia: Niente attacchi personali}} [[file:Diskussion-Icon XY.svg|thumb|75px|L'enciclopedia si arricchisce grazie alle diversità di pensiero]] Prima di intervenire in qualunque pagina di discussione, si ricordino due principi fondamentali. * Gli interventi sulle pagine di discussione devono sempre rispettare la [[Aiuto:Wikiquette|'''Wikiquette''']]: ciò significa anche aderire allo spirito di collaborazione e mutua comprensione di Wikipedia (il cosiddetto [[Aiuto:Wikilove|'''Wikilove''']]). * Le discussioni servono a discutere temi di interesse per Wikipedia. Utenti diversi possono avere punti di vista differenti su un dato argomento, ma nelle discussioni si commentano e confrontano sempre e soltanto i contenuti, mai gli autori dei messaggi. Negli spazi di discussione non sono ammesse provocazioni, ''[[Flame (Internet)|flame]]'' (risse verbali) e men che meno [[Wikipedia:Niente attacchi personali|'''attacchi personali''']] contro altri utenti. È indispensabile accettare il fatto che siamo tutti parte della stessa comunità. Siamo tutti wikipediani: tu lo sei ugualmente a come lo sono tutti gli altri, '''qualunque sia il tuo bagaglio culturale o personale'''. Su Wikipedia non esistono ''esperti'', ma solo fonti attendibili e terze. Non squalificare il tuo operato su Wikipedia attraverso atteggiamenti e toni poco consoni ad un progetto collaborativo! === Organizzazione della pagina === Le pagine di discussione sono organizzate secondo pochi semplici criteri: * Ogni argomento si discute all'interno di una [[aiuto:sezione|sezione]] apposita. * Per inserire un ''nuovo'' argomento, clicca sulla linguetta "'''Aggiungi discussione'''" posta in alto nella schermata<ref>Se usi la [[wikipedia:Skin|skin monobook]] sarà quella contrassegnata con un "+".</ref>. Comparirà allora una nuova finestra con una riga denominata "Oggetto/intestazione", dove inserire ''il titolo'' della nuova discussione, e una finestra più grande in cui inserire il testo del proprio messaggio. * Tutti i messaggi vanno sempre '''[[aiuto:Firma|firmati]]'''. * Non si cancellano i messaggi degli altri utenti. * Ogni nuovo intervento va inserito in fondo alla discussione in corso, in modo che la discussione sia organizzata automaticamente in ordine cronologico, dall'intervento più vecchio a quello più recente. === Scrivere un messaggio === <div class="mw-gadget-tabbedwindow"> ===Strumenti di discussione (desktop, default)=== [[File:Itwiki_help_reply_tools.png|thumb|upright=1.7|center|link=|Esempio di utilizzo degli strumenti di discussione]] Utilizzando gli '''strumenti di discussione''', attivati di default per tutte le utenze e attivabile/disattivabile dalla sezione ''Pagine di discussione'' nelle [[Speciale:Preferenze#mw-prefsection-editing|preferenze sulla casella di modifica]] e dalla sezione ''Strumenti di discussione'' delle [[Speciale:Preferenze#mw-prefsection-betafeatures|funzionalità beta]], è possibile: * Rispondere a dei messaggi premendo il pulsante <code>'''[rispondi]'''</code> posto in seguito ad ogni messaggio; nel caso il messaggio non sia firmato, il pulsante non apparirà e dunque sarà necessario procedere con la [[#Modifica manuale (desktop)|modifica manuale]]. * Creare nuove discussioni premendo la linguetta "'''Aggiungi discussione'''" o aprendo una pagina di discussione non esistente. * Ricevere una notifica ogni volta che viene aggiunto un messaggio in una discussione premendo il pulsante <code>'''[iscriviti]'''</code>, situato all'estremo destro dello schermo, alla stessa altezza del titolo della sezione. ===Modifica manuale (desktop)=== [[File:Itwiki_help_reply_desktop.png|thumb|upright=1.7|right|link=|Esempio di risposta attraverso la modifica manuale]] [[File:Itwiki help newsection desktop.png|thumb|upright=1.7|left|link=|Dimostrazione di come si aggiunge una nuova discussione]] {{Avviso |testo = '''Lo sapevi che''' su Wikipedia esiste un [[Aiuto:Tour guidato|Tour guidato]] per imparare in fretta ad usare le pagine di discussione? '''[[Aiuto:Tour_guidato/Tutorial_2-1|Clicca qui per provare!]]''' |tipo = contenuto |immagine = [[File:Bombilla amarilla - yellow Edison lamp.svg|40px|!]] }} Per partecipare ad una discussione utilizzando il '''metodo manuale''', bisogna [[Aiuto:Modifica|modificare]] la pagina di discussione. Ciò avviene in modo identico ad una pagina tradizionale, attraverso la linguetta "'''{{MediaWiki:Visualeditor-ca-editsource}}'''" posta nella parte alta della schermata, oppure utilizzando il pulsante "<code>[modifica]</code>" posto fianco del titolo di una delle sezioni che compongono la pagina. Si può iniziare una nuova discussione premendo la linguetta "'''Aggiungi discussione'''" o aprendo una pagina di discussione non esistente. Per facilitare la lettura della pagina, si raccomanda di usare i seguenti accorgimenti: * Lasciare sempre una riga orizzontale vuota tra un messaggio e l'altro; * [[Indentazione|indentare]] ogni nuovo messaggio verso destra, inserendo uno o più segni di "<code>:</code>" (due punti) ''all'inizio del paragrafo''. (vedi la sezione [[#Indentazione della discussione]] qui sotto). '''Chiunque''' scriva in una pagina di discussione '''deve sempre firmare''' il proprio messaggio prima di salvare la pagina. {{vedi anche|Aiuto:Firma}} Solo quando si risponde utilizzando il metodo manuale è opportuno inserire manualmente la firma. [[File:Per firmare.png|thumb|upright=2.7|Clicca sempre '''questo bottone''' quando hai finito di scrivere il tuo intervento e prima di salvare la pagina.]] Ci sono due modi per scrivere la propria firma: * Finito di scrivere, clicca sul pulsante raffigurante una penna, posizionato in alto nella finestra di modifica. * Finito di scrivere, aggiungi manualmente <code><nowiki>"--~~~~"</nowiki></code> alla fine del tuo messaggio. Dopo aver salvato la pagina, al posto di <nowiki>"--~~~~"</nowiki> compariranno il nome utente di chi ha scritto il messaggio, insieme alla data e all'ora di salvataggio della pagina. Se non sei un utente registrato, non hai effettuato il [[Aiuto:Login|login]] o la tua sessione non è più attiva, al posto del nome utente comparirà il tuo indirizzo IP. Per verificare di essere connessi con la propria utenza basta premere il pulsante [[Aiuto:Anteprima|anteprima]] della pagina prima di salvarla e verificare che al posto della firma <nowiki>"~~~~"</nowiki> appaia il proprio nome utente. {{Avviso |tipo = importante |immagine = [[File:Emblem-important-red.svg|40px|Smile]] | testo = Usa la firma sempre soltanto nelle pagine di discussione, '''MAI''' nelle voci di Wikipedia. ''(Le voci sono prodotti comunitari, non vanno mai firmate!)'' }} ===Mobile=== [[File:Itwiki_help_reply_mobile.jpg|thumb|upright=1|right|link=|Esempio di risposta da mobile]] Per partecipare ad una discussione utilizzando '''dispositivi mobili''', bisogna aprire la pagina di discussione, premere sul titolo della sezione interessata e scrivere la risposta nel box in fondo alla pagina. Si può iniziare una nuova discussione premendo il pulsante "'''Aggiungi argomento'''" posto in cima alla pagina di discussione o aprendo una pagina di discussione non esistente. Per facilitare la lettura della pagina, si raccomanda di [[Indentazione|indentare]] ogni nuovo messaggio verso destra, inserendo uno o più segni di "<code>:</code>" (due punti) ''all'inizio del paragrafo''. (vedi la sezione [[#Indentazione della discussione]] qui sotto). Oppure selezionando l'opzione "Leggi come pagina Wiki" è possibile, cliccando sul simbolo della matita '''[[File:OOjs_UI_icon_edit-ltr.svg|link=|alt={{int|vector-view-edit|lang=it}}]]''', aggiungere il commento come spiegato in [[#Modifica manuale (desktop)|modifica manuale]]. Se non si accede a Wikipedia dal web ma dall'applicazione per dispositivi mobili, il pulsante per accedere alle pagine di discussione sarà situato in fondo alle voci. </div> '' [ommiss] '' CC-BY-SA 4.0 [[:it:Aiuto:Pagina di discussione]] 1ddymlagxbrl1e1idhe02ds284dzugp User:Ponor/common.js 2 148324 741033 725339 2026-05-08T17:36:33Z Ponor 47975 Blanked the page 741033 javascript text/javascript phoiac9h4m842xq45sp7s6u21eteeq1 741041 741033 2026-05-08T19:00:29Z Ponor 47975 Restored revision 725339 by [[Special:Contributions/Ponor|Ponor]] ([[User talk:Ponor|talk]]) / Twinkle 741041 javascript text/javascript mw.loader.load("//test.wikipedia.org/w/index.php?title=User:Ponor/wAwB.js&action=raw&ctype=text/javascript"); mw.loader.load("//test.wikipedia.org/w/index.php?title=User:Ponor/CoolCat.js&action=raw&ctype=text/javascript"); mw.loader.load("//test.wikipedia.org/w/index.php?title=User:Ponor/chess-gadget.js&action=raw&ctype=text/javascript"); mw.loader.using(['jquery.ui', 'mediawiki.util'], function(){ mw.loader.load('//commons.wikimedia.org/w/load.php?modules=ext.gadget.Cat-a-lot'); }); //mw.loader.load("//test.wikipedia.org/w/index.php?title=User:Ponor/chess.js&action=raw&ctype=text/javascript"); // Inline diffs // en.wikipedia.org/wiki/User:Bradv/Scripts/ExpandDiffs //mw.loader.load("//en.wikipedia.org/w/index.php?title=User:Bradv/Scripts/ExpandDiffs.js&action=raw&ctype=text/javascript"); // Inline diffs // en.wikipedia.org/wiki/User:Writ_Keeper/Scripts/inlineDiffDocs //mw.loader.load("//en.wikipedia.org/w/index.php?title=User:Writ Keeper/Scripts/commonHistory.js&action=raw&ctype=text/javascript"); // Inline patrol (use with inline diff tools) // meta.wikimedia.org/wiki/User:Ponor/contributions-and-history-patrol.js //mw.loader.load("//test.wikipedia.org/w/index.php?title=User:Ponor/inline-patrol.js&action=raw&ctype=text/javascript"); // Inline diffs and inline patrol window.inline_patrol_running = false; //metawiki one mw.loader.load("//test.wikipedia.org/w/index.php?title=User:Ponor/inline-diff-inline-patrol.js&action=raw&ctype=text/javascript"); //------------------------------------ Configuration window.ip_configuration = { diff_button: "show diff", max_diff_height: "32em", patrol_disabled: false, } // Fancy diffs mw.loader.load('https://commons.wikimedia.org/w/index.php?title=User:Enterprisey/fancy-diffs.js&action=raw&ctype=text/javascript'); //mw.loader.load('https://commons.wikimedia.org/w/index.php?title=User:Serhio_Magpie/instantDiffs.js&action=raw&ctype=text/javascript'); mw.loader.load( 'https://www.mediawiki.org/w/index.php?title=User:Serhio_Magpie/instantDiffs.test.js&action=raw&ctype=text/javascript' ); // Really quick block // meta.wikimedia.org/wiki/User:Ponor/really-quick-block mw.loader.load("//meta.wikimedia.org/w/index.php?title=User:Ponor/really-quick-block.js&action=raw&ctype=text/javascript"); window.rqb_buttons = { V1: {reason:"vandalism - api test", expiry:"1 minute", options:["anononly","autoblock", "nocreate", "allowusertalk"]}, P2: {reason:"profanity - api test", expiry:"2 minutes", options:["anononly","autoblock", "nocreate", "allowusertalk"]}, A6: {reason:"attacks - api test", expiry:"6 minutes"}, }; //My copy of HotCat gadget //mw.loader.load("//test.wikipedia.org/w/index.php?title=User:Ponor/HotCat.js&action=raw&ctype=text/javascript"); // JavaScript Wiki Browser // en.wikipedia.org/wiki/User:Joeytje50/JWB mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js/load.js&action=raw&ctype=text/javascript'); ll5hl81rltxtpqmk8334zl8lo81jcen User talk:JWBTH/CD test page 3 154341 741102 740841 2026-05-09T07:04:06Z JWBTH 52211 /* Section 1 */ delete addition ([[mw:c:Special:MyLanguage/User:JWBTH/CD|CD]]) 741102 wikitext text/x-wiki == Section 1 == first section comment [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 02:37, 20 November 2024 (UTC) unsigned comment end {{unsigned|user}} : comment to be edited [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 02:38, 20 November 2024 (UTC) :: comment to test buttons [[User:Jack who built the house|Jack who built the house]] ([[User talk:Jack who built the house|talk]]) 02:41, 20 November 2024 (UTC) ::: child comment of comment to test buttons [[User:Jack who built the house|Jack who built the house]] ([[User talk:Jack who built the house|talk]]) 06:09, 27 August 2025 (UTC) ::: test [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 19:32, 16 March 2026 (UTC) : [[#c-Test_account_8-20241120023700-Section_1|Test account 8 @ 02:37, 20 November 2024 (UTC)]] [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 06:43, 28 March 2026 (UTC) === test2 === test [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 14:55, 14 September 2025 (UTC) : [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 20:13, 26 March 2026 (UTC) === Comment with complex markup === * ̴͍͖̪̭̂ฑεᚹẻ̴̦̜̜͙̰̉̒͠͠иℳἒԊ৩βà̸̩̳̗m̶̧̲̲̬̌̀̈́̀ь β ì̵̛̹̌͛͝«Зᾷу៚ἐฑἒдì̵̛̹̌͛͝ю»ì̵̛̹̌͛͝ ! Ᾰ D̴̞̓̊̀ля чẻ̴̦̜̜͙̰̉̒͠͠рẻ̴̦̜̜͙̰̉̒͠͠счуr̵̢͈͕̺͎̀̅ s̸̢̈́ерьӚz̵͓̫̻͔͠Ԋыᚸ βыΔε௭иm̶̧̲̲̬̌̀̈́̀ь <s>ฑр৩c̴̨͍͇̪̏̿́̽̕m̶̧̲̲̬̌̀̈́̀раԊc̴̨͍͇̪̏̿́̽̕m̶̧̲̲̬̌̀̈́̀β৩</s> ३ᾷβ৩Δь «D̴̞̓̊̀β৩йԊая z̵͓̫̻͔͠à̸̩̳̗௶พь». Ἇ m̶̧̲̲̬̌̀̈́̀৩ иz̵͓̫̻͔͠ Ԋẻ̴̦̜̜͙̰̉̒͠͠k̸̟͔̯̯̖̍̂͐̎͘৩m̶̧̲̲̬̌̀̈́̀৩ᚹыᚸ c̴̨͍͇̪̏̿́̽̕m̶̧̲̲̬̌̀̈́̀ᾷ z̵͓̫̻͔͠а௶พь m̶̧̲̲̬̌̀̈́̀ᾷк ì̵̛̹̌͛͝и ௭ε३εm̶̧̲̲̬̌̀̈́̀ чεᚹعz̵͓̫̻͔͠ k̸̟͔̯̯̖̍̂͐̎͘ᚹᾷй !!! ̴͍͖̪̭̂ <span style="font-family:Calibri; font-size:175%; display: inline-block; letter-spacing: 5px; transform: rotate(10deg); padding: 20px 0px;>[[User:Example|'''<span style="color: Magenta; position: relative; top: -4px;">ঞ</span><span style="color: SpringGreen; position: relative; top: -3px;">ʆ</span><span style="color: red; position: relative; top: -2px;">ἕ</span><span style="color: LimeGreen; position: relative; top: -1px;">ฃ</span><span style="color: DeepPink; position: relative; top: 2px;">r̵̢͈͕̺͎̀̅</span><span style="color: Aqua; position: relative; top: 4px;"> ̴͍͖̪̭̂</span><span style="color: DarkOrange; position: relative; top: 4px;">D̴̞̓̊̀</span><span style="color: DarkOrchid; position: relative; top: 3px;">ἒ</span><span style="color: Chartreuse; position: relative; top: 4px;"> ̴͍͖̪̭̂</span><span style="color: Fuchsia; position: relative; top: 1px;">ໃ</span><span style="color: DarkTurquoise; position: relative; top: 0px;">à̸̩̳̗</span><span style="color: Forestgreen; position: relative; top: -2px;">ʁ</span><span style="color: deeppink; position: relative; top: 2px;">i̵͖̒͆̕͝ͅ</span><span style="color: Turquoise; position: relative; top: -1px;">ń̸̳͑̑͌</span><span style="color: LimeGreen; position: relative; top: -4px;">៩</span><span style="color: Magenta; position: relative; top: 1px;">♥</font>''']]</span> 14:08, 1 April 2026 (UTC) test === Transcluded comments === {{User talk:JWBTH/CD test page/comment}} : test. [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 10:36, 20 April 2026 (UTC) === Vote === Comment. # Vote 1. [[User:Example|Example]] ([[User talk:Example|talk]]) 06:46, 9 April 2026 (UTC) # Vote 2. [[User:Example|Example]] ([[User talk:Example|talk]]) 06:46, 9 April 2026 (UTC) === Last subsection === test [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 14:56, 14 September 2025 (UTC) : Comment [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 09:24, 31 March 2026 (UTC) :: Comment [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 09:25, 31 March 2026 (UTC) ::: Comment beginning<br> Comment ending [[User:Example|Example]] ([[User talk:Example|talk]]) 09:34, 31 March 2026 (UTC) == Section to add test comments == section [[User:Example|Example]] ([[User talk:Example|talk]]) 02:37, 1 March 2026 (UTC) : Test comment with random number 0.4478961847809999 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 22:01, 19 April 2026 (UTC) : Test comment with random number 0.42841430187725704 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 22:10, 19 April 2026 (UTC) == Section with equals sign (=) for moving == <div class="cd-moveMark">''Moved to [[User talk:JWBTH/CD test page 2#Section with equals sign ({{=}}) for moving]]. [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 13:40, 1 April 2026 (UTC)''</div> == test == <div class="cd-moveMark">''Moved to [[User talk:JWBTH/CD test page 2#test]]. [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 14:33, 17 April 2026 (UTC)''</div> == Section for moving == test [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 19:52, 15 March 2026 (UTC) 35z7i9v9hizbaoxev3uhluvtauazuzy Test 0 155073 741011 740898 2026-05-08T15:48:32Z Valcio 46860 test 741011 wikitext text/x-wiki <div class="codex-tabs" data-framed="true"> <div class="codex-tab" data-label="Overview"> This is the overview tab. * Normal wikitext lists work here. * Links like [[Main Page]] work here too. </div> <div class="codex-tab" data-label="Details"> == Details heading == This content becomes the second Codex tab. </div> <div class="codex-tab" data-label="Examples"> Here are examples: {| class="wikitable" ! Name !! Status |- | Foo || Done |- | Bar || Draft |} </div> </div> 3o51xjwjw9bg3m5gia4xyoj1v2rcwgj 741012 741011 2026-05-08T15:53:52Z Valcio 46860 test 741012 wikitext text/x-wiki <div class="codex-tabs" data-framed="true"> <div class="codex-tab" data-label="Overview"> This is the first tab content. More content here. </div> <div class="codex-tab" data-label="Details"> This is the second tab content. More content here. </div> </div> qidws0vnny9slved3i48p15y4gd8pt2 741013 741012 2026-05-08T15:54:15Z Valcio 46860 - 741013 wikitext text/x-wiki <div class="codex-tabs" > <div class="codex-tab" data-label="Overview"> This is the first tab content. More content here. </div> <div class="codex-tab" data-label="Details"> This is the second tab content. More content here. </div> </div> fxz8ycnnd80uycv9xffz9j6tk8jnvpd 741016 741013 2026-05-08T15:56:39Z Valcio 46860 test 741016 wikitext text/x-wiki <div class="codex-tabs"> <div class="codex-tab" data-label="Overview"> This is the overview tab. More content here. </div> <div class="codex-tab" data-label="Details"> This is the details tab. More content here. </div> </div> l6e8ip4ppjspu37gyocitz7xdgt9img 741018 741016 2026-05-08T15:59:37Z Valcio 46860 + 741018 wikitext text/x-wiki <div class="codex-tabs-sections"> == Overview == This becomes the first tab content. Normal wikitext works here: * list item * another item == Details == This becomes the second tab content. {| class="wikitable" ! Name !! Status |- | Foo || Done |} == Examples == This becomes the third tab content. </div> f1c64w4wfrtgp715h6r3v93te2ttdom 741022 741018 2026-05-08T16:02:43Z Valcio 46860 t 741022 wikitext text/x-wiki <div class="codex-tabs-sections" data-framed="true"> == Overview == This is the overview tab. * Item one * Item two == Details == This is the details tab. === Subheading inside Details === This should stay inside the Details tab. == Examples == This is the examples tab. </div> o8ygypx8qv6iyg30h6vxg4qmh14tiim 741027 741022 2026-05-08T16:10:56Z Valcio 46860 + 741027 wikitext text/x-wiki <div class="codex-tabs-sections" data-framed="true"> == Overview == This is the overview tab. * Item one * Item two == Details == This is the details tab. === Subheading inside Details === This should stay inside the Details tab. == Examples == This is the examples tab. </div> <div class="codex-tabs-sections"> == Overview == This is the overview tab. * Item one * Item two == Details == This is the details tab. === Subheading inside Details === This should stay inside the Details tab. == Examples == This is the examples tab. </div> h2xiawngu3jdrlmrjdeqb7mmiwoldsg 741028 741027 2026-05-08T16:11:40Z Valcio 46860 t 741028 wikitext text/x-wiki <div class="codex-tabs-sections" data-framed="false"> == Overview == This is the overview tab. * Item one * Item two == Details == This is the details tab. === Subheading inside Details === This should stay inside the Details tab. == Examples == This is the examples tab. </div> <div class="codex-tabs-sections"> == Overview == This is the overview tab. * Item one * Item two == Details == This is the details tab. === Subheading inside Details === This should stay inside the Details tab. == Examples == This is the examples tab. </div> 65zzlwsm0qzuqpirc5kqocwrxij49uz MediaWiki:GrowthExperimentsSuggestedEdits.json 8 156151 741042 740595 2026-05-08T19:02:19Z Etonkovidova (WMF) 27425 testing invalid input 741042 json application/json { "GEInfoboxTemplates": [ "m", "custom", "my own infobox", "my own template" ], "copyedit": { "disabled": false, "templates": [ "Who", "Which", "Whose", "To whom?", "From whom?", "Like whom?", "Compared to?", "NPOV", "Copy edit", "Proofreader needed", "Pronunciation needed", "Romanization needed", "Advert" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Basic copyediting" }, "expand": { "disabled": false, "templates": [ "Stub", "Missing information", "Expand section" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Manual of Style/Layout" }, "image_recommendation": { "disabled": false, "excludedTemplates": [], "excludedCategories": [], "learnmore": "", "maxTasksPerDay": 25, "templates": [], "group": "medium", "type": "image-recommendation" }, "link_recommendation": { "disabled": false, "excludedTemplates": [], "excludedCategories": [], "learnmore": "Hello World", "maximumLinksToShowPerTask": 3, "excludedSections": [ "foo" ], "maxTasksPerDay": 6, "underlinkedWeight": 0.5, "minimumLinkScore": 0.6, "maximumEditsTaskIsAvailable": "150", "templates": [], "group": "easy", "type": "link-recommendation" }, "links": { "disabled": false, "templates": [ "Sections", "Cleanup bare URLs" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Manual of Style/Linking" }, "references": { "disabled": false, "templates": [ "Citation needed", "Unreferenced" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Citing sources" }, "section_image_recommendation": { "disabled": false, "excludedTemplates": [], "excludedCategories": [], "learnmore": "", "maxTasksPerDay": 1, "templates": [], "group": "medium", "type": "section-image-recommendation" }, "update": { "disabled": false, "templates": [ "Update", "Update inline" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:As of" }, "$version": "2.0.0" } 3o5nqema6u5k9b6qo7jk9e86nn3mzw8 741043 741042 2026-05-08T19:02:57Z Etonkovidova (WMF) 27425 Undid revision [[Special:Diff/741042|741042]] by [[Special:Contributions/Etonkovidova (WMF)|Etonkovidova (WMF)]] ([[User talk:Etonkovidova (WMF)|talk]]) 741043 json application/json { "GEInfoboxTemplates": [ "m", "custom", "my own infobox" ], "copyedit": { "disabled": false, "templates": [ "Who", "Which", "Whose", "To whom?", "From whom?", "Like whom?", "Compared to?", "NPOV", "Copy edit", "Proofreader needed", "Pronunciation needed", "Romanization needed", "Advert" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Basic copyediting" }, "expand": { "disabled": false, "templates": [ "Stub", "Missing information", "Expand section" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Manual of Style/Layout" }, "image_recommendation": { "disabled": false, "excludedTemplates": [], "excludedCategories": [], "learnmore": "", "maxTasksPerDay": 25, "templates": [], "group": "medium", "type": "image-recommendation" }, "link_recommendation": { "disabled": false, "excludedTemplates": [], "excludedCategories": [], "learnmore": "Hello World", "maximumLinksToShowPerTask": 3, "excludedSections": [ "foo" ], "maxTasksPerDay": 6, "underlinkedWeight": 0.5, "minimumLinkScore": 0.6, "maximumEditsTaskIsAvailable": "150", "templates": [], "group": "easy", "type": "link-recommendation" }, "links": { "disabled": false, "templates": [ "Sections", "Cleanup bare URLs" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Manual of Style/Linking" }, "references": { "disabled": false, "templates": [ "Citation needed", "Unreferenced" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Citing sources" }, "section_image_recommendation": { "disabled": false, "excludedTemplates": [], "excludedCategories": [], "learnmore": "", "maxTasksPerDay": 1, "templates": [], "group": "medium", "type": "section-image-recommendation" }, "update": { "disabled": false, "templates": [ "Update", "Update inline" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:As of" }, "$version": "2.0.0" } cuezlkncpji6aac1wyd9jige25z9a2w 741044 741043 2026-05-08T19:03:38Z Etonkovidova (WMF) 27425 741044 json application/json { "GEInfoboxTemplates": [ "m", "custom" ], "copyedit": { "disabled": false, "templates": [ "Who", "Which", "Whose", "To whom?", "From whom?", "Like whom?", "Compared to?", "NPOV", "Copy edit", "Proofreader needed", "Pronunciation needed", "Romanization needed", "Advert" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Basic copyediting" }, "expand": { "disabled": false, "templates": [ "Stub", "Missing information", "Expand section" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Manual of Style/Layout" }, "image_recommendation": { "disabled": false, "excludedTemplates": [], "excludedCategories": [], "learnmore": "", "maxTasksPerDay": 25, "templates": [], "group": "medium", "type": "image-recommendation" }, "link_recommendation": { "disabled": false, "excludedTemplates": [], "excludedCategories": [], "learnmore": "Hello World", "maximumLinksToShowPerTask": 3, "excludedSections": [ "foo" ], "maxTasksPerDay": 6, "underlinkedWeight": 0.5, "minimumLinkScore": 0.6, "maximumEditsTaskIsAvailable": "150", "templates": [], "group": "easy", "type": "link-recommendation" }, "links": { "disabled": false, "templates": [ "Sections", "Cleanup bare URLs" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Manual of Style/Linking" }, "references": { "disabled": false, "templates": [ "Citation needed", "Unreferenced" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Citing sources" }, "section_image_recommendation": { "disabled": false, "excludedTemplates": [], "excludedCategories": [], "learnmore": "", "maxTasksPerDay": 1, "templates": [], "group": "medium", "type": "section-image-recommendation" }, "update": { "disabled": false, "templates": [ "Update", "Update inline" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:As of" }, "$version": "2.0.0" } pl4a32s9xzcd4rhe2jorre08qjsvps6 741045 741044 2026-05-08T19:09:55Z Etonkovidova (WMF) 27425 741045 json application/json { "GEInfoboxTemplates": [ "m", "custom", "Template:" ], "copyedit": { "disabled": false, "templates": [ "Who", "Which", "Whose", "To whom?", "From whom?", "Like whom?", "Compared to?", "NPOV", "Copy edit", "Proofreader needed", "Pronunciation needed", "Romanization needed", "Advert" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Basic copyediting" }, "expand": { "disabled": false, "templates": [ "Stub", "Missing information", "Expand section" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Manual of Style/Layout" }, "image_recommendation": { "disabled": false, "excludedTemplates": [], "excludedCategories": [], "learnmore": "", "maxTasksPerDay": 25, "templates": [], "group": "medium", "type": "image-recommendation" }, "link_recommendation": { "disabled": false, "excludedTemplates": [], "excludedCategories": [], "learnmore": "Hello World", "maximumLinksToShowPerTask": 3, "excludedSections": [ "foo" ], "maxTasksPerDay": 6, "underlinkedWeight": 0.5, "minimumLinkScore": 0.6, "maximumEditsTaskIsAvailable": "150", "templates": [], "group": "easy", "type": "link-recommendation" }, "links": { "disabled": false, "templates": [ "Sections", "Cleanup bare URLs" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Manual of Style/Linking" }, "references": { "disabled": false, "templates": [ "Citation needed", "Unreferenced" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Citing sources" }, "section_image_recommendation": { "disabled": false, "excludedTemplates": [], "excludedCategories": [], "learnmore": "", "maxTasksPerDay": 1, "templates": [], "group": "medium", "type": "section-image-recommendation" }, "update": { "disabled": false, "templates": [ "Update", "Update inline" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:As of" }, "$version": "2.0.0" } 2ux9mx0h6j86udrlmzohdtw1kjnso2b 741046 741045 2026-05-08T19:10:10Z Etonkovidova (WMF) 27425 741046 json application/json { "GEInfoboxTemplates": [ "m", "custom" ], "copyedit": { "disabled": false, "templates": [ "Who", "Which", "Whose", "To whom?", "From whom?", "Like whom?", "Compared to?", "NPOV", "Copy edit", "Proofreader needed", "Pronunciation needed", "Romanization needed", "Advert" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Basic copyediting" }, "expand": { "disabled": false, "templates": [ "Stub", "Missing information", "Expand section" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Manual of Style/Layout" }, "image_recommendation": { "disabled": false, "excludedTemplates": [], "excludedCategories": [], "learnmore": "", "maxTasksPerDay": 25, "templates": [], "group": "medium", "type": "image-recommendation" }, "link_recommendation": { "disabled": false, "excludedTemplates": [], "excludedCategories": [], "learnmore": "Hello World", "maximumLinksToShowPerTask": 3, "excludedSections": [ "foo" ], "maxTasksPerDay": 6, "underlinkedWeight": 0.5, "minimumLinkScore": 0.6, "maximumEditsTaskIsAvailable": "150", "templates": [], "group": "easy", "type": "link-recommendation" }, "links": { "disabled": false, "templates": [ "Sections", "Cleanup bare URLs" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Manual of Style/Linking" }, "references": { "disabled": false, "templates": [ "Citation needed", "Unreferenced" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:Citing sources" }, "section_image_recommendation": { "disabled": false, "excludedTemplates": [], "excludedCategories": [], "learnmore": "", "maxTasksPerDay": 1, "templates": [], "group": "medium", "type": "section-image-recommendation" }, "update": { "disabled": false, "templates": [ "Update", "Update inline" ], "excludedTemplates": [], "excludedCategories": [], "learnmore": "Wikipedia:As of" }, "$version": "2.0.0" } pl4a32s9xzcd4rhe2jorre08qjsvps6 User:Serhio Magpie/instantDiffs.js 2 167026 741101 740638 2026-05-09T06:13:03Z Serhio Magpie 37334 [2162944] [v5.5.1]: Updated from repository. 741101 javascript text/javascript /** * Instant Diffs * * Version: 5.5.1 * Author: Serhio Magpie * Licenses: (MIT OR CC-BY-SA-4.0) * Documentation: https://www.mediawiki.org/wiki/Instant_Diffs * * For license information please see: https://www.mediawiki.org/wiki/User:Serhio_Magpie/instantDiffs.js.LEGAL.txt */ /* <nowiki> */ (()=>{var Xn=Object.create;var je=Object.defineProperty,eo=Object.defineProperties,to=Object.getOwnPropertyDescriptor,io=Object.getOwnPropertyDescriptors,so=Object.getOwnPropertyNames,Ps=Object.getOwnPropertySymbols,Es=Object.getPrototypeOf,$s=Object.prototype.hasOwnProperty,no=Object.prototype.propertyIsEnumerable,oo=Reflect.get;var Xt=(i,e,t)=>e in i?je(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t,f=(i,e)=>{for(var t in e||(e={}))$s.call(e,t)&&Xt(i,t,e[t]);if(Ps)for(var t of Ps(e))no.call(e,t)&&Xt(i,t,e[t]);return i},j=(i,e)=>eo(i,io(e));var As=i=>e=>{var t=i[e];if(t)return t();throw new Error("Module not found in bundle: "+e)};var v=(i,e)=>()=>(i&&(e=i(i=0)),e);var se=(i,e)=>()=>(e||i((e={exports:{}}).exports,e),e.exports),Q=(i,e)=>{for(var t in e)je(i,t,{get:e[t],enumerable:!0})},Ts=(i,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of so(e))!$s.call(i,n)&&n!==t&&je(i,n,{get:()=>e[n],enumerable:!(s=to(e,n))||s.enumerable});return i};var ro=(i,e,t)=>(t=i!=null?Xn(Es(i)):{},Ts(e||!i||!i.__esModule?je(t,"default",{value:i,enumerable:!0}):t,i)),Me=i=>Ts(je({},"__esModule",{value:!0}),i);var a=(i,e,t)=>Xt(i,typeof e!="symbol"?e+"":e,t);var Oe=(i,e,t)=>oo(Es(i),t,e);var m=(i,e,t)=>new Promise((s,n)=>{var r=h=>{try{u(t.next(h))}catch(b){n(b)}},c=h=>{try{u(t.throw(h))}catch(b){n(b)}},u=h=>h.done?s(h.value):Promise.resolve(h.value).then(r,c);u((t=t.apply(i,e)).next())});var ao,o,T=v(()=>{self.instantDiffs||(self.instantDiffs={});ao=self.instantDiffs,o=ao});var Is=se((vr,Os)=>{Os.exports=(function(e){var t=String.prototype.split,s=/()??/.exec("")[1]===e,n;return n=function(r,g,u){if(Object.prototype.toString.call(g)!=="[object RegExp]")return t.call(r,g,u);var h=[],b=(g.ignoreCase?"i":"")+(g.multiline?"m":"")+(g.extended?"x":"")+(g.sticky?"y":""),x=0,g=new RegExp(g.source,b+"g"),D,E,ue,Ss;for(r+="",s||(D=new RegExp("^"+g.source+"$(?!\\s)",b)),u=u===e?-1>>>0:u>>>0;(E=g.exec(r))&&(ue=E.index+E[0].length,!(ue>x&&(h.push(r.slice(x,E.index)),!s&&E.length>1&&E[0].replace(D,function(){for(var ct=1;ct<arguments.length-2;ct++)arguments[ct]===e&&(E[ct]=e)}),E.length>1&&E.index<r.length&&Array.prototype.push.apply(h,E.slice(1)),Ss=E[0].length,x=ue,h.length>=u)));)g.lastIndex===E.index&&g.lastIndex++;return x===r.length?(Ss||!g.test(""))&&h.push(""):h.push(r.slice(x)),h.length>u?h.slice(0,u):h},n})()});var Ws=se((kr,Rs)=>{var lo=[].indexOf;Rs.exports=function(i,e){if(lo)return i.indexOf(e);for(var t=0;t<i.length;++t)if(i[t]===e)return t;return-1}});var ti=se((yr,Ns)=>{var ei=Ws();Ns.exports=co;function co(i){var e=i.classList;if(e)return e;var t={add:s,remove:n,contains:r,toggle:c,toString:u,length:0,item:h};return t;function s(g){var D=b();ei(D,g)>-1||(D.push(g),x(D))}function n(g){var D=b(),E=ei(D,g);E!==-1&&(D.splice(E,1),x(D))}function r(g){return ei(b(),g)>-1}function c(g){return r(g)?(n(g),!1):(s(g),!0)}function u(){return i.className}function h(g){var D=b();return D[g]||null}function b(){var g=i.className;return fo(g.split(" "),uo)}function x(g){var D=g.length;i.className=g.join(" "),t.length=D;for(var E=0;E<g.length;E++)t[E]=g[E];delete g[D]}}function fo(i,e){for(var t=[],s=0;s<i.length;s++)e(i[s])&&t.push(i[s]);return t}function uo(i){return!!i}});var Vs=se((xr,Fs)=>{var ho={className:"class",htmlFor:"for"},po={accept:new Set(["form","input"]),"accept-charset":new Set(["form"]),accesskey:"GLOBAL",action:new Set(["form"]),align:new Set(["applet","caption","col","colgroup","hr","iframe","img","table","tbody","td","tfoot","th","thead","tr"]),alt:new Set(["applet","area","img","input"]),async:new Set(["script"]),autocomplete:new Set(["form","input"]),autofocus:new Set(["button","input","keygen","select","textarea"]),autoplay:new Set(["audio","video"]),autosave:new Set(["input"]),bgcolor:new Set(["body","col","colgroup","marquee","table","tbody","tfoot","td","th","tr"]),border:new Set(["img","object","table"]),buffered:new Set(["audio","video"]),challenge:new Set(["keygen"]),charset:new Set(["meta","script"]),checked:new Set(["command","input"]),cite:new Set(["blockquote","del","ins","q"]),class:"GLOBAL",code:new Set(["applet"]),codebase:new Set(["applet"]),color:new Set(["basefont","font","hr"]),cols:new Set(["textarea"]),colspan:new Set(["td","th"]),content:new Set(["meta"]),contenteditable:"GLOBAL",contextmenu:"GLOBAL",controls:new Set(["audio","video"]),coords:new Set(["area"]),data:new Set(["object"]),datetime:new Set(["del","ins","time"]),default:new Set(["track"]),defer:new Set(["script"]),dir:"GLOBAL",dirname:new Set(["input","textarea"]),disabled:new Set(["button","command","fieldset","input","keygen","optgroup","option","select","textarea"]),download:new Set(["a","area"]),draggable:"GLOBAL",dropzone:"GLOBAL",enctype:new Set(["form"]),for:new Set(["label","output"]),form:new Set(["button","fieldset","input","keygen","label","meter","object","output","progress","select","textarea"]),formaction:new Set(["input","button"]),headers:new Set(["td","th"]),height:new Set(["canvas","embed","iframe","img","input","object","video"]),hidden:"GLOBAL",high:new Set(["meter"]),href:new Set(["a","area","base","link"]),hreflang:new Set(["a","area","link"]),"http-equiv":new Set(["meta"]),icon:new Set(["command"]),id:"GLOBAL",ismap:new Set(["img"]),itemprop:"GLOBAL",keytype:new Set(["keygen"]),kind:new Set(["track"]),label:new Set(["track"]),lang:"GLOBAL",language:new Set(["script"]),list:new Set(["input"]),loop:new Set(["audio","bgsound","marquee","video"]),low:new Set(["meter"]),manifest:new Set(["html"]),max:new Set(["input","meter","progress"]),maxlength:new Set(["input","textarea"]),maxlength:new Set(["input","textarea"]),media:new Set(["a","area","link","source","style"]),method:new Set(["form"]),min:new Set(["input","meter"]),multiple:new Set(["input","select"]),muted:new Set(["video"]),name:new Set(["button","form","fieldset","iframe","input","keygen","object","output","select","textarea","map","meta","param"]),novalidate:new Set(["form"]),open:new Set(["details"]),optimum:new Set(["meter"]),pattern:new Set(["input"]),ping:new Set(["a","area"]),placeholder:new Set(["input","textarea"]),poster:new Set(["video"]),preload:new Set(["audio","video"]),radiogroup:new Set(["command"]),readonly:new Set(["input","textarea"]),rel:new Set(["a","area","link"]),required:new Set(["input","select","textarea"]),reversed:new Set(["ol"]),rows:new Set(["textarea"]),rowspan:new Set(["td","th"]),sandbox:new Set(["iframe"]),scope:new Set(["th"]),scoped:new Set(["style"]),seamless:new Set(["iframe"]),selected:new Set(["option"]),shape:new Set(["a","area"]),size:new Set(["input","select"]),sizes:new Set(["img","link","source"]),span:new Set(["col","colgroup"]),spellcheck:"GLOBAL",src:new Set(["audio","embed","iframe","img","input","script","source","track","video"]),srcdoc:new Set(["iframe"]),srclang:new Set(["track"]),srcset:new Set(["img"]),start:new Set(["ol"]),step:new Set(["input"]),style:"GLOBAL",summary:new Set(["table"]),tabindex:"GLOBAL",target:new Set(["a","area","base","form"]),title:"GLOBAL",type:new Set(["button","input","command","embed","object","script","source","style","menu"]),usemap:new Set(["img","input","object"]),value:new Set(["button","option","input","li","meter","progress","param"]),width:new Set(["canvas","embed","iframe","img","input","object","video"]),wrap:new Set(["textarea"])};function go(i,e){e=e.toLowerCase();var t=po[i.toLowerCase()];return!!t&&(t==="GLOBAL"||t.has(e))}function mo(i){return ho[i]||i}Fs.exports={isStandardAttribute:go,propToAttr:mo}});var _s=se((Dr,Gs)=>{var wo=ti(),qs=Vs();function Be(i,e){this.type=i,this.target=null,Object.keys(e||{}).forEach(function(t){this[t]=e[t]},this)}Be.prototype.preventDefault=function(){};Be.prototype.stopPropagation=function(){};Be.prototype.stopImmediatePropagation=function(){};function Bs(i,e){this._eventListeners=this._eventListeners||{},this._eventListeners[i]=this._eventListeners[i]||[];var t=this._eventListeners[i];t.indexOf(e)===-1&&t.push(e)}function Us(i,e){var t=this._eventListeners&&this._eventListeners[i];if(t){var s=t.indexOf(e);s!==-1&&t.splice(s,1)}}function Hs(i){i.target=this;var e=this._eventListeners&&this._eventListeners[i.type];return e&&e.forEach(function(t){t(i)}),!0}function he(){}he.prototype.createTextNode=function(i){var e=new U;return e.textContent=i,e.nodeName="#text",e.nodeType=3,e};he.prototype.createElement=function(i){var e=new M;return e.nodeName=e.tagName=i,e};he.prototype.createComment=function(i){var e=new J;return e.data=i,e};he.prototype.addEventListener=Bs;he.prototype.removeEventListener=Us;he.prototype.dispatchEvent=Hs;function Ue(){}U.prototype=new Ue;M.prototype=new Ue;J.prototype=new Ue;function He(i){this.el=i,this.styles=[]}He.prototype.setProperty=function(i,e){this.el._setProperty(this.styles,{name:i,value:e})};He.prototype.getProperty=function(i){return this.el._getProperty(this.styles,i)};He.prototype.__defineGetter__("cssText",function(){var i="";return this.styles.forEach(function(e){i+=e.name+":"+e.value+";"}),i});He.prototype.__defineSetter__("cssText",function(i){this.styles.length=0,i.split(";").forEach(function(e){var t=e.indexOf(":");if(t){var s=e.slice(0,t).trim(),n=e.slice(t+1).trim();this.setProperty(s,n)}},this)});function bo(i,e){i&&(this.name=i,this.value=e||"")}function M(){var i=this;this.style=new He(this),this.classList=wo(this),this.childNodes=[],this.attributes=[],this.dataset={},this.className="",this._setProperty=function(e,t,s,n){var r=i._getProperty(e,s);if(r){r.value=String(n);return}e.push(typeof t=="function"?new t(s.toLowerCase(),String(n)):t)},this._getProperty=function(e,t){if(t){t=t.toLowerCase();for(var s=0;s<e.length;s++)if(t===e[s].name)return e[s]}}}M.prototype.nodeType=1;M.prototype.appendChild=function(i){return i.parentElement=this,this.childNodes.push(i),i};M.prototype.setAttribute=function(i,e){i==="style"?this.style.cssText=e:this._setProperty(this.attributes,bo,i,e)};M.prototype.getAttribute=function(i){if(i==="style")return this.style.cssText;var e=this._getProperty(this.attributes,i);return typeof e!="undefined"?e.value:null};M.prototype.removeAttribute=function(i){if(i==="class")delete this.className;else for(var e=0,t=this.attributes.length;e<t;e++)if(this.attributes[e].name===i){this.attributes.splice(e,1);break}};M.prototype.replaceChild=function(i,e){var t=this,s=!1;if(this.childNodes.forEach(function(n,r){n===e&&(t.childNodes[r]=i,i.parentElement=this,s=!0)}),s)return e};M.prototype.removeChild=function(i){var e=this,t=!0;if(this.childNodes.forEach(function(s,n){s===i&&(e.childNodes.splice(n,1),i.parentElement=null,t=!0)}),t)return i};M.prototype.insertBefore=function(i,e){var t=this.childNodes;if(e===null)t.push(i);else for(var s=0,n=t.length;s<n;s++){var r=t[s];if(r===e){s===0?t.unshift(i):t.splice(s,0,i);break}}return i.parentElement=this,i};M.prototype.addEventListener=Bs;M.prototype.removeEventListener=Us;M.prototype.dispatchEvent=Hs;M.prototype.insertAdjacentHTML=function(i,e){};M.prototype.__defineGetter__("innerHTML",function(){var i=this.childNodes.html||"";return this.childNodes.forEach(function(e){i+=e.outerHTML||e.textContent}),i});M.prototype.__defineSetter__("innerHTML",function(i){this.childNodes.length=0,this.childNodes.html=i});M.prototype.__defineGetter__("outerHTML",function(){var i=[],e=this,t={AREA:!0,BASE:!0,BR:!0,COL:!0,EMBED:!0,HR:!0,IMG:!0,INPUT:!0,KEYGEN:!0,LINK:!0,META:!0,PARAM:!0,SOURCE:!0,TRACK:!0,WBR:!0};function s(h){var b=[],x;return h.forEach(function(g){x=g.name!="style"?g.value:e.style.cssText,b.push(g.name+'="'+js(x)+'"')}),b.length?" "+b.join(" "):""}function n(h){var b=[],x;return Object.keys(h).forEach(function(g){b.push("data-"+g+'="'+js(h[g])+'"')}),b.length?" "+b.join(" "):""}function r(){var h=[];for(var b in e){var x=qs.propToAttr(b);e.hasOwnProperty(b)&&["string","boolean","number"].indexOf(typeof e[b])!==-1&&qs.isStandardAttribute(x,e.nodeName)&&c(b,x)&&h.push({name:x,value:e[b]})}return h?s(h):""}function c(h,b){return e.getAttribute(b)?!1:!(h==="className"&&!e[h])}var u=this.style.cssText?this.attributes.concat([{name:"style"}]):this.attributes;return i.push("<"+this.nodeName+r()+s(u)+n(this.dataset)+">"),t[this.nodeName.toUpperCase()]||(i.push(this.innerHTML),i.push("</"+this.nodeName+">")),i.join("")});M.prototype.__defineGetter__("textContent",function(){var i="";return this.childNodes.forEach(function(e){i+=e.textContent}),i});M.prototype.__defineSetter__("textContent",function(i){var e=new U;return e.textContent=i,this.childNodes=[e],i});function Ge(i){return String(i).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function js(i){return Ge(i).replace(/"/g,"&quot;")}M.prototype.nodeValue=null;function U(){}U.prototype.nodeType=3;U.prototype.nodeName="#text";U.prototype.__defineGetter__("textContent",function(){return Ge(this.value||"")});U.prototype.__defineSetter__("textContent",function(i){this.value=i});U.prototype.__defineGetter__("nodeValue",function(){return Ge(this.value||"")});U.prototype.__defineSetter__("nodeValue",function(i){this.value=i});U.prototype.__defineGetter__("length",function(){return(this.value||"").length});U.prototype.replaceData=function(i,e,t){this.value=this.value.slice(0,i)+t+this.value.slice(i+e)};function J(){}J.prototype.nodeType=8;J.prototype.nodeName="#comment";J.prototype.__defineGetter__("data",function(){return this.value});J.prototype.__defineSetter__("data",function(i){this.value=i});J.prototype.__defineGetter__("outerHTML",function(){return"<!--"+Ge(this.value||"")+"-->"});J.prototype.__defineGetter__("nodeValue",function(){return Ge(this.value||"")});J.prototype.__defineSetter__("nodeValue",function(i){this.value=i});function ft(i){i.__defineGetter__("parentNode",function(){return this.parentElement})}ft(M.prototype);ft(J.prototype);ft(U.prototype);ft(Ue.prototype);Gs.exports={Document:he,Node:Ue,Element:M,Comment:J,Text:U,document:new he,Event:Be,CustomEvent:Be}});var Ys=se((Lr,Js)=>{var vo=Is(),ko=ti(),Ks=typeof window=="undefined"?_s():window,_e=Ks.document,yo=Ks.Text;function Qs(){var i=[];function e(){var t=[].slice.call(arguments),s=null;function n(r){var c;function u(g){var D=vo(g,/([\.#]?[^\s#.]+)/);/^\.|#/.test(D[1])&&(s=_e.createElement("div")),zs(D,function(E){var ue=E.substring(1,E.length);E&&(s?E[0]==="."?ko(s).add(ue):E[0]==="#"&&s.setAttribute("id",ue):s=_e.createElement(E))})}if(r!=null){if(typeof r=="string")s?s.appendChild(c=_e.createTextNode(r)):u(r);else if(typeof r=="number"||typeof r=="boolean"||r instanceof Date||r instanceof RegExp)s.appendChild(c=_e.createTextNode(r.toString()));else if(Do(r))zs(r,n);else if(ii(r))s.appendChild(c=r);else if(r instanceof yo)s.appendChild(c=r);else if(typeof r=="object")for(var h in r)if(typeof r[h]=="function")/^on\w+/.test(h)?(function(g,D){s.addEventListener?(s.addEventListener(g.substring(2),D[g],!1),i.push(function(){s.removeEventListener(g.substring(2),D[g],!1)})):(s.attachEvent(g,D[g]),i.push(function(){s.detachEvent(g,D[g])}))})(h,r):(s[h]=r[h](),i.push(r[h](function(g){s[h]=g})));else if(h==="style")if(typeof r[h]=="string")s.style.cssText=r[h];else for(var b in r[h])(function(g,D){if(typeof D=="function")s.style.setProperty(g,D()),i.push(D(function(ue){s.style.setProperty(g,ue)}));else var E=r[h][g].match(/(.*)\W+!important\W*$/);E?s.style.setProperty(g,E[1],"important"):s.style.setProperty(g,r[h][g])})(b,r[h][b]);else if(h==="attrs")for(var x in r[h])s.setAttribute(x,r[h][x]);else h.substr(0,5)==="data-"?s.setAttribute(h,r[h]):s[h]=r[h];else if(typeof r=="function"){var x=r();s.appendChild(c=ii(x)?x:_e.createTextNode(x)),i.push(r(function(D){ii(D)&&c.parentElement?(c.parentElement.replaceChild(D,c),c=D):c.textContent=D}))}}return c}for(;t.length;)n(t.shift());return s}return e.cleanup=function(){for(var t=0;t<i.length;t++)i[t]();i.length=0},e}var xo=Js.exports=Qs();xo.context=Qs;function ii(i){return i&&i.nodeName&&i.nodeType}function zs(i,e){if(i.forEach)return i.forEach(e);for(var t=0;t<i.length;t++)e(i[t],t)}function Do(i){return Object.prototype.toString.call(i)=="[object Array]"}});var dt,V,pe=v(()=>{P();oe();O();H();dt=class{constructor(e,t){a(this,"options",{});a(this,"values",{type:null,typeVariant:null,hostname:location.hostname});a(this,"mw",{serverName:mw.config.get("wgServerName"),mobileServerName:mw.config.get("wgMobileServerName")});a(this,"isValid",!1);a(this,"isForeign",!1);a(this,"isHidden",!1);this.options=f({fixTenet:!0},t),W(e)||this.set(e)}set(e){this.values=f(f({},this.values),this.validateValues(e)),this.isValid=this.validate(),this.process()}setValue(e,t){this.values[e]=t}setValues(e){for(let[t,s]of Object.entries(e))this.setValue(t,s)}get(e){return this.values[e]}getValues(){return this.values}getMW(e){return this.mw[e]}validateValues(e){return!l(e.diff)&&F(e.diff)&&e.diff.indexOf("|")>-1&&(e.diff=e.diff.split("|").shift()),!l(e.oldid)&&F(e.oldid)&&e.oldid.indexOf("|")>-1&&(e.oldid=e.oldid.split("|").shift()),!l(e.curid)&&F(e.curid)&&e.curid.indexOf("|")>-1&&(e.curid=e.curid.split("|").shift()),[0,"0"].includes(e.oldid)&&delete e.oldid,[0,"0","current","latest"].includes(e.diff)&&(e.diff="cur"),R(e.direction)||(e.direction="prev"),l(e.hash)||(e.hash=mw.util.percentDecodeFragment(e.hash),e.hash&&(e.hash=e.hash.replace(/^#/,""))),l(e.section)||(e.section=e.section.replace(/^#/,"")),e}validate(){if(ut(this.values.title)==="Special:ComparePages"&&(!l(this.values.page1)||w(this.values.rev1))&&(!l(this.values.page2)||w(this.values.rev2)))return this.options.fixTenet=!1,this.values.type="diff",this.values.typeVariant="comparePages",!0;if(ut(this.values.title)==="Special:Undelete")return this.values.type="diff",this.values.typeVariant="undelete",!1;if(w(this.values.oldid)&&l(this.values.diff))return this.values.type="revision",!0;if(w(this.values.diff)||w(this.values.oldid)){if(this.values.type="diff",l(this.values.title)&&R(this.values.oldid)){let e=this.values.oldid;this.values.oldid=this.values.diff,this.values.diff=e}if(l(this.values.oldid)&&(this.values.oldid=this.values.diff,this.values.diff=this.values.direction),this.options.fixTenet&&w(this.values.oldid)&&w(this.values.diff)&&parseInt(this.values.oldid)>parseInt(this.values.diff)){let e=this.values.oldid;this.values.oldid=this.values.diff,this.values.diff=e}return!0}return!l(this.values.title)&&R(this.values.diff)?(this.values.type="diff",!0):w(this.values.curid)?(this.values.type="revision",this.values.typeVariant="page",!0):!1}process(){this.values.revid=si(this),l(this.values.hostname)||this.setHostname(),l(this.values.title)||this.setTitle(),(!l(this.values.page1)||!l(this.values.page2))&&this.setComparePages()}setHostname(){let{general:e}=k.siteInfoAliases[this.values.hostname]||{};W(e)?(this.mw.serverName=this.values.hostname,this.mw.mobileServerName=this.values.hostname):(this.values.hostname=ye()&&!l(e.mobileservername)?e.mobileservername:e.servername,this.mw.serverName=e.servername,this.mw.mobileServerName=e.mobileservername),this.mw.endPoint=`https://${this.values.hostname}${mw.util.wikiScript("index")}`,this.mw.endPointUrl=new URL(this.mw.endPoint),this.isForeign=re(this.values.hostname)}setTitle(){l(this.values.origTitle)&&(this.values.origTitle=this.values.title);try{this.mw.title=new mw.Title(this.values.title),this.values.title=this.mw.title.getPrefixedDb(),this.values.titleText=this.mw.title.getPrefixedText()}catch(e){}d.get("linksHash")&&!l(this.values.section)&&(this.values.titleSection=[this.values.title,this.values.section].join("#"),this.values.titleTextSection=[this.values.titleText,this.values.section].join("#")),this.values.href=mw.util.getUrl(this.values.titleSection||this.values.title),this.isForeign&&(this.values.href=z(this,this.values.href))}setComparePages(){try{this.mw.page1=new mw.Title(this.values.page1),this.values.page1=this.mw.page1.getPrefixedDb(),this.values.page1Text=this.mw.page1.getPrefixedText()}catch(e){}try{this.mw.page2=new mw.Title(this.values.page2),this.values.page2=this.mw.page2.getPrefixedDb(),this.values.page2Text=this.mw.page2.getPrefixedText()}catch(e){}}};a(dt,"utils",ht);V=dt});var Y,ni,k,H=v(()=>{T();P();Ie();O();pe();Y=class Y{static getApi(e){let t=e instanceof V?e.get("hostname"):e;if(!re(t))return this.api||(this.api=new mw.Api),this.api;if(!this.foreignApi[t]){let s=`https://${t}${mw.util.wikiScript("api")}`;this.foreignApi[t]=new mw.ForeignApi(s)}return this.foreignApi[t]}static get(e,t){return this.getApi(t).get(e)}static post(e,t){return this.getApi(t).post(e)}static postWithToken(e,t,s){return this.getApi(s).postWithToken(e,t)}static watch(e,t,s){return this.getApi(s).watch(e,t)}static unwatch(e,t){return this.getApi(t).unwatch(e)}static notifyError(e){C("error-api-generic",{tag:"api",message:(e==null?void 0:e.message)||e,silent:!0})}static getAuthToken(e){let t={action:"centralauthtoken",format:"json",formatversion:2,uselang:o.local.language};return this.get(t,e)}static loadMessage(e,t){return e=typeof e=="string"?[e]:e,e.filter(n=>!mw.message(n).exists()).length===0?$.Deferred().resolve().promise():this.getApi(t).loadMessagesIfMissing(e,{uselang:o.local.userLanguage})}static parseWikitext(e,t){return m(this,null,function*(){e=f({action:"parse",contentmodel:"wikitext",format:"json",formatversion:2,uselang:o.local.language},e);try{let{parse:s}=yield this.post(e,t);return s.text}catch(s){this.notifyError(s)}})}static getCompare(e,t,s){return m(this,null,function*(){e=f({action:"compare",prop:["title","ids","timestamp","comment"],format:"json",formatversion:2,uselang:o.local.userLanguage},e);let n=s||this;try{return(yield n.get(e,t)).compare}catch(r){this.notifyError(r)}})}static getPageInfo(e,t,s){return m(this,null,function*(){let n=o.local.userLanguage;e=f({action:"query",prop:["info","pageprops","entityterms"],inprop:["watched","notificationtimestamp"],wbetterms:["label"],wbetlanguage:n,intestactions:["edit"],format:"json",formatversion:2,uselang:n},e);let r=s||this;try{return(yield r.get(e,t)).query.pages[0]}catch(c){this.notifyError(c)}})}static markAsSeen(e,t){return m(this,null,function*(){e=f({action:"setnotificationtimestamp",redirects:1,format:"json",formatversion:2,uselang:o.local.userLanguage},e);try{return(yield this.postWithToken("csrf",e,t)).setnotificationtimestamp[0].notificationtimestamp}catch(s){this.notifyError(s)}})}static getSiteInfo(){return m(this,arguments,function*(e=["general","skins"],t,s){let n=t instanceof V?t.get("hostname"):t;if(l(n)&&(n=mw.config.get("wgServerName")),!ze()&&W(this.siteInfo)&&(this.siteInfo=mw.storage.getObject(`${o.config.prefix}-siteInfo`)||{},this.processSiteInfo()),this.checkSiteInfo(n,e))return this.siteInfoAliases[n]||this.siteInfo[n];let r={action:"query",meta:"siteinfo",siprop:e,format:"json",formatversion:2,uselang:o.local.userLanguage},c=s||this;try{let{query:u}=yield c.get(r,n);this.siteInfo[n]||(this.siteInfo[n]={});for(let[h,b]of Object.entries(u))this.siteInfo[n][h]=b;return mw.storage.setObject(`${o.config.prefix}-siteInfo`,this.siteInfo,d.get("storageExpiry")),this.processSiteInfoAliases(this.siteInfo[n]),this.siteInfo[n]}catch(u){this.notifyError(u)}})}static processSiteInfo(){if(!W(this.siteInfo))for(let e of Object.values(this.siteInfo))this.processSiteInfoAliases(e)}static processSiteInfoAliases(e){W(e==null?void 0:e.general)||(this.siteInfoAliases[e.general.servername]=e,l(e.general.mobileserver)||(e.general.mobileservername=ee("hostname",e.general.mobileserver),this.siteInfoAliases[e.general.mobileservername]=e))}static checkSiteInfo(e,t=[]){return this.siteInfoAliases[e]?l(t)||t.every(s=>this.siteInfoAliases[e][s]):this.siteInfo[e]?l(t)||t.every(s=>this.siteInfo[e][s]):!1}static siteInfoHasSkin(e,t){return m(this,null,function*(){let{skins:s}=(yield Y.getSiteInfo(["skins"],t))||{};return s==null?void 0:s.some(n=>n.code===e)})}static getSpecialPages(e){return m(this,null,function*(){if(W(this.specialPages)&&o.config.specialPages.forEach(s=>{this.specialPages[s]=s}),!ze()&&W(this.specialPagesLocal)&&(this.specialPagesLocal=mw.storage.getObject(`${o.config.prefix}-specialPagesLocal`)||{}),!W(this.specialPagesLocal))return this.specialPagesLocal;for(let[s,n]of Object.entries(this.specialPages))this.specialPagesLocal[s]=n;let t={action:"query",titles:o.config.specialPages,format:"json",formatversion:2,uselang:mw.config.get("wgContentLanguage")};try{let{query:s}=yield this.get(t,e);return s.normalized&&s.normalized.forEach(n=>{this.specialPagesLocal[n.from]=n.to}),mw.storage.setObject(`${o.config.prefix}-specialPagesLocal`,this.specialPagesLocal,d.get("storageExpiry")),this.specialPagesLocal}catch(s){this.notifyError(s)}})}static getInterwikiMap(e){return m(this,null,function*(){if(!ze()&&l(this.interwikiMap)&&(this.interwikiMap=mw.storage.getObject(`${o.config.prefix}-interwikiMap`)||[]),!l(this.interwikiMap))return this.interwikiMap;let t={action:"query",meta:"siteinfo",siprop:"interwikimap",format:"json",formatversion:2,uselang:o.local.userLanguage};try{let{query:s}=yield this.get(t,e);return this.interwikiMap=s.interwikimap,mw.storage.setObject(`${o.config.prefix}-interwikiMap`,this.interwikiMap,d.get("storageExpiry")),this.interwikiMap}catch(s){this.notifyError(s)}})}static getWBLabel(e,t,s){return m(this,null,function*(){if(!oi(e))return;let n=o.local.userLanguage,r={action:"wbgetentities",props:"labels",ids:e,languages:n,languagefallback:1,format:"json",formatversion:2,uselang:n},c=s||this;try{let{entities:u}=yield c.get(r,t),h=u[e];return h.type==="lexeme"?Object.values(h.lemmas).map(b=>b.value).join("/"):h.labels[n].value}catch(u){this.notifyError(u)}})}};a(Y,"utils",ri),a(Y,"api"),a(Y,"foreignApi",{}),a(Y,"siteInfo",{}),a(Y,"siteInfoAliases",{}),a(Y,"specialPages",{}),a(Y,"specialPagesLocal",{}),a(Y,"interwikiMap",[]);ni=Y,k=ni});var ri={};Q(ri,{getEntitySchemaLabel:()=>ci,getNamespaceConfig:()=>ai,getWikilambdaLabel:()=>fi,isEditableContentModel:()=>li,isProbablyWbTitle:()=>oi,isWbContentModel:()=>xe});function ai(i){let e=k.siteInfoAliases[i];if(!W(e))return{wgFormattedNamespaces:Object.values(e.namespaces).reduce((t,s)=>(t[s.id]=s.canonical||"",t),{}),wgNamespaceIds:f(f({},Object.values(e.namespaces).reduce((t,s)=>(t[pt(s.name.toLowerCase())]=s.id,s.canonical&&(t[pt(s.canonical.toLowerCase())]=s.id),t),{})),e.namespacealiases.reduce((t,s)=>(t[s.alias.toLowerCase()]=s.id,t),{})),wgCaseSensitiveNamespaces:Object.values(e.namespaces).filter(t=>t.case==="case-sensitive").map(t=>t.id),wgContentNamespaces:Object.values(e.namespaces).filter(t=>t.content).map(t=>t.id)}}function oi(i){return!l(i)&&/^[QPL][0-9]+$/.test(i)}function xe(i){return!l(i)&&i.includes("wikibase")}function li(i){return!o.config.nonEditableContentModels.includes(i)}function ci(i){return $(i).find(".entityschema-title-label").text()}function fi(i){return!W(i)&&(i[`wikilambda-label-${o.local.userLanguage}`]||i["wikilambda-label-en"])}var Ie=v(()=>{T();P();H()});var ht={};Q(ht,{addLinkTags:()=>gi,getDependencies:()=>di,getForeignDependencies:()=>ui,getHref:()=>q,getHrefAbsolute:()=>z,getRevID:()=>si,getWikilink:()=>wi,loadForeignDependencies:()=>hi,loadForeignStylesDependencies:()=>pi,removeLinkTags:()=>mi});function si(i){let e=i.getValues();if(w(e.revid))return e.revid;if(e.type==="revision"&&w(e.oldid)&&(!R(e.direction)||e.direction==="prev"))return e.oldid;if(e.type==="diff"){if(w(e.oldid)&&w(e.diff))return Math.max(e.oldid,e.diff);if(w(e.oldid)){if(!R(e.diff)||e.diff==="prev")return e.oldid}else if(w(e.diff)&&(!R(e.oldid)||e.oldid==="prev"))return e.diff}return!1}function di(i){let e=[],t=o.config.dependencies.page;t&&(e=e.concat(Re(i,t)));let s=o.config.dependencies[i.get("type")];s&&(e=e.concat(Re(i,s)));let n=o.config.dependencies.skins[mw.config.get("skin")];return n&&(e=e.concat(Re(i,n))),e}function Re(i,e){var n;let t=[];if(l(e))return t;Z(e["*"])&&(t=t.concat(e["*"]));let s=(n=i.getMW("title"))==null?void 0:n.getNamespaceId();return Z(e[s])&&(t=t.concat(e[s])),t}function ui(i){let e=[],t=[],s=[],n=o.config.foreignDependencies[i.get("type")];if(n){if(e=e.concat(Re(i,n)),t=t.concat(Re(i,n.styles)),xe(mw.config.get("wgPageContentModel"))){let r=n.wikibase;r&&(e=e.concat(Re(i,r)),t=t.concat(r.styles.all,ye()?r.styles.mobile:r.styles.desktop))}s=s.concat(Lo(i,n.links))}return{modules:e,styles:t,links:s}}function Lo(i,e){var n;let t=[];if(l(e))return t;Z(e["*"])&&(t=t.concat(e["*"].map(r=>Zs(i,r))));let s=(n=i.getMW("title"))==null?void 0:n.getNamespaceId();return Z(e[s])&&(t=t.concat(e[s].map(r=>Zs(i,r)))),t}function hi(i,e){let t=gt(e),s=i.get("hostname"),n=mw.util.wikiScript("load"),r=$.param({modules:t.join("|"),skin:mw.config.get("skin")});mw.loader.load(`https://${s}${n}?${r}`)}function pi(i,e){let t=gt(e),s=i.get("hostname"),n=mw.util.wikiScript("load"),r=$.param({modules:t.join("|"),only:"styles",skin:mw.config.get("skin")});mw.loader.load(`https://${s}${n}?${r}`,"text/css")}function gi(i){if(!l(i))return i.map(e=>{var t,s;return(s=(t=mw.loader).addLinkTag)==null?void 0:s.call(t,e)})}function mi(i){l(i)||i.forEach(e=>e==null?void 0:e.remove())}function wi(i){return m(this,null,function*(){let e={relative:!1,hash:d.get("linksHash"),minify:d.get("linksFormat")==="minify",wikilink:!0,wikilinkPreset:d.get("wikilinksFormat")};if(i.isForeign){let t=yield k.getInterwikiMap();t&&(e.interwiki=t.filter(s=>s.url.includes(i.getMW("serverName"))).reduce((s,n)=>!s||s.prefix.length>n.prefix.length?n:s))}return q(i,{},e)})}function q(i,e,t){i instanceof V||(i=new V(i)),e=f({},e),t=f({type:null},t);let s=f({},i.getValues());return t.type||(s.type==="revision"&&s.typeVariant==="page"?t.type="page":t.type=s.type),t.type==="diff"&&(l(s.diff)&&R(s.direction)&&(s.diff=s.direction),w(s.oldid)&&w(s.diff)?(e.oldid=s.oldid,e.diff=s.diff):w(s.revid)?e.diff=s.revid:w(s.oldid)?R(s.diff)&&s.diff!=="prev"?(e.oldid=s.oldid,e.diff=s.diff):e.diff=s.oldid:w(s.diff)&&(R(s.oldid)&&s.oldid!=="prev"?(e.oldid=s.diff,e.diff=s.oldid):e.diff=s.diff)),t.type==="revision"&&(l(s.direction)&&R(s.diff)&&(s.direction=s.diff),w(s.revid)?e.oldid=s.revid:w(s.oldid)&&(e.oldid=s.oldid,R(s.direction)&&s.direction==="next"&&(e.direction=s.direction))),t.type==="page"&&(e.curid=s.curid),So(i,e,t)}function z(i,e){let t=(i==null?void 0:i.mw.endPointUrl)||o.local.mwEndPointUrl;try{return new URL(e,t.origin).toString()}catch(s){return e}}function So(i,e,t){e=f({},e),t=f({type:"diff",relative:!0,hash:!1,minify:!1,interwiki:null,wikilink:!1,wikilinkPreset:null},t),re(i.get("hostname"))&&(t.relative=!1);let s=i.getMW("endPointUrl")||o.local.mwEndPointUrl,n;if(l(i.get("title"))?(n=new URL(s),n.search=new URLSearchParams(e).toString()):n=new URL(mw.util.getUrl(i.get("title"),e),s.origin),t.hash&&!l(i.get("section"))){let r=mw.util.escapeIdForLink(i.get("section"));r&&(n.hash=`#${r}`)}return t.minify&&(n.pathname="",n.hash="",n.searchParams.delete("title")),t.href=decodeURIComponent(t.relative?n.pathname+n.search+n.hash:n.toString()),t.hash=decodeURIComponent(n.hash),t.wikilink?Po(i,e,t):t.href}function Po(i,e,t){var u;e=f({},e),t=f({href:null,hash:null,type:"diff",minify:!1,relative:!0,interwiki:null,wikilink:!0,wikilinkPreset:"special"},t);let s=null;!l(e.oldid)&&!l(e.diff)?s=`${e.oldid}/${e.diff}`:l(e.oldid)?l(e.diff)?l(e.curid)||(s=e.curid):s=e.diff:s=e.oldid,l(t.hash)||(s=`${s}${t.hash}`);let r=(o.config.wikilinkPresets[t.wikilinkPreset]||o.config.wikilinkPresets.special)[t.type],c=(u=t.interwiki)==null?void 0:u.prefix;return r.replace("$1",s).replace("$pref",c?`${c}:`:"").replace("$href",t.href).replace("$msg",p(`copy-wikilink-${t.type}`))}function Zs(i,e){let t=mw.util.getUrl(e,{action:"raw",ctype:"text/css"});return i.isForeign?z(i,t):t}var oe=v(()=>{T();P();Ie();H();pe();O()});function K(i){let e=Object.getPrototypeOf(i);return OO.initClass(e),i.static=Object.create(e.static),Object.keys(i).filter(t=>t!=="static").forEach(t=>{i.static[t]=i[t]}),i.parent=i.super=e,i}function bi(i){let e={prototype:{}};OO.mixinClass(e,OO.EventEmitter),Object.assign(i,e.prototype),OO.EventEmitter.call(i)}function mt(){L(OO.ui.RadioSelectWidget.prototype.findFirstSelectedItem)||(OO.ui.RadioSelectWidget.prototype.findFirstSelectedItem=function(){let i=this.findSelectedItems();return Array.isArray(i)?i[0]||null:i}),L(OO.ui.ButtonSelectWidget.prototype.findFirstSelectedItem)||(OO.ui.ButtonSelectWidget.prototype.findFirstSelectedItem=function(){let i=this.findSelectedItems();return Array.isArray(i)?i[0]||null:i}),L(OO.ui.getTeleportTarget)||(OO.ui.getTeleportTarget=function(){return document.body})}function Xs(){$(["#mw-notification-area",".mw-notification-area-overlay",".ext-checkuser-userinfocard-popover"]).each((i,e)=>{$(e).removeAttr("aria-hidden").removeAttr("inert")})}function wt(){Eo();let i=new OO.ui.WindowManager;return $(OO.ui.getTeleportTarget()).append(i.$element),i}function Eo(i){i=i||d.get("viewWidth")||"standard",i!=="full"&&(OO.ui.WindowManager.static.sizes.instantDiffs=A.constructor.sizes[i]||A.constructor.sizes.standard),A.isOpen&&A.dialog.setSize(vi(i))}function vi(i){return i=i||d.get("viewWidth")||"standard",i==="full"?"full":"instantDiffs"}function bt(i,e){let t=mw.loader.moduleRegistry[i],s=e.match(/^((?:\.\.?\/)+)(.*)$/);return s&&(e=`resources/src/${i}/${s[2]}`),t==null?void 0:t.packageExports[e]}function en(i){let e=mw.loader.moduleRegistry[i];return e==null?void 0:e.script($,jQuery,null,null)}var G=v(()=>{P();ae();O()});var xi={};Q(xi,{getMWLine:()=>ki,getMWLineTitle:()=>yi,getSplitSpecialUrl:()=>vt,isMWLink:()=>le});function vt(i){let e=i.split("/"),t={};return o.local.specialPagesAliasesPrefixed["Special:PermanentLink"].includes(e[0])?(t.oldid=e[1],t):o.local.specialPagesAliasesPrefixed["Special:Redirect"].includes(e[0])?e[1]==="revision"?(t.oldid=e[2],t):(e[1]==="page"&&(t.curid=e[2]),t):(e.length>1&&(t.diff=e.pop()),e.length>1&&(t.oldid=e.pop()),t)}function le(i,e){let t=!1;return e=e||o.config.mwLink,e.id&&(t=e.id.some(s=>i.id===s),t)||e.hasClass&&(t=e.hasClass.some(s=>i.classList.contains(s)),t)||e.hasChild&&(t=e.hasChild.some(s=>i.querySelector(s)),t)||e.closestTo&&(t=e.closestTo.some(s=>i.closest(s))),t}function ki(i){return i.closest(o.config.mwLine.selector.join(","))}function yi(i){let e=i.dataset.title;if(!l(e))return decodeURIComponent(e);let t=o.config.mwLineTitle.selector.join(","),s=i.querySelector(t);if(s)return l(s.title)?s.innerText:s.title}var tn=v(()=>{T();P()});var Di,ce,kt=v(()=>{P();Di=class{constructor(e){a(this,"options",{});a(this,"node");var t;this.options=f({node:null,tag:"button",classes:[],label:null,title:null,href:null,target:"_self",handler:null,container:null,insertMethod:"appendTo",ariaHaspopup:!1,altTitle:null,useAltKey:!1},e),l(this.options.href)||(this.options.tag="a"),OO.EventEmitter.call(this),((t=this.options.node)==null?void 0:t.nodeType)===1?(this.node=this.options.node,this.process()):this.render()}render(){this.node=document.createElement(this.options.tag),this.node.innerText=this.options.label,this.node.classList.add(...this.options.classes),l(this.options.title)||(this.node.title=this.options.title),l(this.options.href)?(this.node.setAttribute("tabindex","0"),this.node.setAttribute("role","button")):(this.node.href=this.options.href,this.node.target=this.options.target),this.process(),this.embed(this.options.container,this.options.insertMethod)}process(){L(this.options.handler)&&(this.options.ariaHaspopup&&this.node.setAttribute("aria-haspopup","dialog"),l(this.options.altTitle)||(this.node.dataset.altTitle=this.options.altTitle),Ke(this.node,this.options.handler.bind(this),this.options.useAltKey))}embed(e,t){N(this.node,e,t)}remove(){this.node.remove()}pending(e){this.node.classList.toggle("instantDiffs-link--pending",e)}getContainer(){return this.node}},ce=Di});var sn=v(()=>{});var nn,$o,De,Li,I,Ne=v(()=>{T();P();tn();H();pe();kt();ae();O();sn();({h:nn,ht:$o}=y),De=class De{constructor(e,t){a(this,"node");a(this,"options",{});a(this,"article");a(this,"nodes",{});a(this,"mw",{hasLink:!1,hasLine:!1});a(this,"manual",{behavior:"basic",options:{}});a(this,"actions",{});a(this,"extensions",{});a(this,"isValid",!1);a(this,"isForeign",!1);a(this,"isLoading",!1);a(this,"isLoaded",!1);a(this,"isProcessed",!1);a(this,"isObserved",!1);a(this,"hasRequest",!1);a(this,"onRequestRevisionError",(e,t)=>{this.isLoading=!1,this.error={type:"revision",tag:"link",code:l(this.article.get("curid"))?"generic":"curid",article:this.article,silent:!0},t!=null&&t.error?(this.error.code=t.error.code,this.error.message=t.error.info):(this.error.message=e,C(`error-revision-${this.error.code}`,this.error)),this.renderError()});a(this,"onRequestRevisionDone",e=>{var c,u;this.isLoading=!1;let t=e==null?void 0:e.query;if(!t||!t.badrevids&&!t.badpageids&&!t.pages)return this.onRequestRevisionError(void 0,e);let s=(c=t.pages)==null?void 0:c[0],n=(u=s==null?void 0:s.revisions)==null?void 0:u[0],r={type:"revision"};if(t.badrevids?r.code="badrevids":t.badpageids?r.code="badpageids":!s||s.missing||!n?r.code="missing":s.invalid&&(r.code="invalid",r.info=s.invalidreason),r.code)return this.error=r,this.renderError();this.revision=n,this.article.set({title:s.title,section:Pi(this.revision)}),this.article.isHidden=Si(this.revision),this.renderSuccess()});a(this,"onRequestDiffError",(e,t)=>{this.isLoading=!1,this.error={type:"diff",tag:"link",article:this.article,silent:!0},t!=null&&t.error?(this.error.code=t.error.code,this.error.message=t.error.info):(this.error.message=e,C("error-diff-generic",this.error)),this.renderError()});a(this,"onRequestDiffDone",e=>{if(this.isLoading=!1,this.compare=e==null?void 0:e.compare,!this.compare)return this.onRequestDiffError(null,e);this.article.set({title:ge(this.compare),section:We(this.compare)}),this.article.isHidden=yt(this.compare),this.renderSuccess()});a(this,"onRequestCompareError",(e,t)=>{this.isLoading=!1,this.error={type:"diff",tag:"link",article:this.article,silent:!0},t!=null&&t.error?(this.error.code=t.error.code,this.error.message=t.error.info):(this.error.message=e,C("error-diff-generic",this.error)),this.renderError()});a(this,"onRequestCompareDone",e=>{if(this.isLoading=!1,this.compare=e==null?void 0:e.compare,!this.compare)return this.onRequestCompareError(null,e);this.article.set({oldid:this.compare.fromrevid,diff:this.compare.torevid,page1:this.compare.fromtitle,page2:this.compare.totitle,title:ge(this.compare),section:We(this.compare)}),this.article.isHidden=yt(this.compare),this.renderSuccess()});this.node=e,this.options=f({behavior:"basic",insertMethod:"insertAfter",showLink:d.get("showLink"),showPageLink:d.get("showPageLink"),showAltTitle:!1,initiatorLink:null,initiatorPage:null,initiatorView:null,onRequest:()=>{},onLoad:()=>{},onOpen:()=>{},onClose:()=>{}},t),A.isContains(this.node)&&(this.options.initiatorView=A,this.options.initiatorPage=A.getPage()),this.process(),De.addLink(this.node,this),this.isValid&&this.render()}static findLinks(e){return typeof e=="undefined"&&(e=Fe()),e.find(o.local.linkSelector)}static addLink(e,t){this.stack.set(e,t.isValid?t:!1)}static getLink(e){return this.stack.get(e)}static hasLink(e){return this.stack.has(e)}static getLinks(){return this.stack.values()}process(){if(this.href=this.node.href,l(this.href))return;let e={};try{this.url=new URL(this.href),e.title=this.url.searchParams.get("title"),e.pathname=decodeURIComponent(this.url.pathname),e.pathnameNormalized=e.pathname.replace(new RegExp(o.local.mwArticlePath),"")}catch(s){return}if(o.config.exclude.linkActions.includes(this.url.searchParams.get("action"))||le(this.node,o.config.mwLinkExclude))return;let t={hostname:this.url.hostname,hash:this.url.hash};o.local.specialPagesLinksSearchRegExp.test(e.title)?t=f(f({},t),vt(e.title)):o.local.specialPagesLinksPathRegExp.test(e.pathname)?t=f(f({},t),vt(e.pathnameNormalized)):(["title","curid","oldid","diff","direction","page1","rev1","page2","rev2"].forEach(s=>{t[s]=this.url.searchParams.get(s)}),l(t.title)&&o.local.articlePathRegExp.test(e.pathname)&&(t.title=e.pathnameNormalized)),this.article=new V(t),this.isValid=this.article.isValid,this.isForeign=this.article.isForeign}render(){switch(this.processMWOptions(),this.processManualOptions(),this.postValidateOptions(),l(this.article.get("title"))&&this.mw.hasLine&&this.article.set({title:this.mw.title}),this.options.behavior){case"event":this.renderEvent();break;case"basic":this.renderBasic();break;case"request":this.renderRequest();break}}processMWOptions(){this.mw.isContent=le(this.node,o.config.mwLinkContent),this.mw.isContent&&(this.options.behavior="request"),this.mw.hasLink=le(this.node,o.config.mwLink),this.mw.hasLink&&(this.options.behavior="basic",this.mw.isDiffOnly=le(this.node,o.config.mwLinkDiffOnly),this.mw.isPrepend=le(this.node,o.config.mwLinkPrepend),this.mw.isPrepend&&(this.options.insertMethod="insertBefore"),this.mw.isAltTitle=le(this.node,o.config.mwLinkAltTitle),this.mw.isAltTitle&&(this.options.showAltTitle=!0),this.mw.line=ki(this.node),this.mw.line&&(this.mw.hasLine=!0,this.mw.title=yi(this.mw.line),this.mw.line.classList.add("instantDiffs-line")),this.mw.isContentInside=le(this.node,o.config.mwLinkContentInside),this.mw.isContentInside&&(this.options.behavior="request"))}processManualOptions(){if(this.manual.options=this.node.dataset.instantdiffsOptions,!l(this.manual.options))try{this.manual.options=JSON.parse(this.manual.options),this.options=f(f({},this.options),this.manual.options)}catch(e){let t={type:"link",tag:"link",message:(e==null?void 0:e.message)||e,silent:!0};C("error-link-options",t)}this.manual.behavior=this.node.dataset.instantdiffsLink,l(this.manual.behavior)||(this.options.behavior=this.manual.behavior)}postValidateOptions(){var t;let e={link:"event",default:"request"};e[this.options.behavior]&&(this.options.behavior=e[this.options.behavior]),["request","basic","event","none"].includes(this.options.behavior)||(this.options.behavior="basic"),(t=this.options).showPageLink&&(t.showPageLink=this.options.behavior==="request")}observe(){this.isObserved||(this.isObserved=!0,o.local.interactionObserver.observe(this.node))}unobserve(){this.isObserved&&(this.isObserved=!1,o.local.interactionObserver.unobserve(this.node))}onIntersect(){this.isLoading||this.isLoaded||!this.isObserved||(this.unobserve(),this.request())}renderRequest(){this.hasRequest=this.isValid,this.hasRequest?(this.toggleSpinner(!0),this.observe()):(this.toggleSpinner(!1),this.isLoaded=!0,this.isProcessed=!1,this.unobserve())}request(){let e=this.article.get("type"),t=this.article.get("typeVariant");if(e==="revision")return this.requestRevision();if(e==="diff")return t==="comparePages"?this.requestCompare():this.requestDiff()}requestRevision(){if(this.isLoading)return;this.isLoading=!0,this.error=null;let e={action:"query",prop:"revisions",rvprop:["ids","timestamp","comment","content","user"],rvslots:"main",rvsection:0,format:"json",formatversion:2,uselang:o.local.userLanguage};return l(this.article.get("oldid"))?l(this.article.get("curid"))||(e.pageids=this.article.get("curid")):e.revids=this.article.get("oldid"),k.get(e,this.article).then(this.onRequestRevisionDone).fail(this.onRequestRevisionError)}requestDiff(){if(this.isLoading)return;this.isLoading=!0,this.error=null;let e={action:"compare",prop:["title","ids","timestamp","comment","user"],fromrev:w(this.article.get("oldid"))?this.article.get("oldid"):void 0,fromtitle:l(this.article.get("title"))?void 0:this.article.get("title"),torev:w(this.article.get("diff"))?this.article.get("diff"):void 0,torelative:R(this.article.get("diff"))?this.article.get("diff"):void 0,format:"json",formatversion:2,uselang:o.local.userLanguage};return k.get(e,this.article).then(this.onRequestDiffDone).fail(this.onRequestDiffError)}requestCompare(){if(this.isLoading)return;this.isLoading=!0,this.error=null;let e=this.article.getValues(),t={action:"compare",prop:["title","ids","timestamp","comment","user"],fromrev:w(e.rev1)?e.rev1:void 0,fromtitle:l(e.page1)?void 0:e.page1,torev:w(e.rev2)?e.rev2:void 0,totitle:l(e.page2)?void 0:e.page2,format:"json",formatversion:2,uselang:o.local.userLanguage};return k.get(t,this.article).then(this.onRequestCompareDone).fail(this.onRequestCompareError)}renderEvent(){this.isValid&&(this.actions.action=new ce({node:this.node,handler:this.openDialog.bind(this),ariaHaspopup:!0}),this.renderSuccess())}renderBasic(){!this.isValid||this.mw.isDiffOnly&&this.article.get("type")!=="diff"||this.renderSuccess()}renderError(){if(this.isLoaded=!0,this.isProcessed=!1,this.toggleSpinner(!1),this.options.behavior!=="event"){this.renderWrapper();let e;this.error.type&&(e=`error-${this.error.type}-${this.error.code||"generic"}`,Qe(e)||(e=`error-${this.error.type}-generic`)),this.nodes.error=nn("span",{class:["item","error","error-info"],title:fe(e,this.error,this.article)},$o(Le("error"))),this.nodes.inner.append(this.nodes.error),this.embed(this.node,this.options.insertMethod)}mw.hook(`${o.config.prefix}.link.renderError`).fire(this)}renderSuccess(){this.isLoaded=!0,this.isProcessed=!0,this.toggleSpinner(!1),this.options.behavior!=="event"&&(this.renderWrapper(),this.renderLinkAction(),this.options.showPageLink&&this.renderPageAction(),this.embed(this.node,this.options.insertMethod)),mw.hook(`${o.config.prefix}.link.renderSuccess`).fire(this)}renderWrapper(){this.nodes.container=this.nodes.inner=nn("span",{class:["instantDiffs-panel","nowrap","noprint"]})}renderAction(e){return e=f({tag:"a",label:null,title:null,href:null,target:Je(this.options.initiatorView),handler:null,classes:[],modifiers:[],container:this.nodes.inner},e),e.classes=["item","text","instantDiffs-action",...e.classes],e.modifiers.forEach(t=>e.classes.push(`instantDiffs-action--${t}`)),new ce(e)}getLinkTitle(e){return this.options.showAltTitle&&!l(this.node.title)?this.node.title:(this.article.isHidden&&(e=`${e}-hidden`),p(e))}renderLinkAction(){let e=this.article.get("typeVariant")==="comparePages"?"compare-pages":this.article.get("type"),t=this.getLinkTitle(`${e}-title`);if(!this.options.showLink)return this.mutateLinkAction(t);let s=[];this.article.isHidden&&s.push("error","error-admin"),this.actions.action=this.renderAction({label:Le(this.article.get("type")),title:t,classes:s,modifiers:[this.article.get("type")],handler:this.openDialog.bind(this),ariaHaspopup:!0})}mutateLinkAction(e){let t=["instantDiffs-link",`instantDiffs-link--${this.article.get("type")}`,`is-${this.options.insertMethod}`];this.article.isHidden&&t.push("instantDiffs-link--error"),this.node.classList.remove("external"),this.node.classList.add(...t),this.node.dataset.instantdiffsLink=this.options.behavior,this.actions.action=new ce({node:this.node,handler:this.openDialog.bind(this),ariaHaspopup:!0,altTitle:e,useAltKey:!0})}renderPageAction(){this.actions.page=this.renderAction({label:Le("page"),title:this.article.get("titleTextSection")||this.article.get("titleText"),href:this.article.get("href"),modifiers:["page"]})}openDialog(){let e={initiatorPage:this.options.initiatorPage,onOpen:()=>this.onDialogOpen(),onClose:()=>this.onDialogClose()};if(A.setup(this,e))return this.onDialogRequest(),$.when(A.load()).always(()=>this.onDialogLoad())}onDialogRequest(){this.toggleLoader(!0),L(this.options.onRequest)&&this.options.onRequest(this)}onDialogLoad(){this.toggleLoader(!1),L(this.options.onLoad)&&this.options.onLoad(this)}onDialogOpen(){this.mw.hasLine&&d.get("highlightLine")&&this.mw.line.classList.add("instantDiffs-line--highlight"),L(this.options.onOpen)&&this.options.onOpen(this),this.options.initiatorLink instanceof De&&this.options.initiatorLink.onDialogOpen()}onDialogClose(){this.mw.hasLine&&(d.get("highlightLine")&&this.mw.line.classList.remove("instantDiffs-line--highlight"),d.get("markWatchedLine")&&o.config.changeLists.includes(mw.config.get("wgCanonicalSpecialPageName"))&&(this.mw.line.classList.remove(...o.config.mwLine.unseen),this.mw.line.classList.add(...o.config.mwLine.seen)),d.get("markWatchedLine")&&o.local.mwCanonicalSpecialPageName==="GlobalWatchlist"&&this.mw.line.classList.add("instantDiffs-line--seen")),L(this.options.onClose)&&this.options.onClose(this),this.options.initiatorLink instanceof De&&this.options.initiatorLink.onDialogClose()}toggleLoader(e){this.actions.action?this.actions.action.pending(e):this.node.classList.toggle("instantDiffs-link--pending",e)}toggleSpinner(e){let t=xt(["loader",this.article.get("type")]);e?this.node.classList.add(...t):this.node.classList.remove(...t)}embed(e,t){N(this.nodes.container,e,t)}getContainer(){return this.nodes.container}getNode(){return this.node}getInitiatorLink(){return this.options.initiatorLink||this}getArticle(){return this.article}getMW(){return this.mw}};a(De,"utils",xi),a(De,"stack",new Map);Li=De,I=Li});var Dt,Ei,Se,$i=v(()=>{P();Ne();Dt=class Dt{constructor(e){a(this,"options",{});a(this,"link");a(this,"links",[]);this.options=f({filterType:null,filterMWLine:!1},e),this.links=Array.from(I.findLinks())}static newInstance(e){this.instance=new Dt(e)}setLink(e){this.link=e}hasLink(e){return e instanceof I&&this.links.includes(e.getNode())}isLinkValid(e){var c;if(!(e instanceof I)||!(e.isValid&&(e.isProcessed||e.hasRequest&&!e.isLoaded)))return!1;let n=l(this.options.filterType)?!0:e.getArticle().get("type")===this.options.filterType,r=this.options.filterMWLine===!0?(c=e.getMW())==null?void 0:c.hasLine:!0;return n&&r}getLength(){return this.links.length}getIndex(){return this.link instanceof I?this.links.indexOf(this.link.getNode()):-1}getPreviousLink(e){if(typeof e=="undefined"&&(e=this.getIndex()),e<=0)return;let t=e-1,s=I.getLink(this.links[t]);return this.isLinkValid(s)?s:this.getPreviousLink(t)}getNextLink(e){if(typeof e=="undefined"&&(e=this.getIndex()),e<0||e+1>=this.getLength())return;let t=e+1,s=I.getLink(this.links[t]);return this.isLinkValid(s)?s:this.getNextLink(t)}};a(Dt,"instance");Ei=Dt,Se=Ei});function on(i){return i==="<unregistered>"?!1:!mw.util.isIPAddress(i)}function rn(i){return"isTemporaryUser"in mw.util?mw.util.isTemporaryUser(i):!1}function Ye(i){if(F(i)&&(i=new Date(i)),!(i instanceof Date))return;let e=Ze("mediawiki.DateFormatter");return e?e.forUser().formatTimeAndDate(i):i.toLocaleString()}var Ai=v(()=>{P()});var et={};Q(et,{isVisualDiffsAvailable:()=>Pt,processRevisionDiffTable:()=>Xe,renderDiffTable:()=>Ci,renderDiffTableSide:()=>St,renderMobileDiffFooter:()=>Oi,renderUserInfoCardButton:()=>ln,renderUserLink:()=>Mi,restoreFileMediaInfo:()=>Fi,restoreInlineFormatToggle:()=>Ii,restoreRollbackLink:()=>Wi,restoreVisualDiffs:()=>Ri,restoreWikiLambda:()=>Ni});function Ci(i){let e={};return e.container=S("table",{class:["diff","diff-type-table",`diff-contentalign-${mw.config.get("wgContentLanguageDir")==="rtl"?"right":"left"}`,`diff-editfont-${mw.user.options.get("editfont")}`]},S("colgroup",S("col",{class:"diff-marker"}),S("col",{class:"diff-content"}),S("col",{class:"diff-marker"}),S("col",{class:"diff-content"})),e.head=S("tbody",S("tr",{class:"diff-title",lang:o.local.userLanguage},e.deleted=S("td",{class:["diff-otitle","diff-side-deleted"],colSpan:2}),e.added=S("td",{class:["diff-ntitle","diff-side-added"],colSpan:2}))),e.body=S("tbody")),l(i)?i===""&&(e.notice=S("tr",S("td",{class:"diff-notice",colSpan:4},S("div",{class:"mw-diff-empty"},mw.msg("diff-empty")))),e.body.append(e.notice)):qi(e.body,i),e}function St(i){i=f({prefix:"n",title:null,revid:null,curRevid:null,hostname:null,timestamp:null,texthidden:!1,user:null,userhidden:!1,comment:null,commenthidden:!1},i);let e=`mw-diff-${i.prefix}title`,t=i.revid===i.curRevid?"currentrev-asof":"revisionasof",s=new V({type:"revision",title:i.title,oldid:i.revid,hostname:i.hostname});return Ti(S("div",{id:`${e}1`},S("strong",i.texthidden?S("span",{class:"history-deleted"},mw.msg(t,Ye(i.timestamp))):S("a",{href:q(s)},mw.msg(t,Ye(i.timestamp))))),S("div",{id:`${e}2`},i.userhidden?S("span",{class:["mw-userlink","history-deleted"]},mw.msg("rev-deleted-user")):Mi(s,i.user)),S("div",{id:`${e}3`},i.commenthidden?S("span",{class:["comment","history-deleted"]},mw.msg("rev-deleted-comment")):l(i.comment)?S("span",{class:["comment","mw-comment-none"]},mw.msg("changeslist-nocomment")):S("span",{class:["comment","comment--without-parentheses"],innerHTML:i.comment})))}function Xe(i){d.get("showRevisionInfo")?(i.find("td:is(.diff-otitle, .diff-side-deleted)").addClass("instantDiffs-hidden"),i.find("td:is(.diff-ntitle, .diff-side-added)").attr("colspan","4"),i.find("tr:not([class])").addClass("instantDiffs-hidden")):i.addClass("instantDiffs-hidden")}function Mi(i,e){let t=new mw.Title(e,2).getPrefixedText(),s=new mw.Title(e,3).getPrefixedText(),n=new mw.Title(`Contributions/${e}`,-1).getPrefixedText(),r=Ti(S("a",{class:["mw-redirect","mw-usertoollinks-talk"],title:s,href:z(i,mw.util.getUrl(s))},mw.msg("talkpagelinktext")),an(mw.msg("pipe-separator")),S("a",{class:["mw-redirect","mw-usertoollinks-contribs"],title:n,href:z(i,mw.util.getUrl(n))},mw.msg("contribslink")));return Ti(ln(e),S("a",{class:"mw-userlink",title:t,href:z(i,mw.util.getUrl(t))},S("bdi",e)),an(mw.msg("word-separator")),S("span",{class:"mw-usertoollinks"},Ao(mw.message("parentheses",r).parseDom())))}function ln(i){if(!mw.user.options.get("checkuser-userinfocard-enable")||!on(i))return;let e=["cdx-button__icon","ext-checkuser-userinfocard-button__icon",rn(i)?"ext-checkuser-userinfocard-button__icon--userTemporary":"ext-checkuser-userinfocard-button__icon--userAvatar"],t=S("a",{class:"ext-checkuser-userinfocard-button cdx-button cdx-button--action-default cdx-button--weight-quiet cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--icon-only cd-comment-author-userInfoCard-button",role:"button",tabindex:0,href:"javascript:void(0)",ariaLabel:mw.msg("checkuser-userinfocard-toggle-button-aria-label"),"data-username":i},S("span",{class:e}));return t.setAttribute("aria-haspopover","dialog"),t}function Oi(i){i=f({title:null,revid:null,hostname:null,user:null,userhidden:!1},i);let e=new V({type:"revision",title:i.title,oldid:i.revid,hostname:i.hostname});return S("div",{class:["mw-diff-mobile-footer"]},i.userhidden?S("span",{class:["mw-userlink","history-deleted"]},mw.msg("rev-deleted-user")):Mi(e,i.user))}function Ii(i){if(!i||i.length===0||mw.loader.getState("mediawiki.diff")!=="ready")return!1;let e=i.find("#mw-diffPage-inline-toggle-switch-layout"),t=bt("mediawiki.diff","./inlineFormatToggle.js");try{return t(e),!0}catch(s){}return!1}function Ri(i){if(!i||i.length===0||!w(mw.config.get("wgDiffOldId"))||!w(mw.config.get("wgDiffNewId"))||!Pt(mw.config.get("wgPageContentModel"))||mw.loader.getState("ext.visualEditor.diffPage.init")!=="ready")return!1;let e=i.find(".ve-init-mw-diffPage-diffMode");if(e.length>0)return!0;e=$("<div>").addClass("ve-init-mw-diffPage-diffMode");let t=i.find(".mw-diffPage-inlineToggle-container");return t.length>0?t.before(e):i.append(e),!0}function Pt(i){let e=mw.config.get("wgVisualEditorConfig");return e&&Object.prototype.hasOwnProperty.call(e.contentModels,i)}function Wi(i){if(!i||i.length===0)return!1;let e=['.mw-rollback-link a[data-mw="interface"]',".mw-rollback-link a[data-mw-interface]"];return i.confirmable({i18n:{confirm:mw.msg("rollback-confirmation-confirm"),yes:mw.msg("rollback-confirmation-yes"),no:mw.msg("rollback-confirmation-no")},delegate:e.join(","),handler:t=>{t.preventDefault(),To(t.target)}}),!0}function To(i){let e=$.createSpinner({size:"small",type:"inline"});$(i).css("display","none").after(e);let t={action:"rollback",title:Vi(i.href),user:mw.util.getParamValue("from",i.href),token:mw.util.getParamValue("token",i.href),formatversion:2,uselang:o.local.userLanguage};k.post(t).then(s=>{var r;let n=$(Lt((r=s==null?void 0:s.rollback)==null?void 0:r.summary));me(n),mw.notify(n,{tag:"rollback"}),$(i).closest(".mw-rollback-link").remove(),A.refresh()}).catch((s,n)=>{var c;let r=$(Lt((c=n==null?void 0:n.error)==null?void 0:c.info));me(r),mw.notify(r,{type:"error",tag:"rollback"}),e.remove(),$(i).css("display","")})}function Ni(i){return!i||i.length===0?!1:(mw.loader.using(["@wikimedia/codex","ext.wikilambda.app"]).then(e=>{let{createMwApp:t}=e("vue"),{createPinia:s}=e("pinia"),{useMainStore:n,App:r}=e("ext.wikilambda.app");if(mw.config.get("wgWikiLambda")){let c=s(),u=n(c);window.vueInstance=t(Object.assign({provide:()=>({viewmode:u.getViewMode})},r)).use(c).mount(i.get(0))}}),!0)}function Fi(i){return m(this,null,function*(){if(!i||i.length===0)return;let e=["wikibasemediainfo-filepage-fileinfo-heading","wikibasemediainfo-filepage-structured-data-heading"];return yield k.loadMessage(e),Co(i)})}function Co(i){let e=new OO.ui.TabPanelLayout("captions",{expanded:!1,label:mw.msg("wikibasemediainfo-filepage-fileinfo-heading"),$content:i.find("mediainfoviewcaptions")}),t=new OO.ui.TabPanelLayout("statements",{expanded:!1,label:mw.msg("wikibasemediainfo-filepage-structured-data-heading"),$content:i.find("mediainfoviewstatements")}),s=new OO.ui.IndexLayout({expanded:!1,framed:!1});s.addTabPanels([e,t],0);let n=new OO.ui.PanelLayout({expanded:!1,framed:!1,content:[s]});return S("div",{class:"instantDiffs-page-mediaInfo"},n.$element.get(0))}var S,Ti,an,Ao,Et=v(()=>{T();P();G();oe();Ai();H();pe();ae();O();({h:S,hf:Ti,ht:an,hj:Ao}=y)});var ji,Bi,cn=v(()=>{P();ji=class{constructor(e,t){a(this,"config",mw.config);a(this,"values",{});a(this,"backup",{});t&&(this.config=t),this.setValues(e)}set(e,t){Object.hasOwn(this.backup,e)||(this.backup[e]=this.config.get(e)),this.values[e]=t}setValues(e){for(let[t,s]of Object.entries(e))this.set(t,s)}setTitle(e){l(e)||(F(e)&&(e=new mw.Title(e)),this.setValues({wgTitle:e.getMainText(),wgPageName:e.getPrefixedDb(),wgNamespaceNumber:e.getNamespaceId(),wgRelevantPageName:e.getPrefixedDb()}))}get(e){return this.values[e]}getValues(){return this.values}apply(){for(let[e,t]of Object.entries(this.values))t!==void 0&&this.config.set(e,t)}restore(){for(let[e,t]of Object.entries(this.backup))t!==void 0&&this.config.set(e,t)}},Bi=ji});var Ui,fn,dn=v(()=>{H();Ui=class{constructor(){a(this,"items",new Map)}get(e,t){let s=k.get(e,t);return this.add(s),s}ajax(e){let t=$.ajax(e);return this.add(t),t}when(...e){return $.when(...e)}abort(){this.items.forEach((e,t)=>t.abort())}add(e){let t=e.always(()=>this.delete(e));return this.items.set(e,t),t}delete(e){this.items.delete(e)}},fn=Ui});var zi={};Q(zi,{getDaysLeftExpiry:()=>Hi,updateGlobalWatchlistStatus:()=>_i,updateWatchButtonStatus:()=>$t,updateWatchlistStatus:()=>Gi});function Hi(i){if(!i||mw.util.isInfinity(i))return null;let e=new Date(i);return Math.ceil((e-new Date)/(1e3*60*60*24))}function $t(i,e){let t=i.get("watched"),s=t?"unwatch":"watch",n=i.get("expiry")||"infinity",r=Hi(n),c=`action-${s}`,u=mw.util.getUrl(i.get("title"),{action:s}),h,b;t?mw.util.isInfinity(n)?(h="unwatch",b="unStar"):(h=r>0?"unwatch-expiring":"unwatch-expiring-hours",b="halfStar"):(h="watch",b="star"),e.setLabel(p(c)),e.setTitle(mw.msg(`tooltip-ca-${h}`,r)),e.setHref(z(i,u)),e.setIcon(b)}function Gi(i,e,t){let s=i.get("titleText");e?hn(s,(n,r,c)=>{r.find(".mw-changelist-line-inner-unwatched").addBack(".mw-enhanced-rc-nested").removeClass("mw-changelist-line-inner-unwatched"),c.length>0&&c.text(mw.msg("watchlist-unwatch")).attr("title",mw.msg("tooltip-ca-unwatch")).attr("href",mw.util.getUrl(n,{action:"unwatch"})).removeClass("mw-watch-link loading").addClass("mw-unwatch-link"),un(r,e,t)}):hn(s,(n,r,c)=>{r.find(".mw-changeslist-line-inner, .mw-enhanced-rc-nested").addBack(".mw-enhanced-rc-nested").addClass("mw-changelist-line-inner-unwatched"),c.length>0&&c.text(mw.msg("watchlist-unwatch-undo")).attr("title",mw.msg("tooltip-ca-watch")).attr("href",mw.util.getUrl(n,{action:"watch"})).removeClass("mw-unwatch-link loading").addClass("mw-watch-link"),un(r,e,t)})}function un(i,e,t){if(!e)return;let s=i.find(".mw-changesList-watchlistExpiry");if(mw.util.isInfinity(t))return Mo(i,s);let n=Hi(t),r=n>0?"days-full-text":"hours-full-text",c=mw.msg(`watchlist-expiring-${r}`,n);s.length>0?s.each((u,h)=>{h.title=c}):Oo(i,c)}function Mo(i,e){e.each((t,s)=>{let n=$(s);n.next(".mw-changeslist-separator").addClass("mw-changeslist-separator--semicolon").removeClass("mw-changeslist-separator"),s.previousSibling.nodeValue=s.previousSibling.nodeValue.trimEnd(),s.nextSibling.nodeValue=s.nextSibling.nodeValue.trimStart(),n.next(".mw-changeslist-links").before(" "),e.remove()}),i.find(".mw-changeslist-line-inner-historyLink").prepend(" ")}function Oo(i,e){i.find(".mw-title").each((t,s)=>{let n=$(s),r=n.next(".mw-fr-reviewlink"),c=new OO.ui.IconWidget({icon:"clock",title:e,classes:["mw-changesList-watchlistExpiry"]});(r.length>0?r:n).after(" ").after(c.$element).after(" "),c.$element.next(".mw-changeslist-separator--semicolon").addClass("mw-changeslist-separator").removeClass("mw-changeslist-separator--semicolon")})}function hn(i,e){let t=mw.Title.newFromText(i),n=(t.isTalkPage()?t.getSubjectPage():t.getTalkPage()).getPrefixedText();$(".mw-changeslist-line").each((r,c)=>{$(c).find("[data-target-page]").each((h,b)=>{let x=$(b),g=String(x.data("targetPage"));if(g===i||g===n){let D=x.closest("li, .mw-enhancedchanges-checkbox + table.mw-changeslist-log td[data-target-page], table"),E=D.find(".mw-unwatch-link, .mw-watch-link");e(g,D,E)}})})}function _i(i,e,t){if(mw.globalwatchlist)try{let s=mw.globalwatchlist.watchedSites.siteList.find(n=>n.site===i.get("hostname"));if(!s)return;s.processUpdateWatched(i.get("origTitle"),!e)}catch(s){C("error-global-watchlist",{article:i,tag:"watch",message:(s==null?void 0:s.message)||s,silent:!0})}}var Ki=v(()=>{P();oe()});var Io,tt,At,Qi=v(()=>{T();P();Ki();G();O();H();({h:Io}=y),tt=class{constructor(e,t){a(this,"article");a(this,"options",{});a(this,"preferredExpiry");a(this,"isWatchlistExpiryEnabled",!1);a(this,"watchlistLabelsEnabled",!1);a(this,"isWatchListPopupEnabled",!1);a(this,"isWatched",!1);a(this,"$watchLink");a(this,"watchlistPopupWrapper");a(this,"watchlistPopup");a(this,"showError",(e,t)=>{let s=k.getApi().getErrorMessage(t);mw.notify(s,{tag:"watch-self",type:"error",id:this.constructor.notificationId})});a(this,"showNotice",e=>{if(!e)return this.showError(void 0,e);this.isWatched=e.watched===!0;let t=this.article.getMW("title"),s=e.expiry||"infinity",n=this.isWatched?"addedwatchtext":"removedwatchtext";t.isTalkPage()&&(n+="-talk");let r;this.isWatchListPopupEnabled?(this.isWatched&&(n=!this.preferredExpiry||mw.util.isInfinity(this.preferredExpiry)?"addedwatchindefinitelytext":"addedwatchexpirytext",t.isTalkPage()&&(n+="-talk")),r=this.showWatchlistNotice(t,n,s)):r=this.showBasicNotice(t,n),r.always(()=>{let c=this.isWatched?"unwatch":"watch";this.updateStatus(this.$watchLink,c,"idle",s,"infinity")})});a(this,"onWatchlistPopupWatch",e=>{var s,n;this.isWatched=!0;let t=(s=e.detail)!=null&&s.watchResponse?e.detail.watchResponse.expiry||((n=e.detail.watchResponse._rawValue)==null?void 0:n.expiry):"infinity";this.updateStatus(this.$watchLink,"unwatch","idle",t)});a(this,"onWatchlistPopupUnwatch",e=>{this.isWatched=!1,this.updateStatus(this.$watchLink,"watch","idle")});a(this,"updateStatus",(e,t,s,n="infinity",r="infinity")=>{let c=t==="unwatch";if(this.isWatched=c,this.article.setValues({watched:c,expiry:n,expirySelected:r}),this.options.onUpdate(s),!this.article.isForeign&&o.local.mwTitleText===this.article.get("titleText")){let{updatePageWatchStatus:u}=Ze("mediawiki.page.watch.ajax")||{};u==null||u(c,n,r)}s!=="loading"&&(!this.article.isForeign&&o.local.mwCanonicalSpecialPageName==="Watchlist"&&Gi(this.article,c,n),o.local.mwCanonicalSpecialPageName==="GlobalWatchlist"&&_i(this.article,c,n))});this.article=e,this.options=f({onUpdate:()=>{}},t),this.$watchLink=$('<a class="instantDiffs-button--fake-watch">'),N(this.$watchLink,document.body);let s=bt("mediawiki.page.watch.ajax","config.json")||{};this.isWatchlistExpiryEnabled=!this.article.isForeign&&(s.WatchlistExpiry||!1),this.watchlistLabelsEnabled=!this.article.isForeign&&(s.EnableWatchlistLabels||!1),this.isWatchListPopupEnabled=d.get("showWatchlistPopup")&&(this.isWatchlistExpiryEnabled||this.watchlistLabelsEnabled);let n=["mediawiki.notification"];(this.isWatchlistExpiryEnabled||this.watchlistLabelsEnabled)&&n.push("mediawiki.watchstar.widgets"),this.watchlistLabelsEnabled&&n.push("mediawiki.widgets.MenuTagMultiselectWidget"),mw.loader.load(n)}preloadMessages(){return m(this,null,function*(){yield k.loadMessage(["watchlist-expiring-days-full-text","watchlist-expiring-hours-full-text","tooltip-ca-watch","tooltip-ca-unwatch","tooltip-ca-unwatch-expiring","tooltip-ca-unwatch-expiring-hours"])})}request(){return m(this,null,function*(){return yield this.preloadMessages(),this.preferredExpiry=mw.user.options.get("watchstar-expiry","infinity"),this.isWatched=this.article.get("watched"),d.get("expEnableWatchlistPopup")&&this.isWatchListPopupEnabled?this.requestModules():this.requestWatchStatus()})}requestModules(){return mw.loader.using("mediawiki.watchstar.widgets").then(e=>{let t=e("mediawiki.watchstar.widgets");return Ve(t)?this.showWatchlistPopup():this.requestWatchStatus()})}requestWatchStatus(){let e=this.article.getMW("title").getPrefixedDb();return(this.isWatched?k.unwatch(e,this.article):k.watch(e,this.preferredExpiry,this.article)).then(this.showNotice).fail(this.showError)}getNoticeMessage(e,t){let s=this.article.get("hostname"),n=mw.message(t,e.getPrefixedText(),this.preferredExpiry).parseDom();return te(n,`https://${s}`),me(n),n}showBasicNotice(e,t){let s=this.getNoticeMessage(e,t);return mw.notify(s,{tag:"watch-self",id:this.constructor.notificationId})}showWatchlistNotice(e,t,s){return mw.loader.using("mediawiki.watchstar.widgets").then(n=>{let r=n("mediawiki.watchstar.widgets");if(!r)return this.showBasicNotice(e,t);let c=this.getNoticeMessage(e,t),u=[this.isWatched?"watch":"unwatch",e.getPrefixedDb(),s,this.updateStatus,{expiryEnabled:this.isWatchlistExpiryEnabled,labelsEnabled:this.watchlistLabelsEnabled,$link:this.$watchLink,message:c}];Ji(mw.config.get("wgVersion"),"1.45.0")<0&&u.splice(2,1);try{let h=new r(...u);mw.notify(h.$element,{tag:"watch-self",id:this.constructor.notificationId,autoHideSeconds:"short"})}catch(h){Pe(this.constructor.name,"Falls back to basic watch/unwatch functionality.",h),this.showBasicNotice(e,t)}})}showWatchlistPopup(){return this.watchlistPopup?(this.watchlistPopup.isOpen?this.watchlistPopup.isOpen=!1:this.watchlistPopup.openPopup(this.$watchLink[0]),$.Deferred().resolve().promise()):mw.loader.using(["@wikimedia/codex","mediawiki.watchstar.widgets"]).then(e=>{let t=e("vue"),s=e("mediawiki.watchstar.widgets"),n=s.WatchlistPopup;this.watchlistPopupWrapper=Io("span.mw-watchlink-popup"),N(this.watchlistPopupWrapper,document.body),this.watchlistPopup=t.createMwApp(n,{initialAction:this.isWatched?"unwatch":"watch",expiryEnabled:this.isWatchlistExpiryEnabled,labelsEnabled:this.watchlistLabelsEnabled,title:this.article.getMW("title"),dataExpiryOptions:s.dataExpiryOptions,preferredExpiry:this.preferredExpiry,link:this.$watchLink[0]}).mount(this.watchlistPopupWrapper),window.addEventListener("WatchlistPopup.watch",this.onWatchlistPopupWatch),window.addEventListener("WatchlistPopup.unwatch",this.onWatchlistPopupUnwatch)})}getArticle(){return this.article}detach(){this.watchlistPopup&&(window.removeEventListener("WatchlistPopup.watch",this.onWatchlistPopupWatch),window.removeEventListener("WatchlistPopup.unwatch",this.onWatchlistPopupUnwatch),this.watchlistPopup.isOpen=!1,this.watchlistPopupWrapper.remove()),this.$watchLink.detach()}};a(tt,"utils",zi),a(tt,"notificationId","mw-watchlink-notification");At=tt});var Yi={};Q(Yi,{default:()=>Ro});var Tt,Ro,Zi=v(()=>{P();G();oe();Ne();O();Tt=class extends OO.ui.ButtonWidget{constructor(t){t=j(f({name:null,type:"default",classes:[],framed:!0,invisibleLabel:!1,invisibleIcon:!1,icon:"puzzle",href:null,target:Je(!0),handler:null,useAltKey:!1,article:null,setLink:!1},t),{linkOptions:f({behavior:"event"},t.linkOptions)}),t.type==="navigation"&&(t.icon=null,t.classes=[...t.classes,"instantDiffs-button--navigation"]),t.type==="pin"&&(t.invisibleLabel=!0,t.classes=[...t.classes,"instantDiffs-button--pin"]),t.type==="menu"&&(t.classes=[...t.classes,"instantDiffs-button--link"],t.framed=!1,d.get("showMenuIcons")||(t.invisibleIcon=!0)),l(t.href)||(t.href=z(t.article,t.href));super(t);a(this,"options",{});a(this,"invisibleIcon",!1);a(this,"link");a(this,"handler");this.options=t,this.setInvisibleIcon(t.invisibleIcon),t.handler&&this.setHandler(t.handler,t.useAltKey),t.setLink&&this.setLink(t.linkOptions)}setInvisibleIcon(t){return t=!!t,this.invisibleIcon!==t&&(this.invisibleIcon=t,this.$element.toggleClass("instantDiffs-invisibleIconElement",!this.icon||this.invisibleIcon)),this}setLink(t){return this.link=new I(this.$button.get(0),t),this}setHandler(t,s){if(L(this.handler)&&Xi(this.$button.get(0),this.handler),L(t)){let n=r=>t(this,r);this.handler=Ke(this.$button.get(0),n,s)}return this}execHandler(){return this.$button.get(0).click(),this}getOption(t){return this.options[t]}getOptions(){return this.options}getArticle(){return this.getOption("article")}pending(t){return this.$button.toggleClass("instantDiffs-link--pending",t),this}};K(Tt);Ro=Tt});var es,pn,gn=v(()=>{P();O();es=class{constructor(e,t){a(this,"article");a(this,"options",{});a(this,"groups",{});a(this,"buttons",{});a(this,"MenuButton");this.article=e,this.options=f({},t),this.MenuButton=(Zi(),Me(Yi)).default}renderGroup(e){return e=f({name:null,group:null,widget:null,type:"vertical",classes:[],container:null},e),e.type==="vertical"&&e.classes.push("instantDiffs-buttons-group","instantDiffs-buttons-group--vertical",`instantDiffs-buttons-group--${e.name}`,d.get("showMenuIcons")?"has-icons":null),e.type==="horizontal"&&e.classes.push("instantDiffs-buttons-group","instantDiffs-buttons-group--horizontal",`instantDiffs-buttons-group--${e.name}`),e.widget=new OO.ui.ButtonGroupWidget(e),N(e.widget.$element,e.container),this.registerGroup(e)}registerGroup(e){if(e=f({name:null,group:null,widget:null},e),!this.groups[e.name])return this.groups[e.name]=e,e}getGroup(e){return this.groups[e]}getGroups(e){return Object.values(this.groups).filter(t=>!e||e===t.group)}getGroupsWidgets(e){return this.getGroups(e).map(t=>t.widget)}getGroupsElements(e){return this.getGroups(e).map(t=>t.widget.$element.get(0))}addGroupButtons(e,t){let s=this.getGroup(e);if(!s)return;t=Z(t)?t:[t];let n=t.map(r=>r.widget);s.widget.addItems(n)}getGroupButtons(e){return this.getButtons().filter(t=>Ct(e,t.group))}renderButton(e){if(e=f({article:this.article,name:null,group:null,canSystem:!1,systemType:"pin",systemGroup:"navigation",canPin:!1,pinType:"pin",pinGroup:"pins",canMenu:!0,menuGroup:"menu",menuType:"menu",widget:null},e),this.buttons[e.name])return;let t=this.buttons[e.name]=[];if(e.canSystem){let s=this.renderButtonHelper(j(f({},e),{type:e.systemType,group:e.systemGroup,isSystem:!0}));t.push(s)}if(e.canPin&&Ct(d.get("pinnedActions"),e.name)){let s=this.renderButtonHelper(j(f({},e),{type:e.pinType,group:e.pinGroup,isPin:!0}));t.push(s)}if(e.canMenu){let s=this.renderButtonHelper(j(f({},e),{type:e.menuType,group:e.menuGroup,isMenu:!0}));t.push(s)}return t}renderButtonHelper(e){return e.widget=new this.MenuButton(e),this.addGroupButtons(e.group,e),e}registerButton(e){if(e=f({name:null,group:null,type:null,widget:null},e),!this.buttons[e.name])return this.buttons[e.name]=[e],this.addGroupButtons(e.group,e),e}getButton(e,t){if(this.buttons[e])return this.buttons[e].filter(n=>!t||F(t)&&n.group===t||Z(t)&&t.includes(n.group))}getButtonWidget(e,t){let s=this.getButton(e,t);if(s)return s.map(n=>n.widget)}getButtons(){return Object.values(this.buttons).flat()}eachButton(e,t,s){let n=this.getButton(e,t);n&&n.forEach(r=>s(r))}eachButtonWidget(e,t,s){let n=this.getButtonWidget(e,t);n&&n.forEach(r=>s(r))}focusButton(e,t){let s=!1;return this.eachButtonWidget(e,t,n=>{if(!n.isDisabled())return n.focus(),s=!0,!0}),s}pendingButton(e,t,s){this.eachButtonWidget(e,t,n=>{n.pending(s)})}},pn=es});var mn=v(()=>{});var wn={};Q(wn,{default:()=>Wo});var Mt,Wo,bn=v(()=>{P();G();O();Mt=class extends OO.ui.PopupButtonWidget{constructor(e){e=ie({icon:"menu",label:p("goto-actions"),title:_("goto-actions","actions",d.get("enableHotkeys")),invisibleLabel:!0,popup:{classes:["instantDiffs-buttons-popup",d.get("showMenuIcons")?"has-icons":null],width:"auto",padded:!1,anchor:!1,align:"backwards",autoClose:!0}},e),super(e)}execHandler(){return this.$button.get(0).click(),this}togglePopup(e){return this.getPopup().toggle(e),this}pending(e){return this.$button.toggleClass("instantDiffs-link--pending",e),this}};K(Mt);Wo=Mt});var Ee,No,Fo,ts,vn,kn=v(()=>{T();P();Ie();oe();Ki();pe();$i();Qi();gn();ae();O();mn();({h:Ee,hf:No,ht:Fo}=y),ts=class{constructor(e,t,s,n){a(this,"MenuActionsButton");a(this,"MenuButton");a(this,"page");a(this,"article");a(this,"articleParams",{});a(this,"options",{});a(this,"nodes",{});a(this,"actionRegister");a(this,"watch");a(this,"menu");a(this,"isDetached",!1);a(this,"groupsMap",{left:["snapshot"],center:["navigation"],right:["pins-custom","pins"]});a(this,"groups",[]);a(this,"actionGroupsMap",["mobile","menu-custom","menu","footer"]);a(this,"actionGroups",[]);a(this,"actionCounterparts",{unpatrolled:"back","back-unpatrolled":"unpatrolled"});a(this,"disabledActionCounterparts",{next:"prev",prev:"next",snapshotNext:"snapshotPrev",snapshotPrev:"snapshotNext"});a(this,"actionHotkeyMap",{none:{ArrowLeft:"prev",ArrowRight:"next"},ctrl:{ArrowLeft:"snapshotPrev",ArrowRight:"snapshotNext",ArrowUp:"switch",ArrowDown:"actions",KeyZ:"back",KeyP:"unpatrolled"},alt:{},shift:{}});a(this,"actionHotkeyMapRTL",{none:{ArrowRight:"prev",ArrowLeft:"next"},ctrl:{ArrowRight:"snapshotPrev",ArrowLeft:"snapshotNext"}});this.page=e,this.article=t,this.articleParams=f({},s),this.options=f({initiatorAction:null,links:{}},n),this.MenuActionsButton=(bn(),Me(wn)).default,this.MenuButton=(Zi(),Me(Yi)).default,A.connect(this,{hotkey:"onHotkey"}),this.render()}render(){this.nodes.container=Ee("div",{class:["instantDiffs-navigation"]},this.nodes.left=Ee("div",{class:["instantDiffs-navigation-group","instantDiffs-navigation-group--left"]}),this.nodes.center=Ee("div",{class:["instantDiffs-navigation-group","instantDiffs-navigation-group--center"]}),this.nodes.right=Ee("div",{class:["instantDiffs-navigation-group","instantDiffs-navigation-group--right"]})),this.renderMenu(),this.renderSnapshotLinks(),this.renderNavigationLinks(),this.renderActionLinks(),mw.hook(`${o.config.prefix}.navigation.complete`).fire(this)}renderMenu(){this.menu=new pn(this.article);for(let[e,t]of Object.entries(this.groupsMap))t.forEach(s=>{this.groups.push(s),this.menu.renderGroup({name:s,group:e,type:"horizontal",container:this.nodes[e]})});this.actionGroupsMap.forEach(e=>{this.actionGroups.push(e),this.menu.renderGroup({name:e,group:"actions",type:"vertical"})})}renderSnapshotLinks(){let e={canSystem:!0,systemType:"pin",systemGroup:"snapshot",canPin:!1,canMenu:!1},t={canMenu:!0,menuGroup:"mobile"};this.renderSnapshotPrevLink(e),this.renderSnapshotNextLink(e),this.page.getInitiatorPage()&&this.renderBackLink(f(f({},e),t)),l(this.options.links.unpatrolled)||this.renderUnpatrolledLink(f(f({},e),t))}renderNavigationLinks(){let e={canSystem:!0,systemType:"navigation",systemGroup:"navigation",canPin:!1,canMenu:!1},t={canMenu:!0,menuGroup:"mobile"};this.renderPrevLink(e),["page"].includes(this.article.get("typeVariant"))||this.renderSwitchLink(f(f({},e),t)),this.renderNextLink(e)}renderActionLinks(){this.renderMenuLinks(),this.renderMenuFooterLinks(),this.renderMenuActions()}renderMenuLinks(){let e={canPin:!0,pinGroup:"pins",canMenu:!0,menuGroup:"menu"};this.renderCopyLink(e),this.renderCopyWikilink(e),this.renderTypeLink(e),l(this.article.get("title"))||(this.renderPageLink(e),this.article.getMW("title").canHaveTalkPage()&&this.renderTalkPageLink(e),li(mw.config.get("wgPageContentModel"))&&this.renderEditLink(e),this.renderHistoryLink(e),this.renderInfoLink(e),o.local.mwIsAnon||this.renderWatchLink(e)),this.renderSettingsLink(e)}renderMenuFooterLinks(){let e={canPin:!1,canMenu:!0,menuGroup:"footer"};this.renderIDLink(e)}renderMenuActions(){let e=is(this.menu.getGroupsElements("actions"),Ee("hr.instantDiffs-buttons-separator")),t=new this.MenuActionsButton({popup:{$content:$(e)}});this.menu.registerButton({name:"actions",group:"pins",type:"pin",widget:t})}renderSnapshotPrevLink(e){let t=Se.instance.getPreviousLink();e=f({name:"snapshotPrev",label:p("goto-snapshot-prev"),title:_("goto-snapshot-prev","snapshot-prev",d.get("enableHotkeys")),icon:"doubleChevronStart",href:t?t.href:null,disabled:!t,setLink:!!t,linkOptions:{initiatorLink:t,onRequest:()=>this.setActionRegister(e.name)}},e),this.menu.renderButton(e)}renderSnapshotNextLink(e){let t=Se.instance.getNextLink();e=f({name:"snapshotNext",label:p("goto-snapshot-next"),title:_("goto-snapshot-next","snapshot-next",d.get("enableHotkeys")),icon:"doubleChevronEnd",href:t?t.href:null,disabled:!t,setLink:!!t,linkOptions:{initiatorLink:t,onRequest:()=>this.setActionRegister(e.name)}},e),this.menu.renderButton(e)}renderPrevLink(e){let t;if(this.options.links.prev){let n=new V({title:this.article.get("title"),hostname:this.article.get("hostname"),oldid:mw.config.get("wgDiffOldId"),diff:this.article.get("type")==="diff"?"prev":null,direction:this.article.get("type")==="revision"?"prev":null});t=q(n)}let s=Ot({short:p("goto-prev"),long:p(`goto-prev-${this.article.get("type")}`),iconBefore:document.dir==="ltr"?"\u2190":"\u2192"});e=f({name:"prev",label:$(s),title:_(`goto-prev-${this.article.get("type")}`,"prev",d.get("enableHotkeys")),href:t,disabled:!t,setLink:!!t,linkOptions:{onRequest:()=>this.setActionRegister(e.name)}},e),this.menu.renderButton(e)}renderNextLink(e){let t;if(this.options.links.next){let n=new V({title:this.article.get("title"),hostname:this.article.get("hostname"),oldid:mw.config.get("wgDiffNewId"),diff:this.article.get("type")==="diff"?"next":null,direction:this.article.get("type")==="revision"?"next":null});t=q(n)}let s=Ot({short:p("goto-next"),long:p(`goto-next-${this.article.get("type")}`),iconAfter:document.dir==="ltr"?"\u2192":"\u2190"});e=f({name:"next",label:$(s),title:_(`goto-next-${this.article.get("type")}`,"next",d.get("enableHotkeys")),href:t,disabled:!t,setLink:!!t,linkOptions:{onRequest:()=>this.setActionRegister(e.name)}},e),this.menu.renderButton(e)}renderSwitchLink(e){let t=this.article.get("type")==="diff"?"revision":"diff",s={type:t};e=f({name:"switch",label:p(`goto-view-${t}`),title:_(`goto-view-${t}`,"switch",d.get("enableHotkeys")),icon:"specialPages",href:q(this.article,{},s),classes:["instantDiffs-button--switch"],setLink:!0,linkOptions:{onRequest:()=>this.setActionRegister(e.name)}},e),this.menu.renderButton(e)}renderUnpatrolledLink(e){e=f({name:"unpatrolled",label:p("goto-view-unpatrolled"),title:_("goto-view-unpatrolled","unpatrolled",d.get("enableHotkeys")),icon:"eyeClosed",href:this.options.links.unpatrolled,classes:["instantDiffs-button--pending"],setLink:!0,linkOptions:{initiatorPage:this.page,onRequest:()=>this.setActionRegister(e.name)}},e),this.menu.renderButton(e)}renderBackLink(e){let t=this.page.getInitiatorPage(),s=t.getArticle();e=f({name:"back",label:p(`goto-back-${s.get("type")}`),title:_(`goto-back-${s.get("type")}`,"back",d.get("enableHotkeys")),icon:"newline",href:q(s,t.getArticleParams()),classes:["instantDiffs-button--back"],setLink:!0,linkOptions:{onRequest:()=>{var c;let n=(c=t.getNavigation())==null?void 0:c.getActionRegister(),r=l(n)?e.name:`${e.name}-${n}`;this.setActionRegister(r)}}},e),this.menu.renderButton(e)}renderCopyLink(e){this.menu.renderButton(f({name:"copyLink",label:p("copy-link"),icon:"link",handler:this.actionCopyLink.bind(this)},e))}renderCopyWikilink(e){this.menu.renderButton(f({name:"copyWikilink",label:p("copy-wikilink"),icon:"wikiText",handler:this.actionCopyWikilink.bind(this)},e))}renderTypeLink(e){let t=this.article.get("type"),s={hash:d.get("linksHash")};this.menu.renderButton(f({name:"link",label:p(`goto-${t}`),icon:"articleRedirect",href:q(this.article,{},s)},e))}renderPageLink(e){let t=this.article.getMW("title").isTalkPage()?this.article.getMW("title").getSubjectPage().getUrl():this.article.get("href"),s={2:"userAvatar",3:"userAvatar",default:"article"};this.menu.renderButton(f({name:"page",label:p("goto-page"),icon:s[this.article.getMW("title").getNamespaceId()]||s.default,href:t},e))}renderTalkPageLink(e){let t=this.article.getMW("title").isTalkPage()?this.article.get("href"):this.article.getMW("title").getTalkPage().getUrl(),s={2:"userTalk",3:"userTalk",default:"speechBubbles"};this.menu.renderButton(f({name:"talkPage",label:p("goto-talkpage"),icon:s[this.article.getMW("title").getNamespaceId()]||s.default,href:t},e))}renderEditLink(e){let t=mw.config.get("wgIsProbablyEditable"),s=mw.util.getUrl(this.article.get("title"),{action:"edit"});this.menu.renderButton(f({name:"edit",label:p(t?"goto-edit":"goto-source"),icon:t?"edit":"editLock",href:s},e))}renderHistoryLink(e){let t=mw.util.getUrl(this.article.get("title"),{action:"history"});this.menu.renderButton(f({name:"history",label:p("goto-history"),icon:"history",href:t},e))}renderInfoLink(e){let t=mw.util.getUrl(this.article.get("title"),{action:"info"});this.menu.renderButton(f({name:"info",label:p("goto-info"),icon:"info",href:t},e))}renderWatchLink(e){this.menu.renderButton(f({name:"watch",label:p("action-watch"),handler:this.actionWatchPage.bind(this)},e)),this.menu.eachButtonWidget("watch",null,t=>{$t(this.article,t)})}renderSettingsLink(e){this.menu.renderButton(f({name:"settings",label:p("goto-settings"),icon:"settings",handler:this.actionOpenSettings.bind(this)},e))}renderIDLink(e){let t=No(Ee("span.name",p("script-name")),Fo(" "),Ee("span.version",`v.${o.config.version}`));this.menu.renderButton(f({name:"id",label:$(t),icon:null,href:It(`/wiki/${o.config.link}`),classes:["instantDiffs-button--link-id"]},e))}actionCopyLink(e){let t={relative:!1,hash:d.get("linksHash"),minify:d.get("linksFormat")==="minify"},s=q(this.article,{},t);it(s),this.focusAction(e)}actionCopyWikilink(e){this.pendingAction(e,!0),$.when(wi(this.article)).done(t=>{it(t)}).fail(()=>{it(!1)}).always(()=>{this.pendingAction(e,!1),this.focusAction(e)})}actionWatchPage(e){this.pendingAction(e,!0),this.watch||(this.watch=new At(this.article,{onUpdate:t=>{this.menu.eachButtonWidget("watch",null,s=>{s.pending(t==="loading"),$t(this.article,s)})}})),$.when(this.watch.request()).always(()=>{this.pendingAction(e,!1),this.focusAction(e)})}actionOpenSettings(e){this.pendingAction(e,!0),d.once("opening",()=>this.toggleActions(!1)),d.once("closed",()=>this.focusAction(e)),$.when(d.load()).always(()=>{this.pendingAction(e,!1)})}focusAction(e){return this.toggleActions(!1),e instanceof this.MenuButton?this.focusActionByWidget(e):F(e)?this.focusActionByName(e):!1}focusActionByWidget(e){if(e.isDisabled())return!1;let t=e.getOption("group");return this.groups.includes(t)?(e.focus(),!0):this.focusActionByName("actions")}focusActionByName(e){return e=this.actionCounterparts[e]||e,this.menu.focusButton(e,this.groups)?!0:(e=this.disabledActionCounterparts[e],e?this.menu.focusButton(e,this.groups):!1)}getActionName(e){if(e instanceof this.MenuButton)return e.getOption("name");if(F(e))return e}pendingAction(e,t){this.getActionName(e)&&this.menu.pendingButton(this.getActionName(e),null,t)}execAction(e){let t=this.getActionName(e);t&&(t!=="actions"&&this.toggleActions(!1),this.menu.eachButtonWidget(t,null,s=>{if(!s.isDisabled())return s.focus(),s.execHandler(),!0}))}toggleActions(e){this.menu.eachButtonWidget("actions",this.groups,t=>{t.togglePopup(e)})}setActionRegister(e){this.actionRegister=e}getActionRegister(){return this.actionRegister}getPinnableActions(){return this.menu.getButtons().filter(e=>e.canPin)}addCustomAction(e){e=j(f({},e),{canSystem:!1,canPin:!0,pinGroup:"pins-custom",canMenu:!0,menuGroup:"menu-custom"}),!l(e.name)&&(e.name=`custom-${e.name}`,this.menu.renderButton(e))}getCustomAction(e){let t;return e instanceof this.MenuButton&&(t=e.getOption("name")),F(e)&&(t=`custom-${e}`),this.menu.getButton(t,["pins-custom","menu-custom"])}getCustomActionWidget(e){let t=this.getCustomAction(e);if(t)return t.map(s=>s.widget)}eachCustomAction(e,t){let s=this.getCustomAction(e);s&&s.forEach(n=>t(n))}eachCustomActionWidget(e,t){let s=this.getCustomActionWidget(e);s&&s.forEach(n=>t(n))}getActionHotkeyMap(){return document.dir==="rtl"?ie(this.actionHotkeyMap,this.actionHotkeyMapRTL):this.actionHotkeyMap}onHotkey(e){var r;if(!d.get("enableHotkeys"))return;let t=this.getActionHotkeyMap(),s=e.altKey?"alt":e.ctrlKey?"ctrl":e.shiftKey?"shift":"none",n=(r=t[s])==null?void 0:r[e.code];n&&(e.preventDefault(),e.stopPropagation(),this.execAction(n))}getOuterHeight(e=!1){return ss(this.nodes.container,e)}getArticle(){return this.article}getMenu(){return this.menu}fire(){this.focusAction(this.options.initiatorAction)}embed(e,t){N(this.nodes.container,e,t)}detach(){var e;(e=this.watch)==null||e.detach(),this.toggleActions(!1),A.disconnect(this,{hotkey:"onHotkey"}),this.nodes.container.remove(),this.isDetached=!0}},vn=ts});var yn=v(()=>{});var Rt,$e,Wt=v(()=>{T();P();Et();oe();Ie();H();cn();dn();kn();O();yn();Rt=class{constructor(e,t){a(this,"type","abstract");a(this,"article");a(this,"options",{});a(this,"articleParams",{});a(this,"error");a(this,"errorData");a(this,"nodes",{});a(this,"links",{});a(this,"configManager");a(this,"userOptionsManager");a(this,"requestManager");a(this,"loadPromise");a(this,"navigation");a(this,"isLoading",!1);a(this,"isLoaded",!1);a(this,"isConfigsChanged",!1);a(this,"isDetached",!1);a(this,"loadProcessSecondary",()=>{let e=this.getLoadSecondaryPromises();return Promise.allSettled(e)});a(this,"onLoadResponse",()=>m(this,null,function*(){var e;this.isLoading=!1,this.isLoaded=!0,!this.isDetached&&((e=this.error)==null?void 0:e.statusText)!=="abort"&&(l(this.data)?yield this.renderError():yield this.renderSuccess())}));a(this,"onRequestError",(e,t)=>{this.error=e,this.errorData=t==null?void 0:t.error});a(this,"onRequestDone",e=>{this.data=e});a(this,"onRequestCompareError",(e,t)=>{this.onRequestError(e,t)});a(this,"onRequestCompareDone",e=>{let t=e==null?void 0:e.compare;if(!t)return this.onRequestCompareError(null,e);this.article.set({oldid:t.fromrevid,diff:t.torevid,page1:t.fromtitle,page2:t.totitle,title:ge(t),section:We(t)})});this.article=e,this.options=f({initiatorAction:null,initiatorPage:null,fireDiffHook:!0,fireContentHook:!0},t),this.articleParams={action:"render",diffonly:this.article.get("type")==="diff"?1:0,unhide:d.get("unHideDiffs")?1:0,uselang:o.local.userLanguage},this.configManager=new Bi({wgTitle:!1,wgPageName:!1,wgRelevantPageName:!1,wgPageContentModel:"wikitext",wgNamespaceNumber:!1,wgArticleId:!1,wgRelevantArticleId:!1,wgCurRevisionId:!1,wgRevisionId:!1,wgDiffOldId:!1,wgDiffNewId:!1,wgCanonicalSpecialPageName:!1,wgIsProbablyEditable:!1,wgRelevantPageIsProbablyEditable:!1,wbEntityId:!1,"thanks-confirmation-required":!0}),this.userOptionsManager=new Bi({},mw.user.options),this.requestManager=new fn,OO.EventEmitter.call(this)}load(){return this.isLoading?this.loadPromise:(this.isLoading=!0,this.isLoaded=!1,this.error=null,this.errorData=null,this.loadPromise=this.preloadProcess())}preloadProcess(){let e=this.getPreloadPromises();return Promise.allSettled(e).then(this.loadProcess.bind(this))}loadProcess(){let e=this.getLoadPromises();return Promise.allSettled(e).then(this.onLoadResponse).then(this.loadProcessSecondary)}getPreloadPromises(){return[this.requestCompare()]}getLoadPromises(){return[this.requestPageInfo(),this.request()]}getLoadSecondaryPromises(){return[this.requestWBLabel()]}request(){return this.requestProcess().done(this.onRequestDone).fail(this.onRequestError)}requestProcess(){return this.requestManager.when()}requestCompare(){let e=this.article.getValues();if(this.error||e.typeVariant!=="comparePages"||w(e.oldid)&&w(e.diff))return $.Deferred().resolve().promise();let t={action:"compare",prop:["title","ids","timestamp","comment"],fromrev:w(e.rev1)?e.rev1:void 0,fromtitle:l(e.page1)?void 0:e.page1,torev:w(e.rev2)?e.rev2:void 0,totitle:l(e.page2)?void 0:e.page2,format:"json",formatversion:2,uselang:o.local.userLanguage};return this.requestManager.get(t,e.hostname).then(this.onRequestCompareDone).fail(this.onRequestCompareError)}requestPageInfo(){return m(this,null,function*(){var c,u,h;let e=Math.max(this.article.get("revid"),this.article.get("oldid")),t=this.article.get("curid"),s=this.article.get("title"),n={};w(e)?n.revids=e:w(t)?n.pageids=t:l(s)||(n.titles=s);let r=yield k.getPageInfo(n,this.article,this.requestManager);if(r){let b=r.pageprops||{},x=r.entityterms||{};this.configManager.setValues({wgArticleId:r.pageid,wgRelevantArticleId:r.pageid,wgCurRevisionId:r.lastrevid,wgContentLanguage:r.pagelanguage,wgContentLanguageDir:r.pagelanguagedir,wgPageContentModel:r.contentmodel,wgIsProbablyEditable:(c=r.actions)==null?void 0:c.edit,wgRelevantPageIsProbablyEditable:(u=r.actions)==null?void 0:u.edit,wbEntityId:b.wikibase_item||xe(r.contentmodel)&&r.title||this.configManager.get("wbEntityId")}),this.article.setValues({title:r.title,curid:r.pageid,curRevid:r.lastrevid,watched:r.watched,expiry:r.watchlistexpiry,notificationtimestamp:r.notificationtimestamp,new:r.new,label:xe(r.contentmodel)&&((h=x.label)==null?void 0:h[0])||r.contentmodel==="EntitySchema"&&ci(b.displaytitle)||r.contentmodel==="zobject"&&fi(b)||this.article.get("label")}),this.setConfigs()}})}requestWBLabel(){return m(this,null,function*(){var s;if(this.error||!l(this.article.get("label"))||!xe(this.configManager.get("wgPageContentModel")))return $.Deferred().resolve().promise();let e=(s=this.article.getMW("title"))==null?void 0:s.getMain(),t=yield k.getWBLabel(e,this.article,this.requestManager);l(t)||(this.configManager.set("wbEntityId",e),this.article.setValue("label",t),this.setConfigs())})}markAsSeen(){if(this.error||!d.get("markWatchedLine")||!this.article.isForeign||l(this.article.get("timestamp"))||l(this.article.get("notificationtimestamp")))return;let e=new Date(this.article.get("notificationtimestamp")).getTime();if(new Date(this.article.get("timestamp")).getTime()<e)return;let s={titles:this.article.get("titleText"),newerthanrevid:this.article.get("revid")};k.markAsSeen(s,this.article)}abort(){this.isLoading&&this.requestManager.abort()}renderSuccess(){return m(this,null,function*(){yield this.render(),this.markAsSeen(),mw.hook(`${o.config.prefix}.page.renderSuccess`).fire(this),mw.hook(`${o.config.prefix}.page.renderComplete`).fire(this)})}renderError(){return m(this,null,function*(){var n,r,c,u;let e=this.article.get("type"),t=this.article.get("typeVariant"),s=t==="page"?"curid":t==="comparePages"?"compare-pages":"generic";this.error={type:e,code:s,tag:"page",status:(n=this.error)==null?void 0:n.status,statusText:(r=this.error)==null?void 0:r.statusText,message:((c=this.errorData)==null?void 0:c.info)||ns((u=this.error)==null?void 0:u.status),article:this.article},C(`error-${this.error.type}-${this.error.code}`,this.error),yield this.render(),mw.hook(`${o.config.prefix}.page.renderError`).fire(this),mw.hook(`${o.config.prefix}.page.renderComplete`).fire(this)})}render(){return m(this,null,function*(){let e=["instantDiffs-page",`instantDiffs-page--${this.type}`,`instantDiffs-page--${this.article.get("type")}`,"mw-body-content"],t=["instantDiffs-page-body",`instantDiffs-page-body--${this.type}`,`instantDiffs-page-body--${this.article.get("type")}`],s=o.config.skinBodyClasses[mw.config.get("skin")];s&&e.push(...s),this.nodes.$container=$("<div>").attr("dir",document.dir).addClass(e),this.nodes.$tools=$("<div>").addClass("instantDiffs-page-tools").appendTo(this.nodes.$container),this.nodes.$body=$("<div>").addClass(t).appendTo(this.nodes.$container),yield this.renderContent(),yield this.renderNavigation()})}renderContent(){return m(this,null,function*(){this.error?yield this.renderErrorContent():yield this.renderSuccessContent()})}renderErrorContent(){return m(this,null,function*(){let e=fe(`error-${this.error.type}-${this.error.code}`,this.error,this.article),t=$(`<p>${e}</p>`);this.renderWarning({$content:t})})}renderWarning({$content:e,type:t="warning",container:s=this.nodes.$body,insertMethod:n="prependTo"}){let r=rs({$content:e,type:t});return N(r,s,n),r}renderSuccessContent(){return m(this,null,function*(){yield this.restoreFunctionality(),this.requestDependencies()})}renderNavigation(){return m(this,null,function*(){this.navigation=new vn(this,this.article,this.articleParams,{initiatorAction:this.options.initiatorAction,links:this.links}),this.navigation.embed(this.nodes.$container,"prependTo")})}requestDependencies(e={}){let{modulestyles:t=[],modulescripts:s=[],modules:n=[]}=e,r=[...di(this.article),...t,...s,...n];return mw.loader.using(we(r))}restoreFunctionality(){return m(this,null,function*(){if(!this.error&&(this.nodes.$mediaInfoView=this.nodes.$body.find("mediainfoview"),this.article.get("type")==="revision"&&this.nodes.$mediaInfoView.length>0)){let e=yield Fi(this.nodes.$mediaInfoView);e&&N(e,this.nodes.$diffTitle,"insertAfter")}})}getScrollableSection(){let e=this.article.get("hash");if(!l(e))return os(e,this.nodes.$body)}getScrollableOffsetTop(){var e;return(e=this.getNavigation())==null?void 0:e.getOuterHeight(!0)}fire(){return m(this,null,function*(){var e;if(mw.hook(`${o.config.prefix}.page.ready`).fire(this),(e=this.getNavigation())==null||e.fire(),this.options.fireDiffHook){let t=this.getDiffTable();this.article.get("type")==="diff"&&(t==null?void 0:t.length)>0&&mw.hook("wikipage.diff").fire(t)}if(this.options.fireContentHook){let t=this.getContainer();(t==null?void 0:t.length)>0&&mw.hook("wikipage.content").fire(t)}me(this.nodes.$container),mw.hook(`${o.config.prefix}.page.complete`).fire(this)})}focus(){this.emit("focus")}setConfigs(){this.isConfigsChanged=!0,this.configManager.apply(),this.userOptionsManager.apply()}restoreConfigs(){this.isConfigsChanged&&(this.isConfigsChanged=!1,this.configManager.restore(),this.userOptionsManager.restore())}getArticle(){return this.article}getArticleTitleText(){let e=this.article.getValues(),t;return!l(e.page1Text)&&!l(e.page2Text)?t=`${e.page1Text} \u2192 ${e.page2Text}`:l(e.titleText)?t=p(this.error?"dialog-title-not-found":"dialog-title-empty"):t=e.titleText,l(e.label)?t:`${e.label} (${t})`}getArticleParams(){return this.articleParams}getContainer(){return this.nodes.$container}getDiffTable(){return this.nodes.$table}getInitiatorPage(){return this.options.initiatorPage}getNavigation(){return this.navigation}close(){this.emit("close")}detach(){var e,t;this.isDetached||(mw.hook(`${o.config.prefix}.page.beforeDetach`).fire(this),this.abort(),this.restoreConfigs(),(e=this.getNavigation())==null||e.detach(),(t=this.getContainer())==null||t.detach(),this.isDetached=!0)}};a(Rt,"utils",et);$e=Rt});var as,Ft,ls=v(()=>{T();P();Et();G();Wt();O();as=class i extends $e{constructor(){super(...arguments);a(this,"type","local");a(this,"isDependenciesLoaded",!1);a(this,"onRequestPageError",(t,s,n)=>{this.isDependenciesLoaded=!0;let r={message:t,type:"dependencies",tag:"page",article:this.article,silent:!0};s!=null&&s.error&&(r.code=s.error.code,r.message=s.error.info);let c=n.oldid?"revid":"curid";C(`error-dependencies-${c}`,r)});a(this,"onRequestPageDone",(t,s)=>{if(this.isDependenciesLoaded=!0,this.parse=t==null?void 0:t.parse,!this.parse)return this.onRequestPageError(null,t,s);this.configManager.setValues(f({wgArticleId:this.parse.pageid,wgRevisionId:Math.max(this.article.get("revid"),this.parse.revid)},this.parse.jsconfigvars)),this.article.setValues({curid:this.configManager.get("wgArticleId"),revid:this.configManager.get("wgRevisionId")}),this.setConfigs(),this.processCategories(),this.requestDependencies(this.parse)})}getLoadPromises(){let t=super.getLoadPromises();return this.article.get("type")==="revision"&&(this.article.get("typeVariant")!=="page"&&w(this.article.get("revid"))||this.article.get("typeVariant")==="page"&&w(this.article.get("curid")))&&t.push(this.requestPage()),t}requestPage(){if(this.error)return $.Deferred().resolve().promise();let t={action:"parse",prop:["revid","modules","jsconfigvars","categorieshtml"],disablelimitreport:1,redirects:1,format:"json",formatversion:2,uselang:o.local.userLanguage},s=this.configManager.get("wgDiffNewId")||Math.max(this.article.get("revid"),this.article.get("oldid")),n=this.configManager.get("wgArticleId")||this.article.get("curid");return w(s)?t.oldid=s:w(n)&&(t.pageid=n),this.requestManager.get(t).then(r=>this.onRequestPageDone(r,t)).fail((r,c)=>this.onRequestPageError(r,c,t))}requestProcess(){if(this.error)return $.Deferred().resolve().promise();let t=this.article.getValues(),s={title:l(t.title)?void 0:t.title,diff:l(t.diff)?t.direction:t.diff,oldid:l(t.oldid)?void 0:t.oldid,curid:l(t.curid)?void 0:t.curid},n={url:o.local.mwEndPoint,dataType:"html",data:$.extend(s,this.articleParams)};return this.requestManager.ajax(n)}renderSuccessContent(){return m(this,null,function*(){this.nodes.data=$.parseHTML(this.data),this.nodes.$data=$(this.nodes.data).appendTo(this.nodes.$body),this.collectData(),this.setConfigs(),this.nodes.$data.filter(".cdx-message").prependTo(this.nodes.$body),this.nodes.$data.find(".cdx-message").prependTo(this.nodes.$body);let t=this.nodes.$data.filter("p");t.length>0&&this.renderWarning({$content:t}),this.processMobileFooter(),this.processDiffTable(),this.processFlaggedRevs(),this.article.get("type")==="revision"&&this.processRevision(),yield Oe(i.prototype,this,"renderSuccessContent").call(this)})}collectData(){let t={},s=this.nodes.$data.find("#mw-diff-otitle1 strong > a, #differences-prevlink"),n=this.nodes.$data.find("#mw-diff-ntitle1 strong > a, #differences-nextlink");if(s.length>0){let b=Number(qe("oldid",s.prop("href")));w(b)&&this.configManager.set("wgDiffOldId",b);let x=qe("title",s.prop("href"))||s.prop("title");l(x)||(t.page1=x,t.title=x)}if(n.length>0){let b=Number(qe("oldid",n.prop("href")));w(b)&&(this.configManager.setValues({wgDiffNewId:b,wgRevisionId:b}),t.revid=b,this.article.get("diff")==="cur"&&(t.diff=b));let x=qe("title",n.prop("href"))||n.prop("title");l(x)||(t.page2=x,t.title=x)}t.page1===t.page2&&(delete t.page1,delete t.page2);let r=this.nodes.$data.find("#mw-diff-ntitle2 .mw-userlink");r.length>0&&(t.userhidden=r.hasClass("history-deleted"),t.userhidden||(t.user=r.text()));let c=this.nodes.$data.find("#mw-diff-ntitle1 .mw-diff-timestamp");c.length>0&&(t.timestamp=c.attr("data-timestamp"));let u=this.nodes.$data.find("#mw-diff-ntitle3 .autocomment a");l(this.article.get("section"))&&u.length>0&&(t.section=ee("hash",u.prop("href"))),this.nodes.$data.find(".mw-diff-undo a, .mw-rollback-link a").length>0&&this.configManager.set("wgIsProbablyEditable",!0),this.article.set(t),this.configManager.setTitle(this.article.getMW("title")),this.article.get("type")!=="diff"&&!Pt(this.configManager.get("wgPageContentModel"))&&this.userOptionsManager.set("visualeditor-diffmode-historical","source")}processMobileFooter(){if(this.nodes.$diffMobileFooter=this.nodes.$data.filter(".mw-diff-mobile-footer"),this.nodes.$diffMobileFooter.length===0)return;this.nodes.$diffMobileFooter.appendTo(this.nodes.$body);let t="cdx-button cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--action-default",s=[".mw-diff-undo",".mw-rollback-link"],n=this.nodes.$diffMobileFooter.find(s.join(","));n.length!==0&&(mw.user.isAnon()?n.hide():n.children("a").addClass(t))}processDiffTable(){this.nodes.$diffTablePrefix=this.nodes.$data.filter(".mw-diff-table-prefix"),(this.article.get("type")!=="diff"||!d.get("showDiffTools"))&&this.nodes.$diffTablePrefix.addClass("instantDiffs-hidden"),this.nodes.$table=this.nodes.$data.filter("table.diff"),this.nodes.$prev=this.nodes.$table.find("#differences-prevlink").attr("data-instantdiffs-link","none").addClass("instantDiffs-hidden"),this.nodes.$next=this.nodes.$table.find("#differences-nextlink").attr("data-instantdiffs-link","none").addClass("instantDiffs-hidden");let t=this.nodes.$table.find("#mw-diff-otitle4");Nt(t);let s=this.nodes.$table.find("#mw-diff-ntitle4");Nt(s),this.nodes.$data.filter(".mw-revslider-container, .mw-diff-revision-history-links, #mw-oldid").addClass("instantDiffs-hidden"),this.links.prev=this.article.get("type")==="revision"?w(this.configManager.get("wgDiffOldId")):this.nodes.$prev.attr("href"),this.links.next=this.nodes.$next.attr("href")}processRevision(){this.nodes.$diffTitle=this.nodes.$data.filter(".diff-currentversion-title"),d.get("showRevisionInfo")||this.nodes.$diffMobileFooter.addClass("instantDiffs-hidden"),Xe(this.nodes.$table),this.processCategories(),this.nodes.$data.find(".mw-diff-slot-header, .mw-slot-header").addClass("instantDiffs-hidden")}processFlaggedRevs(){this.nodes.$frDiffHeader=this.nodes.$data.filter("#mw-fr-diff-headeritems").insertBefore(this.nodes.$table),this.nodes.$unpatrolled=this.nodes.$frDiffHeader.find(".fr-diff-to-stable a").attr("data-instantdiffs-link","none").addClass("instantDiffs-hidden"),this.article.get("type")==="diff"&&(this.links.unpatrolled=this.nodes.$unpatrolled.attr("href")),this.article.get("type")==="revision"&&(d.get("showRevisionInfo")?this.nodes.$frDiffHeader.find(".fr-diff-ratings td:nth-child(2n-1)").addClass("instantDiffs-hidden"):this.nodes.$frDiffHeader.addClass("instantDiffs-hidden")),this.nodes.$data.find(".fr-diff-to-stable, #mw-fr-diff-dataform").addClass("instantDiffs-hidden")}processCategories(){l(this.data)||l(this.parse)||l(this.parse.categorieshtml)||(this.nodes.$categories=$(this.parse.categorieshtml).appendTo(this.nodes.$body))}restoreFunctionalityEmbed(){var s;if(this.error)return;en("mediawiki.misc-authed-curate"),Wi(this.nodes.$body);let t=[];if(this.article.get("type")==="diff"&&d.get("showDiffTools")){let n=Ii(this.nodes.$diffTablePrefix);n&&t.push(n);let r=Ri(this.nodes.$diffTablePrefix);r&&t.push(r)}if(((s=this.nodes.$diffTablePrefix)==null?void 0:s.length)>0){let n=this.nodes.$diffTablePrefix.children(":visible").length>0;this.nodes.$diffTablePrefix.toggleClass("instantDiffs-hidden",!n||t.length===0)}if(this.nodes.$wikiLambdaApp=this.nodes.$body.find("#ext-wikilambda-app"),this.nodes.$wikiLambdaApp.length>0){let n=$(be("dialog-notice-wikilambda"));this.renderWarning({$content:n,type:"notice",container:this.nodes.$wikiLambdaApp,insertMethod:"insertBefore"})}}restoreFunctionalityWithDependencies(){this.error||this.nodes.$wikiLambdaApp.length>0&&Ni(this.nodes.$wikiLambdaApp)}fire(){return m(this,null,function*(){this.restoreFunctionalityEmbed(),this.article.get("type")==="revision"&&!this.isDependenciesLoaded&&(yield this.requestPage()),this.restoreFunctionalityWithDependencies(),yield Oe(i.prototype,this,"fire").call(this)})}},Ft=as});var Vo,cs,Vt,fs=v(()=>{T();P();Et();oe();Ie();Ai();H();Wt();ae();({h:Vo}=y),cs=class i extends $e{constructor(t,s){super(t,j(f({},s),{fireDiffHook:!1}));a(this,"type","foreign");a(this,"compare");a(this,"parse");a(this,"linkTags",[]);a(this,"onRequestDone",t=>{this.data=t==null?void 0:t.compare});a(this,"onRequestRevisionError",(t,s,n)=>{let r={message:t,type:"dependencies",tag:"page",article:this.article};s!=null&&s.error&&(r.code=s.error.code,r.message=s.error.info);let c=n.oldid?"revid":"curid";C(`error-dependencies-${c}`,r)});a(this,"onRequestRevisionDone",(t,s)=>m(this,null,function*(){if(this.parse=t==null?void 0:t.parse,!this.parse)return this.onRequestRevisionError(null,t,s);yield this.renderRevision()}))}getLoadPromises(){return[this.requestMessages(),this.requestSiteInfo(),...super.getLoadPromises()]}getLoadSecondaryPromises(){let t=super.getLoadSecondaryPromises();return this.article.get("type")==="revision"&&t.push(this.requestRevision()),t}requestProcess(){let t=this.article.getValues(),s={action:"compare",prop:["title","ids","rel","timestamp","user","diff","parsedcomment"],fromrev:w(t.oldid)?t.oldid:void 0,fromrelative:R(t.oldid)?t.oldid:void 0,torev:w(t.diff)?t.diff:void 0,difftype:ye()?"inline":"table",format:"json",formatversion:2,uselang:o.local.userLanguage};return t.type==="diff"&&!w(t.diff)&&(s.torelative=R(t.diff)?t.diff:"prev"),t.type==="revision"&&!w(t.diff)&&(s.torelative=R(t.direction)?t.direction:"prev"),t.typeVariant==="page"&&w(t.curid)&&(s.fromid=t.curid,s.torelative="cur"),this.requestManager.get(s,this.article)}requestSiteInfo(){return m(this,null,function*(){let t=["general","namespaces","namespacealiases"],s=(yield k.getSiteInfo(t,this.article,this.requestManager))||{};if(!W(s)){let n=s.general;W(n)||(this.article.set({hostname:n.servername}),this.configManager.setValues({wgServer:n.server,wgServerName:n.servername,wgMobileServer:n.mobileserver,wgMobileServerName:n.mobileservername}));let r=ai(this.article.get("hostname"));this.configManager.setValues(r),this.setConfigs()}})}requestMessages(){return m(this,null,function*(){let t=["revisionasof","currentrev-asof","word-separator","pipe-separator","parentheses","talkpagelinktext","contribslink","changeslist-nocomment","rev-deleted-no-diff","rev-deleted-user","rev-deleted-comment","diff-empty","checkuser-userinfocard-toggle-button-aria-label"];yield k.loadMessage(t)})}renderContent(){return m(this,null,function*(){this.renderForeignWarning(),yield Oe(i.prototype,this,"renderContent").call(this)})}renderSuccessContent(){return m(this,null,function*(){this.collectData(),this.setConfigs(),yield this.renderDiffTable(),this.requestDependencies()})}collectData(){this.configManager.setValues({wgArticleId:this.data.toid,wgRevisionId:this.data.torevid,wgDiffOldId:this.data.fromrevid,wgDiffNewId:this.data.torevid});let t=$("<span>").html(this.data.fromparsedcomment).find(".autocomment a");t.length>0&&(this.data.fromsection=ee("hash",t.prop("href")));let s=$("<span>").html(this.data.toparsedcomment).find(".autocomment a");s.length>0&&(this.data.tosection=ee("hash",s.prop("href")));let n={previd:this.data.prev,nextid:this.data.next,curid:this.configManager.get("wgArticleId"),revid:this.configManager.get("wgRevisionId"),title:ge(this.data),section:this.data.tosection,timestamp:this.data.totimestamp,user:this.data.touser,userhidden:this.data.touserhidden};this.data.fromid!==this.data.toid&&(n.page1=this.data.fromtitle,n.page2=this.data.totitle),this.article.set(n),this.configManager.setTitle(this.article.getMW("title")),this.links.prev=this.article.get("type")==="revision"?w(this.data.fromrevid):this.data.prev&&this.data.prev!==this.data.fromrevid,this.links.next=this.data.next&&this.data.next!==this.data.torevid}renderDiffTable(){return m(this,null,function*(){if(this.nodes.table=Ci(this.data.body),(this.data.fromtexthidden||this.data.totexthidden)&&(yield this.renderDeletedWarning()),this.data.fromid){let t=St({prefix:"o",title:this.data.fromtitle,revid:this.data.fromrevid,curRevid:this.article.get("curRevid"),hostname:this.article.get("hostname"),timestamp:this.data.fromtimestamp,texthidden:this.data.fromtexthidden,user:this.data.fromuser,userhidden:this.data.fromuserhidden,comment:this.data.fromparsedcomment,commenthidden:this.data.fromcommenthidden});N(t,this.nodes.table.deleted)}else this.nodes.table.added.colSpan=4,this.nodes.table.deleted.classList.add("instantDiffs-hidden");if(this.data.toid){let t=St({prefix:"n",title:this.data.totitle,revid:this.data.torevid,curRevid:this.article.get("curRevid"),hostname:this.article.get("hostname"),timestamp:this.data.totimestamp,texthidden:this.data.totexthidden,user:this.data.touser,userhidden:this.data.touserhidden,comment:this.data.toparsedcomment,commenthidden:this.data.tocommenthidden});N(t,this.nodes.table.added)}else this.nodes.table.deleted.colSpan=4,this.nodes.table.added.classList.add("instantDiffs-hidden");if(this.nodes.$table=$(this.nodes.table.container).appendTo(this.nodes.$body),te(this.nodes.$table,`https://${this.article.get("hostname")}`),this.article.get("type")==="revision"&&Xe(this.nodes.$table),this.data.toid){let t=Oi({title:this.data.totitle,revid:this.data.torevid,hostname:this.article.get("hostname"),user:this.data.touser,userhidden:this.data.touserhidden});N(t,this.nodes.$body,"appendTo")}})}renderErrorContent(){return m(this,null,function*(){var r,c;((r=this.errorData)==null?void 0:r.code)==="missingcontent"?yield this.renderDeletedWarning():yield Oe(i.prototype,this,"renderErrorContent").call(this);let t=this.article.getValues(),s=((c=this.errorData)==null?void 0:c.code)==="missingcontent"?this.errorData.info.replace(/\D/g,""):null,n=[t.oldid,t.diff,s].filter(u=>!isNaN(u)&&u>0);this.configManager.setValues({wgDiffOldId:Math.min(...n),wgDiffNewId:Math.max(...n)}),this.setConfigs(),this.configManager.get("wgDiffOldId")!==this.configManager.get("wgDiffNewId")&&(this.links.prev=w(this.configManager.get("wgDiffOldId")),this.links.next=w(this.configManager.get("wgDiffNewId"))),this.options.initiatorPage=A.getPreviousPage()})}renderForeignWarning(){let t=$(be(`dialog-notice-foreign-${this.article.get("type")}`,`https://${this.article.get("hostname")}`,this.article.get("hostname")));this.nodes.$foreignWarning=this.renderWarning({$content:t,type:"notice"})}renderDeletedWarning(){return m(this,null,function*(){let t=yield k.parseWikitext({title:this.article.get("title"),text:mw.msg("rev-deleted-no-diff")},this.article),s=$(t).find("p");this.nodes.$deleteWarning=this.renderWarning({$content:s,type:"warning",container:this.nodes.$foreignWarning,insertMethod:"insertAfter"})})}requestRevision(){if(this.error)return $.Deferred().resolve().promise();let t={action:"parse",prop:["text","revid","modules","jsconfigvars","categorieshtml"],disablelimitreport:1,redirects:1,format:"json",formatversion:2,uselang:o.local.userLanguage},s=Math.max(this.article.get("revid"),this.article.get("oldid")),n=this.article.get("curid");return w(s)?t.oldid=s:w(n)&&(t.pageid=n),this.requestManager.get(t,this.article).then(r=>this.onRequestRevisionDone(r,t)).fail((r,c)=>this.onRequestRevisionError(r,c,t))}renderRevision(){return m(this,null,function*(){this.configManager.setValues(f({wgArticleId:this.parse.pageid,wgRevisionId:Math.max(this.article.get("revid"),this.parse.revid)},this.parse.jsconfigvars)),this.article.setValues({curid:this.configManager.get("wgArticleId"),revid:this.configManager.get("wgRevisionId")}),this.setConfigs();let t=this.article.get("revid")===this.article.get("curRevid")?"currentrev-asof":"revisionasof";this.nodes.diffTitle=Vo("h2",{class:"diff-currentversion-title"},mw.msg(t,Ye(this.data.totimestamp))),this.nodes.$diffTitle=$(this.nodes.diffTitle).appendTo(this.nodes.$body),this.nodes.$revision=$(this.parse.text).appendTo(this.nodes.$body),l(this.parse.categorieshtml)||(this.nodes.$categories=$(this.parse.categorieshtml).appendTo(this.nodes.$body)),yield this.processRevision(),te(this.nodes.$body,this.article.get("href")),this.requestDependencies(this.parse),this.requestForeignDependencies()})}processRevision(){return m(this,null,function*(){if(this.nodes.$body.find("#ext-wikilambda-app, .ext-wikilambda-view-nojsfallback, .mw-diff-slot-header, .mw-slot-header").addClass("instantDiffs-hidden"),this.nodes.$wikiLambdaApp=this.nodes.$body.find("#ext-wikilambda-app"),this.nodes.$wikiLambdaApp.length>0){let t=$(`<p>${p("dialog-notice-foreign-wikilambda")}</p>`);this.renderWarning({$content:t,type:"notice",container:this.nodes.$wikiLambdaApp,insertMethod:"insertBefore"})}yield this.restoreFunctionality()})}requestForeignDependencies(){let t=ui(this.article);hi(this.article,t.modules),pi(this.article,t.styles),this.linkTags=gi(t.links)}detach(){this.isDetached||(super.detach(),mi(this.linkTags))}},Vt=cs});var xn=v(()=>{});var st,Dn,Ln=v(()=>{G();st=class extends OO.ui.LabelWidget{constructor(){super({classes:["oo-ui-messageDialog-message","is-transparent"]})}toggleVisibility(e){this.$element.toggleClass("is-transparent",!e)}};a(st,"tagName","div");K(st);Dn=st});var qt,Sn,Pn=v(()=>{P();G();qt=class extends OO.ui.ProgressBarWidget{constructor(t){super(f({classes:["instantDiffs-view-loader","is-transparent"],progress:!1,inline:!0},t));a(this,"toggleDelay");a(this,"toggleTime")}toggleVisibility(t,s){if(this.toggleDelay&&clearTimeout(this.toggleDelay),s&&(this.toggle(t),jt(()=>this.$element.toggleClass("is-transparent",!t))),t===!0&&(this.toggleTime=Date.now(),this.toggle(!0),jt(()=>this.$element.removeClass("is-transparent"))),t===!1){if(!this.isVisible())return;let n=this.calculateRemainingTime(this.toggleTime,1e3),r=Math.max(n-150,0);this.toggleDelay=setTimeout(()=>{this.$element.addClass("is-transparent"),this.toggleDelay=setTimeout(()=>this.toggle(!1),150)},r)}}calculateRemainingTime(t,s=1e3){let r=(Date.now()-t)%s;return s-r}};K(qt);Sn=qt});var En={};Q(En,{default:()=>qo});var Ae,qo,$n=v(()=>{P();G();Ln();Pn();O();Ae=class extends OO.ui.MessageDialog{constructor(){super({classes:["instantDiffs-view"]})}initialize(){return super.initialize(),this.message.$element.remove(),this.message=new Dn,this.text.$element.append(this.message.$element),this.$content.removeAttr("tabindex"),this.container.$element.attr("tabindex","-1"),d.get("closeOutside")&&(this.$clickOverlay=$("<div>").on("click",()=>this.close()).addClass("instantDiffs-view-overlay").appendTo(this.$element)),this.progressBar=new Sn,this.$content.prepend(this.progressBar.$element),this}getSetupProcess(e){return super.getSetupProcess(e).next(()=>{Xs(),this.scrollContentTop(0),this.focus()})}onDialogKeyDown(e){super.onDialogKeyDown(e),!ds()&&this.emit("hotkey",e)}getBodyHeight(){return"auto"}update(e){return this.getUpdateProcess(e).execute()}getUpdateProcess(e){return new OO.ui.Process().next(()=>{e=f({title:this.constructor.static.title,message:this.constructor.static.message,scrollTop:0},e),this.toggleProgress(!1),this.title.setLabel(e.title),this.message.setLabel(e.message),this.scrollContentTop(L(e.scrollTop)?e.scrollTop():e.scrollTop),this.toggleVisibility(!0),this.focus()})}getTeardownProcess(e){return super.getTeardownProcess(e).next(()=>{this.toggleProgress(!1),this.toggleVisibility(!1)})}focus(e){return e?super.focus(e):this.container.$element.trigger("focus"),this}toggleVisibility(e){return this.message.toggleVisibility(e),this}toggleProgress(...e){return this.progressBar.toggleVisibility(...e),this}getContentOffsetTop(e,t=0){var n;let s=0;if((nt(e)||e instanceof jQuery)&&(s=(n=Bt(e,this.container.$element))==null?void 0:n.top),typeof s=="number")return s+t}setScrollOffsetTop(e=0){return this.container.$element.css("--instantDiffs-view-scroll-padding-top",`${e}px`),this}scrollContentTop(e=0,t=0){var n;let s=0;return typeof e=="number"&&(s=e),(nt(e)||e instanceof jQuery)&&(s=(n=Bt(e,this.container.$element))==null?void 0:n.top),typeof s=="number"&&this.container.$element.scrollTop(s+t),this}};a(Ae,"name","Instant Diffs Window"),a(Ae,"size","instantDiffs"),a(Ae,"actions",[{action:"close",label:p("action-close"),title:_("action-close","close")}]);K(Ae);qo=Ae});var Ut,A,ae=v(()=>{T();P();G();Ne();$i();ls();fs();O();xn();Ut=class{constructor(){a(this,"link");a(this,"page");a(this,"options",{});a(this,"opener",{link:null,options:{}});a(this,"initiator",{link:null,options:{}});a(this,"previousInitiator",{link:null,options:{}});a(this,"document",{});a(this,"loadPromise");a(this,"isDependenciesLoaded",!1);a(this,"isConstructed",!1);a(this,"isOpen",!1);a(this,"isLoading",!1);a(this,"isRequesting",!1);a(this,"isProcessing",!1)}static getSize(e){return this.sizes[e]}mixin(){OO.EventEmitter.call(this)}setup(e,t){var s,n;if(this.isRequesting||this.isProcessing)return!1;if(o.timers.dialogProcesStart=mw.now(),this.link=e,this.options=f({initiatorPage:null,onOpen:()=>{},onClose:()=>{}},t),!this.isOpen){this.opener.link=this.link,this.opener.options=f({},this.options);let r={};(n=(s=this.opener.link).getMW)!=null&&n.call(s).hasLine&&(r.filterType=this.opener.link.getArticle().get("type"),r.filterMWLine=!0),Se.newInstance(r)}if(this.link instanceof I){let r=this.link.getInitiatorLink();Se.instance.hasLink(r)&&(this.previousInitiator=f({},this.initiator),this.initiator.link=r,this.initiator.options=f({},this.options),Se.instance.setLink(this.initiator.link))}return!0}load(){return this.isLoading?this.loadPromise:this.isDependenciesLoaded?(this.open(),!0):(this.isLoading=!0,this.error=null,this.loadPromise=$.when(mw.loader.using(this.getDependencies())).then(this.onLoadSuccess.bind(this)).fail(this.onLoadError.bind(this)),this.loadPromise)}getDependencies(){return we([...o.config.dependencies.window,...o.config.dependencies.content])}onLoadError(e){this.isLoading=!1,this.isDependenciesLoaded=!1,this.error={type:"dependencies",tag:"view",message:e&&e.message?e.message:null},C("error-dependencies-generic",this.error)}onLoadSuccess(){this.isLoading=!1,this.isDependenciesLoaded=!0,mt(),this.open()}construct(){this.isConstructed=!0;let e=($n(),Me(En)).default;this.dialog=new e,this.dialog.connect(this,{hotkey:t=>this.emit("hotkey",t)}),this.manager=wt(),this.manager.addWindows([this.dialog])}open(){if(this.isConstructed||this.construct(),!this.isOpen){this.document.scrollableRoot=OO.ui.Element.static.getRootScrollableElement(document.body),this.document.scrollTop=this.document.scrollableRoot.scrollTop;let e=this.link.getArticle(),t={title:e.get("titleText")||e.get("title"),size:vi()};this.windowInstance=this.manager.openWindow(this.dialog,t),this.windowInstance.opening.then(this.onOpening.bind(this)),this.windowInstance.opened.then(this.onOpen.bind(this)),this.windowInstance.closing.then(this.onClosing.bind(this)),this.windowInstance.closed.then(this.onClose.bind(this))}this.request()}onOpening(){this.emit("opening")}onOpen(){this.isOpen=!0,L(this.options.onOpen)&&this.options.onOpen(this),this.emit("opened")}onClosing(){this.emit("closing")}onClose(){this.isOpen=!1,this.isRequesting=!1,this.isProcessing=!1,this.previousPage&&(this.previousPage.detach(),this.previousPage=null),this.page&&(this.page.detach(),this.page=null),L(this.options.onClose)&&this.options.onClose(this),L(this.opener.options.onClose)&&this.opener.link!==this.link&&this.opener.options.onClose(this),L(this.initiator.options.onClose)&&this.initiator.link!==this.link&&this.initiator.options.onClose(this),this.opener={link:null,options:{}},this.initiator={link:null,options:{}},this.previousInitiator={link:null,options:{}},this.document.scrollableRoot.scrollTop=this.document.scrollTop,this.emit("closed")}onUpdate(){this.fire(),this.previousInitiator.link instanceof I&&this.opener.link!==this.previousInitiator.link&&L(this.previousInitiator.options.onClose)&&this.previousInitiator.options.onClose(this),this.initiator.link instanceof I&&this.opener.link!==this.initiator.link&&L(this.initiator.options.onOpen)&&this.initiator.options.onOpen(this),this.emit("updated")}request(){var r,c;this.isRequesting=!0,this.isProcessing=!0,this.error=null,this.previousPage=this.page,this.dialog.toggleProgress(!0),this.previousPage&&this.previousPage.restoreConfigs();let e=this.link.getArticle(),t={initiatorAction:(c=(r=this.previousPage)==null?void 0:r.getNavigation())==null?void 0:c.getActionRegister(),initiatorPage:this.options.initiatorPage},s=e.get("hostname"),n=re(s)?Vt:Ft;this.page=new n(e,t),this.page.connect(this,{focus:"focus",close:"close"}),$.when(this.page.load()).always(this.onRequestResponse.bind(this))}onRequestResponse(){if(this.isRequesting=!1,!this.page||this.page.isDetached)return;let e={title:this.page.getArticleTitleText(),message:this.page.getContainer(),scrollTop:this.getContentOffset.bind(this)};this.dialog.update(e).then(this.onUpdate.bind(this))}refresh(){return this.isRequesting||this.isProcessing?!1:(o.timers.dialogProcesStart=mw.now(),this.load())}fire(){this.previousPage&&this.previousPage.detach(),$.when(this.page.fire()).always(()=>{this.setContentOffset(),o.timers.dialogProcesEnd=mw.now(),d.get("logTimers")&&ve("dialog process time",o.timers.dialogProcesStart,o.timers.dialogProcesEnd),this.isProcessing=!1})}focus(){this.dialog.focus()}close(){this.dialog.close()}getContentOffset(){let e=this.page.getScrollableSection(),t=this.page.getScrollableOffsetTop();return this.dialog.getContentOffsetTop(e,-t)}setContentOffset(){let e=this.page.getArticle();e&&e.get("type")==="revision"&&(this.dialog.setScrollOffsetTop(this.page.getScrollableOffsetTop()),this.dialog.scrollContentTop(this.getContentOffset()))}getLink(){return this.link}getPage(){return this.page}getPreviousPage(){return this.previousPage}getDialog(){return this.dialog}isContains(e){var t;return(t=this.dialog)==null?void 0:t.$content.get(0).contains(e)}};a(Ut,"sizes",{compact:{width:800,height:"auto"},standard:{width:1200,height:"auto"},wide:{width:1600,height:"auto"}});A=new Ut});function jo(){An.call(this,this.getField("linksFormat"))}function An(){let i=this.getFieldValue("linksHash"),e=this.getFieldValue("linksFormat"),s=Cn({relative:!1,hash:i,minify:e==="minify"});this.setFieldHelp("linksFormat",s),Tn.call(this,this.getField("wikilinksFormat"))}function Tn(){let i=this.getFieldValue("linksHash"),e=this.getFieldValue("linksFormat"),t=this.getFieldValue("wikilinksFormat"),n=Cn({relative:!1,hash:i,minify:e==="minify",wikilink:!0,wikilinkPreset:t});this.setFieldHelp("wikilinksFormat",n)}function Cn(i){let e=p("copy-wikilink-example-title"),t=q({title:e,diff:"12345",type:"diff",section:"Section"},{},i),s=q({title:e,oldid:"12345",type:"revision",section:"Section"},{},i),n=q({title:e,curid:"12345",type:"revision",typeVariant:"page",section:"Section"},{},i);return Te("ul.instantDiffs-list--settings",Te("li",Te("i",t)),Te("li",Te("i",s)),Te("li",Te("i",n)))}function Bo(){var n,r;let i=(r=(n=A.getPage())==null?void 0:n.getNavigation())==null?void 0:r.getPinnableActions();if(!i)return{};let e=new Set,t=i.map(c=>(e.add(c.name),[c.name,{label:c.label}]));return(d.get("pinnedActions")||[]).forEach(c=>{e.has(c)||t.push([c,{label:c,show:!1}])}),Object.fromEntries(t)}var Te,ot,us=v(()=>{P();oe();ae();O();H();({h:Te}=y),ot={general:{config:{labelMsg:"settings-fieldset-general"},fields:{enableMobile:{type:"checkbox",enabled:!0,enabledCondition:()=>m(null,null,function*(){return k.siteInfoHasSkin("minerva")}),default:!0,config:{labelMsg:"settings-enable-mobile",helpMsg:"settings-enable-mobile-help"}},notifyErrors:{type:"checkbox",enabled:!0,default:!0,config:{labelMsg:"settings-notify-errors"}}}},links:{config:{labelMsg:"settings-fieldset-links"},fields:{showLink:{type:"checkbox",enabled:!0,default:!1,config:{labelMsg:"settings-show-link",helpMsg:"settings-show-link-help"}},showPageLink:{type:"checkbox",enabled:!0,default:!0,config:{labelMsg:"settings-show-page-link",helpMsg:"settings-show-page-link-help"}},highlightLine:{type:"checkbox",enabled:!0,default:!0,config:{labelMsg:"settings-highlight-line"}},markWatchedLine:{type:"checkbox",enabled:!0,default:!0,config:{labelMsg:"settings-mark-watched-line"}}}},dialog:{config:{labelMsg:"settings-fieldset-dialog"},fields:{viewWidth:{type:"buttonSelect",enabled:!0,default:"standard",config:{labelMsg:"settings-view-width",helpMsg:"settings-view-width-help"},optionsType:"buttonOption",options:{compact:{labelMsg:"settings-view-width-compact",titleMsg:["settings-view-width-option-title",A.constructor.getSize("compact").width]},standard:{labelMsg:"settings-view-width-standard",titleMsg:["settings-view-width-option-title",A.constructor.getSize("standard").width]},wide:{labelMsg:"settings-view-width-wide",titleMsg:["settings-view-width-option-title",A.constructor.getSize("wide").width]},full:{labelMsg:"settings-view-width-full",titleMsg:"settings-view-width-full-title"}}},closeOutside:{type:"checkbox",enabled:!0,default:!0,config:{labelMsg:"settings-close-outside"}},enableHotkeys:{type:"checkbox",enabled:!0,default:!0,config:{labelMsg:"settings-enable-hotkeys"}},showDiffTools:{type:"checkbox",enabled:!0,default:!0,config:{labelMsg:"settings-show-diff-tools"}},showRevisionInfo:{type:"checkbox",enabled:!0,default:!0,config:{labelMsg:"settings-show-revision-info"}},unHideDiffs:{type:"checkbox",enabled:!0,default:!0,config:{labelMsg:"settings-unhide-diffs",helpMsg:["settings-unhide-diffs-help","suppressrevision"]}},openInNewTab:{type:"checkbox",enabled:!0,default:!0,config:{labelMsg:"settings-open-in-new-tab"}}}},menu:{config:{labelMsg:"settings-fieldset-menu"},fields:{showMenuIcons:{type:"checkbox",enabled:!0,default:!0,config:{labelMsg:"settings-show-menu-icons"}},showWatchlistPopup:{type:"checkbox",enabled:!0,default:!0,config:{labelMsg:"settings-show-watchlist-popup",helpMsg:"settings-show-watchlist-popup-help"}},linksHash:{type:"checkbox",enabled:!0,default:!1,config:{labelMsg:"settings-links-hash",helpMsg:"settings-links-hash-help"},onChange:jo},linksFormat:{type:"radioSelect",enabled:!0,default:"full",config:{labelMsg:"settings-links-format",helpMsg:"placeholder"},optionsType:"radioOption",options:{full:{labelMsg:"settings-links-format-full"},minify:{labelMsg:"settings-links-format-minify"}},onSelect:An},wikilinksFormat:{type:"radioSelect",enabled:!0,default:"special",config:{labelMsg:"settings-wikilinks-format",helpMsg:"placeholder"},optionsType:"radioOption",options:{link:{labelMsg:"settings-wikilinks-format-link"},special:{labelMsg:"settings-wikilinks-format-special"}},onSelect:Tn}}},pinnedActions:{config:{labelMsg:"settings-fieldset-pinned-actions"},fields:{pinnedActions:{type:"checkboxMultiselect",enabled:!0,default:["copyLink"],config:{labelMsg:"settings-pinned-actions",helpMsg:"settings-pinned-actions-help"},optionsType:"checkboxMultioption",options:Bo}}}}});var ws={};Q(ws,{getQueryDefaults:()=>ms,getSchemaDefaults:()=>gs,getSchemaSettings:()=>ps,renderNoticeBox:()=>Ht});function ps(){let e=Object.values(ot).flatMap(t=>Object.entries(t.fields)).map(([t,s])=>[t,s.enabled]);return Object.fromEntries(e)}function gs(){let e=Object.values(ot).flatMap(t=>Object.entries(t.fields)).map(([t,s])=>[t,s.default]);return Object.fromEntries(e)}function ms(){var t,s;let i=((s=bs((t=document.currentScript)==null?void 0:t.src))==null?void 0:s.instantdiffs)||{},e=Object.entries(i).map(([n,r])=>[n,r==="true"?!0:r==="false"?!1:r]);return Object.fromEntries(e)}function Ht(i){i=f({modifiers:[],content:null,image:null,alt:null},i);let e=["instantDiffs-notice-box"];return i.modifiers.forEach(t=>e.push(`instantDiffs-notice-box--${t}`)),hs("div",{class:e},hs("img",{src:`${o.config.commonsAssetsPath}${i.image}`,alt:i.alt}),hs("h5",i.content))}var hs,Gt=v(()=>{T();P();us();({h:hs}=y)});var Mn=v(()=>{});var On={};Q(On,{default:()=>Uo});var Ce,Uo,In=v(()=>{T();P();G();Gt();us();O();Ce=class extends OO.ui.ProcessDialog{constructor(){super({classes:["instantDiffs-settings"]});a(this,"panels",{});a(this,"tabs",{});a(this,"visibleTabWidgets",[]);a(this,"fields",{});a(this,"onActionRequestError",(t,s)=>{let n={type:"settings",message:t};s!=null&&s.error&&(n.code=s.error.code,n.message=s.error.info);let r=new OO.ui.Error(fe("error-setting-request",n),{recoverable:!0});this.showErrors(r)});a(this,"onActionRequestSuccess",t=>{var n,r;if(o.local.mwIsAnon)return this.update();let s=(r=(n=t==null?void 0:t.query)==null?void 0:n.userinfo)==null?void 0:r.options;if(!s)return this.onActionRequestError(null,t);try{let c=JSON.parse(s[`${o.config.settingsPrefix}-settings`]);d.set(c,!0)}catch(c){}this.update()});a(this,"onActionSaveError",(t,s)=>{let n={type:"settings",message:t};s!=null&&s.error&&(n.code=s.error.code,n.message=s.error.info);let r=new OO.ui.Error(fe("error-setting-save",n),{recoverable:!0});this.showErrors(r)});a(this,"onActionSaveSuccess",()=>{this.setPanel("finish")})}initialize(...t){super.initialize(...t),this.panels.edit=this.renderEditPanel(),this.panels.finish=this.renderFinishPanel(),this.panels.empty=this.renderEmptyPanel(),this.stackLayout=new OO.ui.StackLayout({items:[this.panels.edit,this.panels.finish,this.panels.empty]}),this.$body.append(this.stackLayout.$element)}renderEditPanel(){return new OO.ui.PanelLayout({classes:["instantDiffs-settings-panel","instantDiffs-settings-panel--edit"],padded:!1,expanded:!0})}renderFinishPanel(){return new OO.ui.PanelLayout({classes:["instantDiffs-settings-panel","instantDiffs-settings-panel--finish"],padded:!0,expanded:!0})}renderEmptyPanel(){return new OO.ui.PanelLayout({classes:["instantDiffs-settings-panel","instantDiffs-settings-panel--empty"],padded:!0,expanded:!0})}setPanel(t){this.panels[t]&&(this.actions.setMode(t),this.stackLayout.setItem(this.panels[t]))}renderContents(){return m(this,null,function*(){yield this.renderEditContent(),this.renderFinishContent(),this.renderEmptyContent(),this.processLinksAttr(this.stackLayout.$element)})}renderEditContent(){return m(this,null,function*(){for(let[s,n]of Object.entries(ot))this.tabs[s]=yield this.renderTab(s,n);this.visibleTabWidgets=Object.values(this.tabs).map(s=>s.tab).filter(s=>s.isVisible());let t=new OO.ui.IndexLayout({expanded:!0,framed:!1});t.addTabPanels(this.visibleTabWidgets,0),this.panels.edit.$element.empty().append(t.$element)})}renderFinishContent(){let s=Ht({image:"/6/6f/Eo_circle_light-green_checkmark.svg",content:p("settings-saved"),alt:p("settings-saved-icon")});this.panels.finish.$element.empty().append(s)}renderEmptyContent(){let t=["/2/2f/Cappuccino.svg","/c/ca/Coffe.svg","/9/9a/Coffee_cup_icon.svg","/1/1a/Applications-ristretto.svg","/f/f7/Cup-o-coffee-simple.svg"],s=Math.floor(Math.random()*t.length),n=t[s]||t[0],r=Ht({image:n,content:p("settings-empty"),alt:p("settings-empty-icon"),modifiers:["empty"]});this.panels.empty.$element.empty().append(r)}renderTab(t,s){return m(this,null,function*(){s=ie({name:t,fields:{},fieldset:null,tab:null,config:{label:null}},s),s.config=this.validateFieldConfig(s.config);for(let[c,u]of Object.entries(s.fields))this.fields[c]=s.fields[c]=yield this.renderField(c,u);let n=Object.values(s.fields).map(c=>c.field);s.fieldset=new OO.ui.FieldsetLayout().addItems(n);let r=Object.keys(s.fields).some(c=>this.fields[c].enabled);return s.tab=new OO.ui.TabPanelLayout(s.name,j(f({},s.config),{content:[s.fieldset]})).toggle(r),s})}renderField(t,s){return m(this,null,function*(){s=ie({name:t,type:null,input:null,field:null,config:{label:null,align:"inline",help:null,helpInline:!0},optionsType:null,options:{},onSelect:()=>{},onChange:()=>{}},s),s.enabled=yield this.checkField(t,s),s.config=this.validateFieldConfig(s.config),L(s.options)&&(s.options=s.options.call(this,s));for(let[r,c]of Object.entries(s.options))s.options[r]=this.renderInputOption(r,c,s.optionsType);let n=Object.values(s.options).map(r=>r.option);switch(s.type){case"checkbox":s.input=new OO.ui.CheckboxInputWidget;break;case"radioSelect":s.input=new OO.ui.RadioSelectWidget({items:n});break;case"buttonSelect":s.input=new OO.ui.ButtonSelectWidget({items:n});break;case"checkboxMultiselect":s.input=new OO.ui.CheckboxMultiselectWidget({items:n});break}return L(s.onSelect)&&s.input.on("select",()=>s.onSelect.call(this,s)),L(s.onChange)&&s.input.on("change",()=>s.onChange.call(this,s)),s.field=new OO.ui.FieldLayout(s.input,s.config).toggle(s.enabled),s})}checkField(t,s){return m(this,null,function*(){return d.check(t)?L(s.enabledCondition)?yield s.enabledCondition(t,s):!0:!1})}renderInputOption(t,s,n){switch(s=ie({name:t,type:n,data:t,option:null,show:!0},s),s=this.validateFieldConfig(s),s.type){case"radioOption":s.option=new OO.ui.RadioOptionWidget(s);break;case"buttonOption":s.option=new OO.ui.ButtonOptionWidget(s);break;case"checkboxMultioption":s.option=new OO.ui.CheckboxMultioptionWidget(s);break}return s.option.toggle(s.show),s}validateFieldConfig(t){return[{key:"labelMsg",target:"label",useDom:!0},{key:"titleMsg",target:"title",useDom:!1},{key:"helpMsg",target:"help",useDom:!0}].forEach(({key:n,target:r,useDom:c})=>{let u=t[n];if(!u)return;let h=c?be:p;t[r]=Array.isArray(u)?h(...u):h(u)}),t}getField(t){return this.fields[t]}getFields(){return this.fields}getFieldValue(t){var n;let s=this.getField(t);if(s){if(["checkbox"].includes(s.type))return s.input.isSelected();if(["radioSelect","buttonSelect"].includes(s.type))return(n=s.input.findFirstSelectedItem())==null?void 0:n.getData();if(["checkboxMultiselect"].includes(s.type))return s.input.findSelectedItemsData()}}getFieldValues(){let t={};for(let[s]of Object.entries(this.fields))t[s]=this.getFieldValue(s);return t}setFieldValue(t,s){let n=this.getField(t);if(n)return["checkbox"].includes(n.type)&&n.input.setSelected(s),["radioSelect","buttonSelect"].includes(n.type)&&n.input.selectItemByData(s),["checkboxMultiselect"].includes(n.type)&&n.input.selectItemsByData(s),this}setFieldHelp(t,s){let n=this.getField(t);if(n)return n.field.$help.empty().append(s),this}setFieldDisabled(t,s){let n=this.getField(t);if(n)return n.input.setDisabled(s),this}getSetupProcess(t){return super.getSetupProcess(t).next(()=>m(this,null,function*(){this.$body.scrollTop(0),yield this.processActionRequest()}))}getActionProcess(t){return t==="save"?new OO.ui.Process(()=>this.processActionSave()):t==="reload"?new OO.ui.Process(()=>this.processActionReload()):t==="close"?new OO.ui.Process(()=>this.close()):super.getActionProcess(t)}processLinksAttr(t){t.find("a:not(.jquery-confirmable-element)").each((n,r)=>r.setAttribute("target","_blank")),te(t,o.config.origin)}getBodyHeight(){return 500}processActionRequest(){return m(this,null,function*(){this.pushPending(),yield this.renderContents(),this.setPanel(this.visibleTabWidgets.length>0?"edit":"empty");for(let[t]of Object.entries(this.fields))this.setFieldDisabled(t,!0);d.request().then(this.onActionRequestSuccess).fail(this.onActionRequestError).always(()=>this.popPending())})}update(){return this.getUpdateProcess().execute()}getUpdateProcess(){return new OO.ui.Process(()=>{this.setPanel(this.visibleTabWidgets.length>0?"edit":"empty"),this.processActionUpdate(d.get())})}processActionUpdate(t){this.popPending();for(let[s]of Object.entries(this.fields)){this.setFieldDisabled(s,!1);let n=t[s];typeof n!="undefined"&&this.setFieldValue(s,n)}}processActionSave(){this.pushPending(),d.save(this.getFieldValues()).then(this.onActionSaveSuccess).fail(this.onActionSaveError).always(()=>this.popPending())}processActionReload(){this.pushPending(),window.location.reload()}};a(Ce,"name","Instant Diffs Settings"),a(Ce,"title",p("settings-title")),a(Ce,"actions",[{action:"save",modes:"edit",label:p("action-save"),flags:["primary","progressive"]},{action:"reload",modes:"finish",label:p("action-reload"),flags:["primary","progressive"]},{action:"close",modes:"empty",label:p("action-close"),flags:["primary","progressive"]},{modes:["edit","finish","empty"],label:p("action-close"),title:p("action-close"),invisibleLabel:!0,icon:"close",flags:["safe","close"]}]);K(Ce);Uo=Ce});var _t,d,O=v(()=>{T();P();Gt();G();H();Mn();_t=class{constructor(){a(this,"loadPromise");a(this,"isDependenciesLoaded",!1);a(this,"isConstructed",!1);a(this,"isOpen",!1);a(this,"isLoading",!1);a(this,"isRequesting",!1);a(this,"isSaving",!1);a(this,"onLoadError",e=>{this.isLoading=!1,this.isDependenciesLoaded=!1,this.error={type:"dependencies",tag:"settings",message:e==null?void 0:e.message},C("error-dependencies-generic",this.error)});a(this,"onLoadSuccess",()=>{this.isLoading=!1,this.isDependenciesLoaded=!0,mt(),this.open()});a(this,"onOpening",()=>{this.emit("opening")});a(this,"onOpen",()=>{this.isOpen=!0,this.emit("opened")});a(this,"onClosing",()=>{this.emit("closing")});a(this,"onClose",()=>{this.isOpen=!1,this.emit("closed")});a(this,"onRequestResponse",()=>{this.isRequesting=!1});a(this,"onSaveResponse",()=>{this.isSaving=!1})}mixin(){OO.EventEmitter.call(this)}load(){return this.isLoading?this.loadPromise:this.isDependenciesLoaded?(this.open(),!0):(this.isLoading=!0,this.error=null,this.loadPromise=$.when(mw.loader.using(we(o.config.dependencies.settings))).then(this.onLoadSuccess).fail(this.onLoadError),this.loadPromise)}construct(){this.isConstructed=!0;let e=(In(),Me(On)).default;this.dialog=new e,this.manager=wt(),this.manager.addWindows([this.dialog])}open(){this.isOpen||(this.isConstructed||this.construct(),this.windowInstance=this.manager.openWindow(this.dialog),this.windowInstance.opening.then(this.onOpening),this.windowInstance.opened.then(this.onOpen),this.windowInstance.closing.then(this.onClosing),this.windowInstance.closed.then(this.onClose))}request(){if(o.local.mwIsAnon)return $.Deferred().resolve().promise();this.isRequesting=!0;let e={action:"query",meta:"userinfo",uiprop:"options",format:"json",formatversion:2,uselang:o.local.userLanguage};return k.post(e).always(this.onRequestResponse)}save(e){return this.set(e,!0),o.local.mwIsAnon?$.Deferred().resolve().promise():(this.isSaving=!0,we(["ext.GlobalPreferences.global"]).length>0?this.saveGlobal(e):this.saveLocal(e))}saveLocal(e){let t=[`${o.config.settingsPrefix}-settings`,JSON.stringify(e)],s=k.getApi();return s.saveOption.apply(s,t).always(this.onSaveResponse)}saveGlobal(e){let t={action:"globalpreferences",optionname:`${o.config.settingsPrefix}-settings`,optionvalue:JSON.stringify(e)};return k.getApi().postWithEditToken(t).always(this.onSaveResponse)}get(e,t){if(t){let s=Object.entries(o.local.defaults).filter(([r])=>r in o.config.settings),n=Object.fromEntries(s);return e?n[e]:n}return e?o.local.defaults[e]:o.local.defaults}check(e){return e?o.local.settings[e]:o.local.settings}set(e,t){var n,r,c;o.local.defaults=f(f({},o.local.defaults),e);let s=this.get(void 0,!0);if(mw.storage.setObject(`${o.config.prefix}-settings`,s),t){let u=JSON.stringify(s);L((n=o.GM)==null?void 0:n.setValue)&&o.GM.setValue("settings",u),o.local.mwIsAnon||(c=(r=mw.user)==null?void 0:r.options)==null||c.set(o.config.settingsPrefix,u)}}processDefaults(){return m(this,null,function*(){var t;let e={};try{e=f(f({},e),mw.storage.getObject(`${o.config.prefix}-settings`))}catch(s){}if(L((t=o.GM)==null?void 0:t.getValue))try{e=f(f({},e),JSON.parse(yield o.GM.getValue("settings")))}catch(s){}if(!o.local.mwIsAnon)try{e=f(f({},e),JSON.parse(mw.user.options.get(`${o.config.settingsPrefix}-settings`)))}catch(s){}this.set(e,!1)})}};a(_t,"utils",ws);d=new _t});var y={};Q(y,{addBaseToLinks:()=>te,addClick:()=>Ke,addTargetToLinks:()=>me,arrayIntersperse:()=>is,arrayUnique:()=>X,clearWhitespaces:()=>Nt,clipboardWriteLink:()=>it,embed:()=>N,getBodyContentNode:()=>Fe,getCanonicalSpecialPage:()=>ut,getCompareSection:()=>We,getCompareTitle:()=>ge,getComponentFromUrl:()=>ee,getDependencies:()=>we,getErrorMessage:()=>fe,getErrorStatusText:()=>ns,getHref:()=>at,getLabel:()=>Le,getMissingDependencies:()=>gt,getMobileServer:()=>ks,getMsgKey:()=>rt,getMsgParams:()=>Qt,getOffsetRelativeToContainer:()=>Bt,getParamFromUrl:()=>qe,getPlaceholderClasses:()=>xt,getRevisionSection:()=>Pi,getSpecialPageAliases:()=>Yt,getTarget:()=>Je,getTargetFromFragment:()=>os,getTitleFromUrl:()=>Vi,getURL:()=>Jt,h:()=>B,hf:()=>ys,hint:()=>vs,hj:()=>zo,hs:()=>_o,ht:()=>Vn,inArray:()=>Ct,isActiveElement:()=>ds,isAllowed:()=>ke,isArray:()=>Z,isBoolean:()=>Wn,isBreakpoint:()=>Ho,isCompareHidden:()=>yt,isElement:()=>nt,isEmpty:()=>l,isEmptyObject:()=>W,isForeign:()=>re,isFunction:()=>L,isMF:()=>ye,isMessageExists:()=>Qe,isNew:()=>ze,isObject:()=>Ve,isRevisionHidden:()=>Si,isString:()=>F,isToggleKey:()=>Nn,isValidDir:()=>R,isValidID:()=>w,log:()=>de,logException:()=>Pe,logTimer:()=>ve,moduleRequire:()=>Ze,msg:()=>p,msgDom:()=>be,msgHint:()=>_,msgParse:()=>Go,notifyError:()=>C,notifyMsg:()=>Fn,onSchedule:()=>jt,optionsMerge:()=>ie,origin:()=>It,outerHeight:()=>ss,parseQuery:()=>bs,processMessages:()=>Kt,removeClick:()=>Xi,renderLabel:()=>Ot,renderMessageBox:()=>rs,renderPlaceholder:()=>lt,semverCompare:()=>Ji,server:()=>zt,setHTML:()=>qi,spacesToUnderlines:()=>pt,textDom:()=>Lt});function l(i){return!i||i.length===0}function W(i){return!i||!Ve(i)||Object.keys(i).length===0}function F(i){return typeof i=="string"}function Wn(i){return typeof i=="boolean"}function L(i){return typeof i=="function"}function Z(i){return Array.isArray(i)}function Ve(i){return i&&typeof i=="object"&&!Array.isArray(i)}function Nn(i){return i.type==="click"||i.type==="keypress"&&["Enter","Space"].includes(i.code)}function nt(i){return i instanceof Element||i instanceof HTMLElement}function ds(){let i=["button","submit","reset","file","checkbox","radio","range","color","image","hidden"],e=document.activeElement;return!e||e.contentEditable==="true"||e.tagName==="TEXTAREA"||e.tagName==="INPUT"&&!i.includes(e.type)}function It(i){return`${o.config.origin}${i}`}function zt(i){return`${o.config.server}${i}`}function we(i){return i.filter(e=>{let t=mw.loader.getState(e);return t&&!["error","missing"].includes(t)})}function gt(i){return i.filter(e=>{let t=mw.loader.getState(e);return!["ready","registered"].includes(t)})}function Ze(i){return o.local.require(i)}function ze(){return o.local.lastVersion!==o.config.version}function ke(){return!d.get("standalone")&&o.config.include.pageActions.includes(mw.config.get("wgAction"))&&!o.config.exclude.pages.includes(mw.config.get("wgCanonicalSpecialPageName"))}function re(i){return!l(i)&&!o.local.mwServerNames.includes(i)}function ye(){return document.readyState==="complete"?document.body.classList.contains("mw-mf"):!l(mw.config.get("wgMFMode"))}function Ho(i){return i=o.config.breakpoints[i],i?window.matchMedia(i):!1}function jt(i){requestAnimationFrame(()=>{requestAnimationFrame(i)})}function de(i,e,t){let s=console[i];if(!s)return;let n=Qe("script-name")?p("script-name"):"Instant Diffs";/\.$/.test(e)||(e=`${e}.`);let r=[`${n}: ${e}`];Z(t)?r.push(...t):l(t)||r.push(t),s(...r)}function Pe(i,e,t){let s=`Exception in "${i}"`;l(e)||(s=`${s}: ${e}`),de("warn",s,t)}function ve(i,e,t){let s=t-e;s<1e3?s=`${Math.round(s)}ms`:s=`${(s/1e3).toFixed(2)}s`,de("info",`${i}: ${s}`)}function pt(i){return i.replace(/ /g,"_")}function Ji(i,e){return i=i.split("-").shift(),e=e.split("-").shift(),i.localeCompare(e,void 0,{numeric:!0,sensitivity:"case",caseFirst:"upper"})}function is(i,e){if(!Array.isArray(i)||i.length===0)return i;let t=nt(e);return i.flatMap((s,n)=>{if(n<i.length-1){let r=t?e.cloneNode(!0):e;return[s,r]}return[s]})}function Ct(i,e){return Z(i)?i.includes(e):F(i)&&F(e)?i===e:!1}function X(i){return[...new Set(i)]}function ie(...i){return i.reduce((e,t)=>(Object.keys(t).forEach(s=>{let n=e[s],r=t[s];Ve(n)&&Ve(r)?e[s]=ie(n,r):e[s]=r}),e),{})}function p(){return mw.msg.apply(mw.msg,Qt(arguments))}function vs(i){return i=`hint-${i}`,`[${p(i)}]`}function _(i,e,t=!0){return i=p(i),t&&(i=`${i} ${vs(e)}`),i.trim()}function Go(){return mw.message.apply(mw.message,Qt(arguments)).parse()}function be(){return mw.message.apply(mw.message,Qt(arguments)).parseDom()}function Lt(i){return mw.messages.set({[rt("buffer")]:i}),be("buffer")}function Qe(i){return l(i)?!1:mw.message(rt(i)).exists()}function Kt(){if(o.local.userLanguage=mw.config.get("wgUserLanguage"),o.local.userLanguage==="qqx"){o.local.language=o.local.userLanguage;return}o.local.language=o.i18n[o.local.userLanguage]?o.local.userLanguage:"en",o.local.messages=o.i18n[o.local.language]||{},o.local.language!=="en"&&(o.local.messages=f(f({},o.i18n.en),o.local.messages));let i={};for(let[e,t]of Object.entries(o.local.messages))i[rt(e)]=t;mw.messages.set(i)}function rt(i){return`${o.config.messagePrefix}-${i}`}function Qt(i){return l(i[0])||(i[0]=rt(i[0])),i}function ns(i){if(Number.isInteger(i)){if(i===0)return p("error-offline");if(i>=400&&i<500)return p("error-revision-missing");if(i>500)return p("error-server")}}function fe(i,e){var n;i=Qe(i)?i:"error-generic",e=f({},e);let t=f({},(n=e.article)==null?void 0:n.getValues()),s=p(i,t.oldid||t.curid||t.page1||t.rev1,t.diff||t.page2||t.rev2,t.titleText||t.title,e.message||p("error-wasted"));return/\.$/.test(s)||(s=`${s}.`),s}function C(i,e){if(e=f({article:null,silent:null},e),e.silent=Wn(e.silent)?e.silent:!d.get("notifyErrors"),o.isUnloading)return;document.visibilityState==="hidden"&&(e.silent=!0);let t=fe(i,e);if(e.silent){de("warn",t,e);return}if(typeof mw!="undefined"&&mw.notify){let s=B("div.instantDiffs-notification",B("div.instantDiffs-notification-label",B("a",{href:It(`/wiki/${o.config.link}`),target:"_blank"},p("script-name"))),Vn(t));Fn(s,e)}de("error",t,e)}function Fn(i,e){mw.notify(i,{type:"error",tag:`${o.config.prefix}-${e.tag}`})}function Le(i){let e=o.config.labels[i];if(e)return typeof e=="object"?e[document.dir]:e}function Je(i){return d.get("openInNewTab")&&i?"_blank":"_self"}function at(i){return/^\/\//.test(i)&&(i=`https:${i}`),i}function Jt(i){try{return new URL(at(i))}catch(e){return null}}function qe(i,e){let t=Jt(e);if(t)return t.searchParams.get(i)}function ee(i,e){let t=Jt(e);if(t)return t[i]}function Vi(i){var t;let e=mw.util.getParamValue("title",i);if(!e)try{let s=new URL(i,location.href),n=(t=mw.config.get("wgArticlePath"))==null?void 0:t.split("$1")[0];s.pathname.startsWith(n)&&(e=decodeURIComponent(s.pathname.substring(n.length)))}catch(s){return de("error","Error parsing URL",s),null}return e}function bs(i){let e=Jt(i);if(!e)return;let t={};for(let[s,n]of e.searchParams){let r=s.match(/^([^[]+)\[([^\]]+)\]$/);if(r){let[,c,u]=r;t[c]=t[c]||{},t[c][u]=n}else t[s]=n}return t}function w(i){return!l(i)&&!isNaN(i)}function R(i){return!l(i)&&["next","prev","cur"].includes(i)}function yt(i){return i&&(i.fromtexthidden||i.totexthidden)}function Si(i){var e,t;return i&&((t=(e=i.slots)==null?void 0:e.main)==null?void 0:t.texthidden)}function ge(i){return i.torevid?i.totitle:i.fromrevid?i.fromtitle:null}function We(i){let e;return i.torevid?(l(i.tocomment)||(e=i.tocomment.match(o.config.sectionRegExp)),e&&e[1]||null):i.fromrevid?(l(i.fromcomment)||(e=i.fromcomment.match(o.config.sectionRegExp)),e&&e[1]||null):null}function Pi(i){let e;return i&&!l(i.comment)&&(e=i.comment.match(o.config.sectionRegExp)),e&&e[1]||null}function ks(){let i=mw.config.get("wgServer").replace(/^https?:/,""),e=new RegExp("^//www\\.").test(i)?"www.":"",t=mw.config.get("wgContentLanguage");if(!l(t)){let n=new RegExp(`^//${t}\\.`);if(n.test(i))return i.replace(n,`//${t}.m.`)}let s=mw.config.get("wgNoticeProject");if(!l(s)){let n=new RegExp(`^//${e}${s}\\.`);if(n.test(i))return i.replace(n,l(e)?`//${s}.m.`:`//m.${s}.`)}}function Fe(){let i=o.config.bodyContentSelector[mw.config.get("skin")]||o.config.bodyContentSelector.default,e=$(i);return(!e||e.length===0)&&(e=$(document.body)),e}function Yt(i,e){let t="Special",s=mw.config.get("wgFormattedNamespaces")[-1],n=e.split(":"),r=i[e],c=r.split(":");n[0]=s,c[0]=t;let u=[e,r,n.join(":"),c.join(":")];return X(u)}function ut(i){if(!l(i))try{let e=new mw.Title(i).getPrefixedDb();for(let[t,s]of Object.entries(o.local.specialPagesAliasesPrefixed))if(s.includes(e))return t}catch(e){}}function B(i,e={},...t){return Object.keys(e).forEach(s=>{let n=e[s];if(!l(n))switch(s){case"id":i=`${i}#${n.trim()}`,delete e[s];break;case"class":n=Array.isArray(n)?n.map(r=>r.trim()).join("."):n.trim().replace(/\s+/g,"."),i=`${i}.${n}`,delete e[s];break}}),(0,Rn.default)(i,e,...t)}function Vn(i){return document.createTextNode(i)}function _o(...i){return i.reduce((e,t)=>e+t.outerHTML,"")}function ys(...i){let e=new DocumentFragment;for(let t of i)t&&e.append(t);return e}function zo(i){return ys(...i.toArray())}function os(i,e){if(l(i))return null;if(!e)return mw.util.getTargetFromFragment(i);let t=e instanceof jQuery?e[0]:e;if(!t)return null;let s=t.querySelector(`#${CSS.escape(i)}`);if(s)return s;let n=mw.util.percentDecodeFragment(i);return n?t.querySelector(`#${CSS.escape(n)}`):null}function Bt(i,e){if(i instanceof jQuery&&(i=i[0]),e instanceof jQuery&&(e=e[0]),!i||!e)return null;let t=0,s=0,n=i;for(;n&&n!==e&&(t+=n.offsetTop,s+=n.offsetLeft,n=n.offsetParent,!(n&&!e.contains(n))););return{top:t,left:s}}function ss(i,e=!1){if(i instanceof jQuery&&(i=i[0]),!i)return 0;let t=i.offsetHeight;if(e){let s=getComputedStyle(i);t+=parseFloat(s.marginTop)||0,t+=parseFloat(s.marginBottom)||0}return t}function Nt(i){!i||i.length===0||i.contents().each((e,t)=>{t.nodeType===3&&t.remove()})}function it(i,e){var n;let t=()=>{mw.notify(p("copy-link-copied"),{tag:`${o.config.prefix}-copyLink`}),L(e)&&e(!0)},s=()=>{mw.notify(p("copy-link-error"),{tag:`${o.config.prefix}-copyLink`,type:"error"}),L(e)&&e(!1)};if(l(i)||!F(i))return s();if((n=navigator.clipboard)!=null&&n.writeText)navigator.clipboard.writeText(i).then(t).catch(s);else{let r=B("textarea",{value:i});document.body.append(r),r.select();let c=document.execCommand("copy");r.remove(),c?t():s()}}function Ke(i,e,t=!0){let s=n=>{if(n){if(!Nn(n)||n.button||n.ctrlKey)return;if(n.preventDefault(),t&&n.altKey&&!l(i.href)){i.target==="_blank"?window.open(i.href,"_blank").focus():window.location.href=i.href;return}}e(n)};return t&&!l(i.href)&&(l(i.dataset.altTitle)&&(i.dataset.altTitle=i.title),i.dataset.altTitle=`${i.dataset.altTitle} ${vs("alt-click")}`.trim(),i.dataset.origTitle=i.title,i.addEventListener("mouseenter",()=>i.title=i.dataset.altTitle),i.addEventListener("mouseleave",()=>i.title=i.dataset.origTitle),i.addEventListener("mousedown",n=>n.preventDefault())),i.addEventListener("click",s),i.addEventListener("keypress",s),s}function Xi(i,e){i.removeEventListener("click",e),i.removeEventListener("keypress",e)}function N(i,e,t="appendTo"){if(!e)return;if(e instanceof jQuery){(i instanceof jQuery?i:$(i))[t](e);return}let s=i instanceof jQuery?i.get(0):i;switch(t){case"insertBefore":e.before(s);break;case"insertAfter":e.after(s);break;case"prependTo":e.prepend(s);break;default:e.append(s);break}}function qi(i,e){if(i){if(i instanceof jQuery){i.html(e);return}i.innerHTML=e}}function te(i,e,t=!1){if(!i)return;let s;try{s=new URL(e,`https://${location.hostname}`)}catch(c){return}let n=(c,u)=>{$(u).attr("href","https://"+s.hostname+s.pathname+$(u).attr("href"))},r=(c,u)=>{$(u).attr("href","https://"+s.hostname+$(u).attr("href").replace(/special:mylanguage\//i,"")).attr("title",($(u).attr("title")||"").replace(/special:mylanguage\//i,""))};i.filter('a[href^="#"]').each(n),i.find('a[href^="#"]').each(n),t||(i.filter('a[href^="/"]:not([href^="//"])').each(r),i.find('a[href^="/"]:not([href^="//"])').each(r))}function me(i){if(!d.get("openInNewTab"))return;let e=(t,s)=>{let n=s.getAttribute("href");l(n)||/^#/.test(n)||s.setAttribute("target","_blank")};i.filter("a:not(.mw-thanks-thank-link, .jquery-confirmable-element)").each(e),i.find("a:not(.mw-thanks-thank-link, .jquery-confirmable-element)").each(e)}function xt(i=[]){let e=["instantDiffs-panel-placeholder"];return i.forEach(t=>e.push(`instantDiffs-panel-placeholder--${t}`)),d.get("showLink")&&e.push("has-link"),e}function lt(){return $("<span>").addClass(xt())}function Ot(i){i=f({short:null,long:null,iconBefore:null,iconAfter:null},i),l(i.short)||(i.short=B("span",i.short)),l(i.long)||(i.long=B("span",i.long)),l(i.iconBefore)||(i.iconBefore=B("i",i.iconBefore)),l(i.iconAfter)||(i.iconAfter=B("i",i.iconAfter));let e=[i.iconBefore,i.short,i.iconAfter].filter(s=>!l(s)).map(s=>s.cloneNode(!0)),t=[i.iconBefore,i.long,i.iconAfter].filter(s=>!l(s)).map(s=>s.cloneNode(!0));return ys(B("div.instantDiffs-label.instantDiffs-label--long",...t),B("div.instantDiffs-label.instantDiffs-label--short",...e))}function rs(i){i=f({$content:null,type:"notice"},i);let e=i.$content.toArray();return B("div",{class:["cdx-message","cdx-message--block",`cdx-message--${i.type}`,"plainlinks"]},B("span.cdx-message__icon"),B("div.cdx-message__content",...e))}var Rn,P=v(()=>{Rn=ro(Ys());T();O()});var qn=se(()=>{window.instantDiffs||(window.instantDiffs={});instantDiffs.i18n||(instantDiffs.i18n={});instantDiffs.i18n.en={"@metadata":{authors:["Serhio Magpie"]},"script-name":"Instant Diffs","script-name-short":"ID","diff-title":"Difference between revisions","diff-title-hidden":"Difference between revisions is hidden","revision-title":"Revision content","revision-title-hidden":"Revision content is hidden","compare-label":"$1","compare-title":"Compare selected revisions ($1)","compare-pages-title":"Difference between pages","compare-pages-title-hidden":"Difference between pages is hidden","page-title":"Go to page","comment-title":"Go to message","action-save":"Save","action-cancel":"Cancel","action-close":"Close","action-reload":"Reload","action-watch":"Watch","action-unwatch":"Unwatch","goto-snapshot-prev":"Previous link on a page","goto-snapshot-next":"Next link on a page","goto-view-diff":"Show changes","goto-view-revision":"Show revision","goto-view-unpatrolled":"Pending changes","goto-prev":"Older","goto-next":"Newer","goto-prev-diff":"Older edit","goto-next-diff":"Newer edit","goto-back-diff":"Back","goto-prev-revision":"Older revision","goto-next-revision":"Newer revision","goto-back-revision":"Back","goto-diff":"Go to edit","goto-revision":"Go to revision","goto-page":"Go to page","goto-comment":"Go to message","goto-edit":"Edit","goto-source":"View source","goto-history":"View history","goto-info":"View info","goto-talkpage":"Discussion","goto-settings":"Settings","goto-actions":"Actions","hint-close":"Esc","hint-alt-click":"Alt+Click: open the link","hint-snapshot-prev":"Ctrl+Arrow Left","hint-snapshot-next":"Ctrl+Arrow Right","hint-prev":"Arrow Left","hint-next":"Arrow Right","hint-switch":"Ctrl+Arrow Up","hint-unpatrolled":"Ctrl+P","hint-back":"Ctrl+Z","hint-actions":"Ctrl+Arrow Down","copy-link":"Copy link","copy-link-copied":"The link has been copied to the clipboard.","copy-link-error":"Couldn't copy the link.","copy-wikilink":"Copy wikilink","copy-wikilink-page":"page","copy-wikilink-diff":"diff","copy-wikilink-revision":"revision","copy-wikilink-example-title":"Main Page","dialog-title-empty":"[No title]","dialog-title-not-found":"[Not found]","dialog-notice-wikilambda":"WikiLambda app currently only shows the latest revision. See a [[phab:T397902|ticket]] on Phabricator.","dialog-notice-foreign-diff":"You are viewing a foreign diff from [$1 $2]. Some features can be limited.","dialog-notice-foreign-revision":"You are viewing a foreign revision from [$1 $2]. Some features can be limited.","dialog-notice-foreign-wikilambda":"WikiLambda app is not currently supported in the foreign revisions.","settings-title":"Instant Diffs Settings","settings-saved":`The settings have been saved successfully. Reload the page to apply them.`,"settings-saved-icon":"Checkmark icon","settings-empty":`Oops, looks like the admin disabled all settings. Time to relax and grab some coffee!`,"settings-empty-icon":"Coffee cup icon","settings-fieldset-links":"Links","settings-show-link":"Show action link","settings-show-link-help":"Displays an action button (\u2756) after the link to open the Instant Diffs dialog. Otherwise, the click action is added directly to the link. You can still open the link in the current tab by pressing Alt+Click.","settings-show-page-link":"Show page link","settings-show-page-link-help":"Displays an action button (\u2794) after the link to navigate to the page and section where the edit was made. If the [[mw:Special:MyLanguage/Convenient Discussions|Convenient Discussions]] script is installed, the button will also try to navigate to the corresponding comment.","settings-highlight-line":"Highlight lines in Watchlists and similar lists when the Instant Diffs dialog opens from the related link.","settings-mark-watched-line":"Mark changes as visited in Watchlists when the Instant Diffs dialog opens from the related link.","settings-fieldset-dialog":"Dialog","settings-view-width":"Set window dimensions:","settings-view-width-help":"Dimensions apply only to desktop view. Mobile view always uses full screen dimensions.","settings-view-width-option-title":"$1 pixels wide","settings-view-width-compact":"Compact","settings-view-width-standard":"Standard","settings-view-width-wide":"Wide","settings-view-width-full":"Full","settings-view-width-full-title":"All available screen space","settings-close-outside":"Close Instant Diffs dialog when clicking outside of it.","settings-enable-hotkeys":"Enable keyboard shortcuts in the Instant Diffs dialog.","settings-show-diff-tools":"Show additional diff tools, such as the Inline format toggle.","settings-show-revision-info":"Show change information when viewing a revision.","settings-unhide-diffs":"Display hidden revision content and diff info without additional steps.","settings-unhide-diffs-help":'The "$1" [[mw:Special:MyLanguage/Help:RevisionDelete|user right]] is required to view revision content.',"settings-open-in-new-tab":"Open links inside the Instant Diffs dialog in a new tab.","settings-fieldset-menu":"Menu","settings-show-menu-icons":"Show icons in the Instant Diffs dialog dropdown menu.","settings-show-watchlist-popup":"Show advanced options when adding or removing pages from the Watchlist.","settings-show-watchlist-popup-help":"When available, displays a popup with watchlist time period and label settings.","settings-links-hash":"Include section name (anchor) in the links","settings-links-hash-help":"The section name will also be appended as an anchor to the link URL when using copy actions with the selected non-minified format.","settings-links-format":"Link format for the copy action:","settings-links-format-full":"Full url with a page title","settings-links-format-minify":"Minified url","settings-wikilinks-format":"Wikilink format for the copy action:","settings-wikilinks-format-link":"Simple link in brackets","settings-wikilinks-format-special":"Internal wiki link","settings-fieldset-general":"General","settings-enable-mobile":"Enable Instant Diffs on the mobile skin (Minerva).","settings-enable-mobile-help":"To re-enable Instant Diffs, you will need to switch to a different skin.","settings-notify-errors":"Show popup alerts for critical errors.","settings-fieldset-pinned-actions":"Pinned Actions","settings-pinned-actions":"Pin selected actions in the quick access menu:","settings-pinned-actions-help":"This list shows only actions available for the current view. Pinned actions appear only in desktop view.","error-generic":"Something went wrong: $4","error-server":"Server error, please try again later","error-offline":"Please check your internet connection","error-wasted":"Unexpected error","error-prepare-generic":"Failed to prepare configuration: $4","error-prepare-version":"Another instance is already running: $4","error-prepare-replaced":"Standalone instance replaced successfully: $4","error-prepare-mobile":"The script is disabled in the settings for the mobile skin (Minerva)","error-link-options":'Failed to parse the "data-instantdiffs-options" link attribute: $4',"error-revision-generic":'Failed to load revision data "oldid=$1": $4',"error-revision-curid":'Failed to load revision data "curid=$1": $4',"error-revision-badrevids":"Revision not found","error-revision-badpageids":"Page not found","error-revision-missing":"Page not found","error-revision-invalid":"Page not found: $4","error-diff-generic":'Failed to load revision compare data "oldid=$1", "diff=$2": $4',"error-diff-compare-pages":'Failed to load page compare data "page1=$1", "page2=$2": $4',"error-diff-missingcontent":"Revision is hidden","error-diff-nosuchrevid":"Revision not found","error-diff-missingtitle":"Page not found","error-api-generic":"Failed to request api: $4","error-dependencies-generic":"Failed to load dependencies: $4","error-dependencies-revid":'Failed to load page dependencies "oldid=$1": $4',"error-dependencies-curid":'Failed to load page dependencies "curid=$1": $4',"error-global-watchlist":"Failed to execute Global Watchlist API: $4","error-setting-request":"Failed to load user options: $4","error-setting-save":"Failed to save user options: $4"}});var jn=se(()=>{window.instantDiffs||(window.instantDiffs={});instantDiffs.i18n||(instantDiffs.i18n={});instantDiffs.i18n.uk={"@metadata":{authors:["Serhio Magpie"]},"script-name":"Instant Diffs","script-name-short":"ID","diff-title":"\u0420\u0456\u0437\u043D\u0438\u0446\u044F \u0432\u0435\u0440\u0441\u0456\u0439","diff-title-hidden":"\u0420\u0456\u0437\u043D\u0438\u0446\u044F \u0432\u0435\u0440\u0441\u0456\u0439 \u043F\u0440\u0438\u0445\u043E\u0432\u0430\u043D\u0430","revision-title":"\u0412\u043C\u0456\u0441\u0442 \u0432\u0435\u0440\u0441\u0456\u0457","revision-title-hidden":"\u0412\u043C\u0456\u0441\u0442 \u0432\u0435\u0440\u0441\u0456\u0457 \u043F\u0440\u0438\u0445\u043E\u0432\u0430\u043D\u043E","compare-label":"$1","compare-title":"\u041F\u043E\u0440\u0456\u0432\u043D\u044F\u0442\u0438 \u0432\u0438\u0431\u0440\u0430\u043D\u0456 \u0432\u0435\u0440\u0441\u0456\u0457 ($1)","compare-pages-title":"\u0420\u0456\u0437\u043D\u0438\u0446\u044F \u043C\u0456\u0436 \u0441\u0442\u043E\u0440\u0456\u043D\u043A\u0430\u043C\u0438","compare-pages-title-hidden":"\u0420\u0456\u0437\u043D\u0438\u0446\u044F \u043C\u0456\u0436 \u0441\u0442\u043E\u0440\u0456\u043D\u043A\u0430\u043C\u0438 \u043F\u0440\u0438\u0445\u043E\u0432\u0430\u043D\u0430","page-title":"\u041F\u0435\u0440\u0435\u0439\u0442\u0438 \u0434\u043E \u0441\u0442\u043E\u0440\u0456\u043D\u043A\u0438","comment-title":"\u041F\u0435\u0440\u0435\u0439\u0442\u0438 \u0434\u043E \u043F\u043E\u0432\u0456\u0434\u043E\u043C\u043B\u0435\u043D\u043D\u044F","action-save":"\u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438","action-cancel":"\u0412\u0456\u0434\u043C\u0456\u043D\u0438\u0442\u0438","action-close":"\u0417\u0430\u043A\u0440\u0438\u0442\u0438","action-reload":"\u041F\u0435\u0440\u0435\u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438","action-watch":"\u0421\u043B\u0456\u0434\u043A\u0443\u0432\u0430\u0442\u0438","action-unwatch":"\u041F\u0440\u0438\u043F\u0438\u043D\u0438\u0442\u0438 \u0441\u043B\u0456\u0434\u043A\u0443\u0432\u0430\u0442\u0438","goto-snapshot-prev":"\u041F\u043E\u043F\u0435\u0440\u0435\u0434\u043D\u0454 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F \u043D\u0430 \u0441\u0442\u043E\u0440\u0456\u043D\u0446\u0456","goto-snapshot-next":"\u041D\u0430\u0441\u0442\u0443\u043F\u043D\u0435 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F \u043D\u0430 \u0441\u0442\u043E\u0440\u0456\u043D\u0446\u0456","goto-view-diff":"\u0420\u0456\u0437\u043D\u0438\u0446\u044F \u0432\u0435\u0440\u0441\u0456\u0439","goto-view-revision":"\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u0438 \u0432\u0435\u0440\u0441\u0456\u044E","goto-view-unpatrolled":"\u041D\u0435\u043F\u0435\u0440\u0435\u0432\u0456\u0440\u0435\u043D\u0456 \u0437\u043C\u0456\u043D\u0438","goto-prev":"\u041F\u043E\u043F\u0435\u0440\u0435\u0434\u043D\u044F","goto-next":"\u041D\u0430\u0441\u0442\u0443\u043F\u043D\u0430","goto-prev-diff":"\u041F\u043E\u043F\u0435\u0440\u0435\u0434\u043D\u0454 \u0440\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u043D\u043D\u044F","goto-next-diff":"\u041D\u0430\u0441\u0442\u0443\u043F\u043D\u0435 \u0440\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u043D\u043D\u044F","goto-back-diff":"\u041F\u043E\u0432\u0435\u0440\u043D\u0443\u0442\u0438\u0441\u044F","goto-prev-revision":"\u041F\u043E\u043F\u0435\u0440\u0435\u0434\u043D\u044F \u0432\u0435\u0440\u0441\u0456\u044F","goto-next-revision":"\u041D\u0430\u0441\u0442\u0443\u043F\u043D\u0430 \u0432\u0435\u0440\u0441\u0456\u044F","goto-back-revision":"\u041F\u043E\u0432\u0435\u0440\u043D\u0443\u0442\u0438\u0441\u044F","goto-diff":"\u041F\u0435\u0440\u0435\u0439\u0442\u0438 \u0434\u043E \u0440\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u043D\u043D\u044F","goto-revision":"\u041F\u0435\u0440\u0435\u0439\u0442\u0438 \u0434\u043E \u0432\u0435\u0440\u0441\u0456\u0457","goto-page":"\u041F\u0435\u0440\u0435\u0439\u0442\u0438 \u0434\u043E \u0441\u0442\u043E\u0440\u0456\u043D\u043A\u0438","goto-comment":"\u041F\u0435\u0440\u0435\u0439\u0442\u0438 \u0434\u043E \u043F\u043E\u0432\u0456\u0434\u043E\u043C\u043B\u0435\u043D\u043D\u044F","goto-edit":"\u0420\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u0442\u0438","goto-source":"\u041F\u0435\u0440\u0435\u0433\u043B\u044F\u043D\u0443\u0442\u0438 \u043A\u043E\u0434","goto-history":"\u041F\u0435\u0440\u0435\u0433\u043B\u044F\u043D\u0443\u0442\u0438 \u0456\u0441\u0442\u043E\u0440\u0456\u044E","goto-info":"\u041F\u0435\u0440\u0435\u0433\u043B\u044F\u043D\u0443\u0442\u0438 \u0456\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0456\u044E","goto-talkpage":"\u041E\u0431\u0433\u043E\u0432\u043E\u0440\u0435\u043D\u043D\u044F","goto-settings":"\u041D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u043D\u043D\u044F","goto-actions":"\u0414\u0456\u0457","hint-close":"Esc","hint-alt-click":"Alt+Click: \u0432\u0456\u0434\u043A\u0440\u0438\u0442\u0438 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F","hint-snapshot-prev":"Ctrl+\u0421\u0442\u0440\u0456\u043B\u043A\u0430 \u0432\u043B\u0456\u0432\u043E","hint-snapshot-next":"Ctrl+\u0421\u0442\u0440\u0456\u043B\u043A\u0430 \u0432\u043F\u0440\u0430\u0432\u043E","hint-prev":"\u0421\u0442\u0440\u0456\u043B\u043A\u0430 \u0432\u043B\u0456\u0432\u043E","hint-next":"\u0421\u0442\u0440\u0456\u043B\u043A\u0430 \u0432\u043F\u0440\u0430\u0432\u043E","hint-switch":"Ctrl+\u0421\u0442\u0440\u0456\u043B\u043A\u0430 \u0432\u0433\u043E\u0440\u0443","hint-unpatrolled":"Ctrl+P","hint-back":"Ctrl+Z","hint-actions":"Ctrl+\u0421\u0442\u0440\u0456\u043B\u043A\u0430 \u0432\u043D\u0438\u0437","copy-link":"\u0421\u043A\u043E\u043F\u0456\u044E\u0432\u0430\u0442\u0438 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F","copy-link-copied":"\u041F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F \u0441\u043A\u043E\u043F\u0456\u0439\u043E\u0432\u0430\u043D\u043E \u0434\u043E \u0431\u0443\u0444\u0435\u0440\u0443 \u043E\u0431\u043C\u0456\u043D\u0443","copy-link-error":"\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0441\u043A\u043E\u043F\u0456\u044E\u0432\u0430\u0442\u0438 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F","copy-wikilink":"\u0421\u043A\u043E\u043F\u0456\u044E\u0432\u0430\u0442\u0438 \u0432\u0456\u043A\u0456-\u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F","copy-wikilink-page":"\u0441\u0442\u043E\u0440\u0456\u043D\u043A\u0430","copy-wikilink-diff":"\u0440\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u043D\u043D\u044F","copy-wikilink-revision":"\u0432\u0435\u0440\u0441\u0456\u044F","copy-wikilink-example-title":"\u0413\u043E\u043B\u043E\u0432\u043D\u0430 \u0441\u0442\u043E\u0440\u0456\u043D\u043A\u0430","dialog-title-empty":"[\u0411\u0435\u0437 \u043D\u0430\u0437\u0432\u0438]","dialog-title-not-found":"[\u041D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E]","dialog-notice-wikilambda":"\u0414\u043E\u0434\u0430\u0442\u043E\u043A WikiLambda \u0437\u0430\u0440\u0430\u0437 \u043F\u043E\u043A\u0430\u0437\u0443\u0454 \u043B\u0438\u0448\u0435 \u043E\u0441\u0442\u0430\u043D\u043D\u044E \u0432\u0435\u0440\u0441\u0456\u044E. \u0414\u0438\u0432. [[phab:T397902|\u0437\u0430\u0432\u0434\u0430\u043D\u043D\u044F]] \u043D\u0430 Phabricator.","dialog-notice-foreign-diff":"\u0412\u0438 \u043F\u0435\u0440\u0435\u0433\u043B\u044F\u0434\u0430\u0454\u0442\u0435 \u0437\u043E\u0432\u043D\u0456\u0448\u043D\u044E \u0440\u0456\u0437\u043D\u0438\u0446\u044E \u0432\u0435\u0440\u0441\u0456\u0439 \u0437 [$1 $2]. \u0414\u0435\u044F\u043A\u0456 \u0444\u0443\u043D\u043A\u0446\u0456\u0457 \u043C\u043E\u0436\u0443\u0442\u044C \u0431\u0443\u0442\u0438 \u043E\u0431\u043C\u0435\u0436\u0435\u043D\u0456.","dialog-notice-foreign-revision":"\u0412\u0438 \u043F\u0435\u0440\u0435\u0433\u043B\u044F\u0434\u0430\u0454\u0442\u0435 \u0437\u043E\u0432\u043D\u0456\u0448\u043D\u044E \u0432\u0435\u0440\u0441\u0456\u044E \u0437 [$1 $2]. \u0414\u0435\u044F\u043A\u0456 \u0444\u0443\u043D\u043A\u0446\u0456\u0457 \u043C\u043E\u0436\u0443\u0442\u044C \u0431\u0443\u0442\u0438 \u043E\u0431\u043C\u0435\u0436\u0435\u043D\u0456.","dialog-notice-foreign-wikilambda":"\u0414\u043E\u0434\u0430\u0442\u043E\u043A WikiLambda \u0437\u0430\u0440\u0430\u0437 \u043D\u0435 \u043F\u0456\u0434\u0442\u0440\u0438\u043C\u0443\u0454\u0442\u044C\u0441\u044F \u043F\u0440\u0438 \u043F\u0435\u0440\u0435\u0433\u043B\u044F\u0434\u0456 \u0437\u043E\u0432\u043D\u0456\u0448\u043D\u044C\u043E\u0457 \u0432\u0435\u0440\u0441\u0456\u0457.","settings-title":"\u041D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u043D\u043D\u044F Instant Diffs","settings-saved":`\u041D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u043D\u043D\u044F \u0443\u0441\u043F\u0456\u0448\u043D\u043E \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043D\u043E. \u041F\u0435\u0440\u0435\u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0442\u0435 \u0441\u0442\u043E\u0440\u0456\u043D\u043A\u0443, \u0449\u043E\u0431 \u0437\u0430\u0441\u0442\u043E\u0441\u0443\u0432\u0430\u0442\u0438 \u0457\u0445.`,"settings-saved-icon":"\u0406\u043A\u043E\u043D\u043A\u0430 \u0433\u0430\u043B\u043E\u0447\u043A\u0438","settings-empty":`\u041E\u0439, \u0441\u0445\u043E\u0436\u0435, \u0430\u0434\u043C\u0456\u043D\u0456\u0441\u0442\u0440\u0430\u0442\u043E\u0440 \u0432\u0438\u043C\u043A\u043D\u0443\u0432 \u0443\u0441\u0456 \u043D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u043D\u043D\u044F. \u0421\u0430\u043C\u0435 \u0447\u0430\u0441 \u0432\u0456\u0434\u043F\u043E\u0447\u0438\u0442\u0438 \u0442\u0430 \u0432\u0438\u043F\u0438\u0442\u0438 \u043A\u0430\u0432\u0438!`,"settings-empty-icon":"\u0406\u043A\u043E\u043D\u0430 \u0447\u0430\u0448\u043A\u0438 \u043A\u0430\u0432\u0438","settings-fieldset-links":"\u041F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F","settings-show-link":"\u041F\u043E\u043A\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u043A\u043D\u043E\u043F\u043A\u0443 \u0434\u0456\u0457","settings-show-link-help":"\u041F\u043E\u043A\u0430\u0437\u0443\u0454 \u043A\u043D\u043E\u043F\u043A\u0443 \u0434\u0456\u0457 (\u2756) \u043F\u0456\u0441\u043B\u044F \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F \u0434\u043B\u044F \u0432\u0456\u0434\u043A\u0440\u0438\u0442\u0442\u044F \u0432\u0456\u043A\u043D\u0430 Instant Diffs. \u0406\u043D\u0430\u043A\u0448\u0435 \u0434\u0456\u044F \u0434\u043E\u0434\u0430\u0454\u0442\u044C\u0441\u044F \u0431\u0435\u0437\u043F\u043E\u0441\u0435\u0440\u0435\u0434\u043D\u044C\u043E \u0434\u043E \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F, \u0430\u043B\u0435 \u0432\u0438 \u0437\u043C\u043E\u0436\u0435\u0442\u0435 \u0432\u0456\u0434\u043A\u0440\u0438\u0442\u0438 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F \u0432 \u043F\u043E\u0442\u043E\u0447\u043D\u0456\u0439 \u0432\u043A\u043B\u0430\u0434\u0446\u0456 \u0437\u0430 \u0434\u043E\u043F\u043E\u043C\u043E\u0433\u043E\u044E Alt+Click.","settings-show-page-link":"\u041F\u043E\u043A\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u043A\u043D\u043E\u043F\u043A\u0443 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F \u043D\u0430 \u0441\u0442\u043E\u0440\u0456\u043D\u043A\u0443","settings-show-page-link-help":"\u041F\u043E\u043A\u0430\u0437\u0443\u0454 \u043A\u043D\u043E\u043F\u043A\u0443 (\u2794) \u043F\u0456\u0441\u043B\u044F \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F \u0434\u043B\u044F \u043F\u0435\u0440\u0435\u0445\u043E\u0434\u0443 \u043D\u0430 \u0441\u0442\u043E\u0440\u0456\u043D\u043A\u0443 \u0442\u0430 \u0440\u043E\u0437\u0434\u0456\u043B, \u0434\u0435 \u0431\u0443\u043B\u043E \u0437\u0440\u043E\u0431\u043B\u0435\u043D\u043E \u0440\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u043D\u043D\u044F. \u042F\u043A\u0449\u043E \u0432\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043E \u0441\u043A\u0440\u0438\u043F\u0442 [[mw:Special:MyLanguage/Convenient Discussions|Convenient Discussions]], \u043A\u043D\u043E\u043F\u043A\u0430 \u0442\u0430\u043A\u043E\u0436 \u0441\u043F\u0440\u043E\u0431\u0443\u0454 \u043F\u0435\u0440\u0435\u0439\u0442\u0438 \u0434\u043E \u0432\u0456\u0434\u043F\u043E\u0432\u0456\u0434\u043D\u043E\u0433\u043E \u043A\u043E\u043C\u0435\u043D\u0442\u0430\u0440\u044F.","settings-highlight-line":"\u041F\u0456\u0434\u0441\u0432\u0456\u0447\u0443\u0432\u0430\u0442\u0438 \u0440\u044F\u0434\u043A\u0438 \u0443 \u0441\u043F\u0438\u0441\u043A\u0430\u0445 \u0441\u043F\u043E\u0441\u0442\u0435\u0440\u0435\u0436\u0435\u043D\u043D\u044F \u0442\u0430 \u043F\u043E\u0434\u0456\u0431\u043D\u0438\u0445 \u0441\u043F\u0438\u0441\u043A\u0430\u0445 \u043F\u0440\u0438 \u0432\u0456\u0434\u043A\u0440\u0438\u0442\u0442\u0456 \u0432\u0456\u043A\u043D\u0430 Instant Diffs \u0447\u0435\u0440\u0435\u0437 \u0432\u0456\u0434\u043F\u043E\u0432\u0456\u0434\u043D\u0435 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F.","settings-mark-watched-line":"\u041F\u043E\u0437\u043D\u0430\u0447\u0430\u0442\u0438 \u0437\u043C\u0456\u043D\u0438 \u044F\u043A \u043F\u0435\u0440\u0435\u0433\u043B\u044F\u043D\u0443\u0442\u0456 \u0432 \u0441\u043F\u0438\u0441\u043A\u0430\u0445 \u0441\u043F\u043E\u0441\u0442\u0435\u0440\u0435\u0436\u0435\u043D\u043D\u044F \u043F\u0440\u0438 \u0432\u0456\u0434\u043A\u0440\u0438\u0442\u0442\u0456 \u0432\u0456\u043A\u043D\u0430 Instant Diffs.","settings-fieldset-dialog":"\u0412\u0456\u043A\u043D\u043E","settings-view-width":"\u0412\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u0438 \u0440\u043E\u0437\u043C\u0456\u0440\u0438 \u0432\u0456\u043A\u043D\u0430:","settings-view-width-help":"\u0420\u043E\u0437\u043C\u0456\u0440\u0438 \u0437\u0430\u0441\u0442\u043E\u0441\u043E\u0432\u0443\u044E\u0442\u044C\u0441\u044F \u043B\u0438\u0448\u0435 \u0434\u043B\u044F \u0441\u0442\u0430\u0446\u0456\u043E\u043D\u0430\u0440\u043D\u043E\u0433\u043E \u0432\u0438\u0433\u043B\u044F\u0434\u0443. \u0414\u043B\u044F \u043C\u043E\u0431\u0456\u043B\u044C\u043D\u043E\u0433\u043E \u0432\u0438\u0433\u043B\u044F\u0434\u0443 \u0437\u0430\u0432\u0436\u0434\u0438 \u0432\u0438\u043A\u043E\u0440\u0438\u0441\u0442\u043E\u0432\u0443\u044E\u0442\u044C\u0441\u044F \u043F\u043E\u0432\u043D\u043E\u0435\u043A\u0440\u0430\u043D\u043D\u0456 \u0440\u043E\u0437\u043C\u0456\u0440\u0438.","settings-view-width-option-title":"$1 \u043F\u0456\u043A\u0441\u0435\u043B\u0456\u0432 \u0437\u0430\u0432\u0448\u0438\u0440\u0448\u043A\u0438","settings-view-width-compact":"\u041A\u043E\u043C\u043F\u0430\u043A\u0442\u043D\u0438\u0439","settings-view-width-standard":"\u0421\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u043D\u0438\u0439","settings-view-width-wide":"\u0428\u0438\u0440\u043E\u043A\u0438\u0439","settings-view-width-full":"\u041F\u043E\u0432\u043D\u043E\u0435\u043A\u0440\u0430\u043D\u043D\u0438\u0439","settings-view-width-full-title":"\u0412\u0435\u0441\u044C \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0438\u0439 \u043F\u0440\u043E\u0441\u0442\u0456\u0440 \u0435\u043A\u0440\u0430\u043D\u0443","settings-close-outside":"\u0417\u0430\u043A\u0440\u0438\u0432\u0430\u0442\u0438 \u0432\u0456\u043A\u043D\u043E Instant Diffs \u043D\u0430\u0442\u0438\u0441\u043A\u0430\u044E\u0447\u0438 \u043F\u043E\u0437\u0430 \u0439\u043E\u0433\u043E \u043C\u0435\u0436\u0430\u043C\u0438.","settings-enable-hotkeys":"\u0423\u0432\u0456\u043C\u043A\u043D\u0443\u0442\u0438 \u0433\u0430\u0440\u044F\u0447\u0456 \u043A\u043B\u0430\u0432\u0456\u0448\u0456 \u0443 \u0432\u0456\u043A\u043D\u0456 Instant Diffs.","settings-show-diff-tools":"\u041F\u043E\u043A\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0434\u043E\u0434\u0430\u0442\u043A\u043E\u0432\u0456 \u0456\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u0438 \u0434\u043B\u044F \u043F\u0435\u0440\u0435\u0433\u043B\u044F\u0434\u0443 \u0437\u043C\u0456\u043D, \u0437\u043E\u043A\u0440\u0435\u043C\u0430 \u043F\u0435\u0440\u0435\u043C\u0438\u043A\u0430\u0447 \u0444\u043E\u0440\u043C\u0430\u0442\u0443 \xAB\u041B\u0456\u043D\u0456\u0439\u043D\u043E\xBB.","settings-show-revision-info":"\u041F\u043E\u043A\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0456\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0456\u044E \u043F\u0440\u043E \u0437\u043C\u0456\u043D\u0438 \u043F\u0456\u0434 \u0447\u0430\u0441 \u043F\u0435\u0440\u0435\u0433\u043B\u044F\u0434\u0443 \u0432\u0435\u0440\u0441\u0456\u0457.","settings-unhide-diffs":"\u041F\u043E\u043A\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0432\u043C\u0456\u0441\u0442 \u043F\u0440\u0438\u0445\u043E\u0432\u0430\u043D\u0438\u0445 \u0432\u0435\u0440\u0441\u0456\u0439 \u0431\u0435\u0437 \u0434\u043E\u0434\u0430\u0442\u043A\u043E\u0432\u0438\u0445 \u0434\u0456\u0439.","settings-unhide-diffs-help":"\u0429\u043E\u0431 \u043F\u0435\u0440\u0435\u0433\u043B\u044F\u043D\u0443\u0442\u0438 \u0432\u043C\u0456\u0441\u0442 \u0432\u0435\u0440\u0441\u0456\u0457 \u043F\u043E\u0442\u0440\u0456\u0431\u043D\u0435 [[mw:Special:MyLanguage/Help:RevisionDelete|\u043F\u0440\u0430\u0432\u043E \u043A\u043E\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430]] \xAB$1\xBB.","settings-open-in-new-tab":"\u0412\u0456\u0434\u043A\u0440\u0438\u0432\u0430\u0442\u0438 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F \u0443 \u0432\u0456\u043A\u043D\u0456 Instant Diffs \u0432 \u043D\u043E\u0432\u0456\u0439 \u0432\u043A\u043B\u0430\u0434\u0446\u0456.","settings-fieldset-menu":"\u041C\u0435\u043D\u044E","settings-show-menu-icons":"\u041F\u043E\u043A\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0456\u043A\u043E\u043D\u043A\u0438 \u0443 \u0432\u0438\u043F\u0430\u0434\u0430\u044E\u0447\u043E\u043C\u0443 \u043C\u0435\u043D\u044E \u0432\u0456\u043A\u043D\u0430 Instant Diffs.","settings-show-watchlist-popup":"\u041F\u043E\u043A\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0440\u043E\u0437\u0448\u0438\u0440\u0435\u043D\u0456 \u043C\u043E\u0436\u043B\u0438\u0432\u043E\u0441\u0442\u0456 \u043F\u0440\u0438 \u0434\u043E\u0434\u0430\u0432\u0430\u043D\u043D\u0456 \u0430\u0431\u043E \u0432\u0438\u043B\u0443\u0447\u0435\u043D\u043D\u0456 \u0441\u0442\u043E\u0440\u0456\u043D\u043A\u0438 \u0437\u0456 \u0441\u043F\u0438\u0441\u043A\u0443 \u0441\u043F\u043E\u0441\u0442\u0435\u0440\u0435\u0436\u0435\u043D\u043D\u044F.","settings-show-watchlist-popup-help":"\u0417\u0430 \u043C\u043E\u0436\u043B\u0438\u0432\u043E\u0441\u0442\u0456 \u0432\u0456\u0434\u043E\u0431\u0440\u0430\u0436\u0430\u0442\u0438\u043C\u0435\u0442\u044C\u0441\u044F \u0432\u0456\u043A\u043D\u043E \u0437 \u043D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u043D\u043D\u044F\u043C\u0438 \u0442\u0440\u0438\u0432\u0430\u043B\u043E\u0441\u0442\u0456 \u0441\u043F\u043E\u0441\u0442\u0435\u0440\u0435\u0436\u0435\u043D\u043D\u044F \u0442\u0430 \u043F\u043E\u0437\u043D\u0430\u0447\u043A\u0430\u043C\u0438.","settings-links-hash":"\u0414\u043E\u0434\u0430\u0432\u0430\u0442\u0438 \u043D\u0430\u0437\u0432\u0443 \u0440\u043E\u0437\u0434\u0456\u043B\u0443 (\u044F\u043A\u0456\u0440) \u0434\u043E \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u044C","settings-links-hash-help":"\u041D\u0430\u0437\u0432\u0430 \u0440\u043E\u0437\u0434\u0456\u043B\u0443 \u0442\u0430\u043A\u043E\u0436 \u0434\u043E\u0434\u0430\u0432\u0430\u0442\u0438\u043C\u0435\u0442\u044C\u0441\u044F \u044F\u043A \u044F\u043A\u0456\u0440 \u0434\u043E URL-\u0430\u0434\u0440\u0435\u0441\u0438 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F \u043F\u0440\u0438 \u043A\u043E\u043F\u0456\u044E\u0432\u0430\u043D\u043D\u0456 \u0443 \u043F\u043E\u0432\u043D\u043E\u043C\u0443 \u0444\u043E\u0440\u043C\u0430\u0442\u0456.","settings-links-format":"\u0424\u043E\u0440\u043C\u0430\u0442 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u044C \u0434\u043B\u044F \u043A\u043E\u043F\u0456\u044E\u0432\u0430\u043D\u043D\u044F:","settings-links-format-full":"\u041F\u043E\u0432\u043D\u0435 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F \u0437 \u043D\u0430\u0437\u0432\u043E\u044E \u0441\u0442\u043E\u0440\u0456\u043D\u043A\u0438","settings-links-format-minify":"\u0421\u043A\u043E\u0440\u043E\u0447\u0435\u043D\u0435 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F","settings-wikilinks-format":"\u0424\u043E\u0440\u043C\u0430\u0442 \u0432\u0456\u043A\u0456-\u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F \u0434\u043B\u044F \u043A\u043E\u043F\u0456\u044E\u0432\u0430\u043D\u043D\u044F:","settings-wikilinks-format-link":"\u041F\u0440\u043E\u0441\u0442\u0435 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F \u0432 \u0434\u0443\u0436\u043A\u0430\u0445","settings-wikilinks-format-special":"\u0412\u043D\u0443\u0442\u0440\u0456\u0448\u043D\u0454 \u0432\u0456\u043A\u0456-\u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F","settings-fieldset-general":"\u0417\u0430\u0433\u0430\u043B\u044C\u043D\u0456","settings-enable-mobile":"\u0423\u0432\u0456\u043C\u043A\u043D\u0443\u0442\u0438 Instant Diffs \u0434\u043B\u044F \u043C\u043E\u0431\u0456\u043B\u044C\u043D\u043E\u0457 \u0442\u0435\u043C\u0438 (Minerva).","settings-enable-mobile-help":"\u0429\u043E\u0431 \u043F\u043E\u0432\u0442\u043E\u0440\u043D\u043E \u0443\u0432\u0456\u043C\u043A\u043D\u0443\u0442\u0438 Instant Diffs, \u0432\u0430\u043C \u043F\u043E\u0442\u0440\u0456\u0431\u043D\u043E \u0431\u0443\u0434\u0435 \u043F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0438\u0442\u0438\u0441\u044F \u043D\u0430 \u0456\u043D\u0448\u0443 \u0442\u0435\u043C\u0443 \u043E\u0444\u043E\u0440\u043C\u043B\u0435\u043D\u043D\u044F.","settings-notify-errors":"\u041F\u043E\u043A\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0441\u043F\u043B\u0438\u0432\u0430\u044E\u0447\u0456 \u043F\u043E\u0432\u0456\u0434\u043E\u043C\u043B\u0435\u043D\u043D\u044F \u043F\u0440\u0438 \u043A\u0440\u0438\u0442\u0438\u0447\u043D\u0438\u0445 \u043F\u043E\u043C\u0438\u043B\u043A\u0430\u0445.","settings-fieldset-pinned-actions":"\u0417\u0430\u043A\u0440\u0456\u043F\u043B\u0435\u043D\u0456 \u0434\u0456\u0457","settings-pinned-actions":"\u0417\u0430\u043A\u0440\u0456\u043F\u0438\u0442\u0438 \u0432\u0438\u0431\u0440\u0430\u043D\u0456 \u0434\u0456\u0457 \u0432 \u043C\u0435\u043D\u044E \u0448\u0432\u0438\u0434\u043A\u043E\u0433\u043E \u0434\u043E\u0441\u0442\u0443\u043F\u0443:","settings-pinned-actions-help":"\u0423 \u0446\u044C\u043E\u043C\u0443 \u0441\u043F\u0438\u0441\u043A\u0443 \u0432\u0456\u0434\u043E\u0431\u0440\u0430\u0436\u0430\u044E\u0442\u044C\u0441\u044F \u043B\u0438\u0448\u0435 \u0434\u0456\u0457, \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0456 \u0434\u043B\u044F \u043F\u043E\u0442\u043E\u0447\u043D\u043E\u0433\u043E \u043F\u0435\u0440\u0435\u0433\u043B\u044F\u0434\u0443. \u0417\u0430\u043A\u0440\u0456\u043F\u043B\u0435\u043D\u0456 \u0434\u0456\u0457 \u0432\u0456\u0434\u043E\u0431\u0440\u0430\u0436\u0430\u044E\u0442\u044C\u0441\u044F \u043B\u0438\u0448\u0435 \u0443 \u0441\u0442\u0430\u0446\u0456\u043E\u043D\u0430\u0440\u043D\u043E\u043C\u0443 \u0432\u0438\u0433\u043B\u044F\u0434\u0456.","error-generic":"\u0429\u043E\u0441\u044C \u043F\u0456\u0448\u043B\u043E \u043D\u0435 \u0442\u0430\u043A: $4","error-server":"\u041F\u043E\u043C\u0438\u043B\u043A\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0441\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435 \u043F\u0456\u0437\u043D\u0456\u0448\u0435","error-offline":"\u041F\u0435\u0440\u0435\u0432\u0456\u0440\u0442\u0435 \u043F\u0456\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u043D\u044F \u0434\u043E \u0456\u043D\u0442\u0435\u0440\u043D\u0435\u0442\u0443","error-wasted":"\u041D\u0435\u0441\u043F\u043E\u0434\u0456\u0432\u0430\u043D\u0430 \u043F\u043E\u043C\u0438\u043B\u043A\u0430","error-prepare-generic":"\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u043F\u0456\u0434\u0433\u043E\u0442\u0443\u0432\u0430\u0442\u0438 \u043A\u043E\u043D\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u044E: $4","error-prepare-version":"\u0421\u043A\u0440\u0438\u043F\u0442 \u0432\u0436\u0435 \u0437\u0430\u043F\u0443\u0449\u0435\u043D\u0438\u0439: $4","error-prepare-replaced":"\u0410\u0432\u0442\u043E\u043D\u043E\u043C\u043D\u0438\u0439 \u0435\u043A\u0437\u0435\u043C\u043F\u043B\u044F\u0440 \u0441\u043A\u0440\u0438\u043F\u0442\u0443 \u0443\u0441\u043F\u0456\u0448\u043D\u043E \u0437\u0430\u043C\u0456\u0449\u0435\u043D\u0438\u0439: $4","error-prepare-mobile":"\u0421\u043A\u0440\u0438\u043F\u0442 \u0432\u0438\u043C\u043A\u043D\u0435\u043D\u043E \u0432 \u043D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u043D\u043D\u044F\u0445 \u0434\u043B\u044F \u043C\u043E\u0431\u0456\u043B\u044C\u043D\u043E\u0457 \u0442\u0435\u043C\u0438 (Minerva)","error-link-options":'\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0440\u043E\u0437\u043F\u0430\u0440\u0441\u0438\u0442\u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F "data-instantdiffs-options": $4',"error-revision-generic":"\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u0434\u0430\u043D\u0456 \u0432\u0435\u0440\u0441\u0456\u0457 \xABoldid=$1\xBB: $4","error-revision-curid":"\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u0434\u0430\u043D\u0456 \u0432\u0435\u0440\u0441\u0456\u0457 \xABcurid=$1\xBB: $4","error-revision-badrevids":"\u0412\u0435\u0440\u0441\u0456\u044E \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E","error-revision-badpageids":"\u0421\u0442\u043E\u0440\u0456\u043D\u043A\u0443 \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E","error-revision-missing":"\u0421\u0442\u043E\u0440\u0456\u043D\u043A\u0443 \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E","error-revision-invalid":"\u0421\u0442\u043E\u0440\u0456\u043D\u043A\u0443 \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E: $4","error-diff-generic":"\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u0434\u0430\u043D\u0456 \u0440\u0456\u0437\u043D\u0438\u0446\u0456 \u043C\u0456\u0436 \u0432\u0435\u0440\u0441\u0456\u044F\u043C\u0438 \xABoldid=$1\xBB, \xABdiff=$2\xBB: $4","error-diff-compare-pages":'\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u0434\u0430\u043D\u0456 \u0440\u0456\u0437\u043D\u0438\u0446\u0456 \u043C\u0456\u0436 \u0441\u0442\u043E\u0440\u0456\u043D\u043A\u0430\u043C\u0438 "page1=$1", "page2=$2": $4',"error-diff-missingcontent":"\u0412\u0435\u0440\u0441\u0456\u044E \u043F\u0440\u0438\u0445\u043E\u0432\u0430\u043D\u043E","error-diff-nosuchrevid":"\u0412\u0435\u0440\u0441\u0456\u044E \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E","error-diff-missingtitle":"\u0421\u0442\u043E\u0440\u0456\u043D\u043A\u0443 \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E","error-api-generic":"\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0432\u0438\u043A\u043E\u043D\u0430\u0442\u0438 \u0437\u0430\u043F\u0438\u0442 API: $4","error-dependencies-generic":"\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u0437\u0430\u043B\u0435\u0436\u043D\u043E\u0441\u0442\u0456: $4","error-dependencies-revid":"\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u0437\u0430\u043B\u0435\u0436\u043D\u043E\u0441\u0442\u0456 \u0441\u0442\u043E\u0440\u0456\u043D\u043A\u0438 \xABcurid=$1\xBB: $4","error-dependencies-curid":"\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u0437\u0430\u043B\u0435\u0436\u043D\u043E\u0441\u0442\u0456 \u0441\u0442\u043E\u0440\u0456\u043D\u043A\u0438 \xABoldid=$1\xBB: $4","error-global-watchlist":"\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0432\u0438\u043A\u043E\u043D\u0430\u0442\u0438 Global Watchlist API: $4","error-setting-request":"\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u043D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u043D\u043D\u044F \u043A\u043E\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430: $4","error-setting-save":"\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0437\u0431\u0435\u0440\u0435\u0433\u0442\u0438 \u043D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u043D\u043D\u044F \u043A\u043E\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430: $4"}});var Un=se(Bn=>{Bn.loaders={en:()=>qn(),uk:()=>jn()}});var Hn=v(()=>{T();P();mw.hook("mw.translate.editor.showTranslationHelpers").add((i,e)=>{!e||!ke()||mw.hook(`${o.config.prefix}.process`).fire(e)})});var Gn=v(()=>{T();P();Ne();mw.hook("convenientDiscussions.preprocessed").add(i=>{if(!i)return;let e=s=>{!s||!s.isValid||!s.isProcessed||s.isForeign||!s.options.showPageLink||s.actions.cd||(s.extensions.cd={},s.extensions.cd.href=t(s),!l(s.extensions.cd.href)&&(s.actions.page&&s.actions.page.remove(),s.actions.cd=s.renderAction({label:Le("page"),title:p("comment-title"),href:s.extensions.cd.href,modifiers:["page","comment"]})))},t=s=>{if(!s.compare&&!s.revision)return;let n=s.getArticle().get("titleText"),r=i.api.pageRegistry.get(n);if(!r||!r.isProbablyTalkPage())return;if(s.revision?s.revision.revid&&(s.extensions.cd.date=new Date(s.revision.timestamp),s.extensions.cd.user=s.revision.user):s.compare&&(s.compare.torevid?(s.extensions.cd.date=new Date(s.compare.totimestamp),s.extensions.cd.user=s.compare.touser):s.compare.fromrevid&&(s.extensions.cd.date=new Date(s.compare.fromtimestamp),s.extensions.cd.user=s.compare.fromuser)),s.extensions.cd.date&&s.extensions.cd.user)try{s.extensions.cd.anchor=i.api.generateCommentId(s.extensions.cd.date,s.extensions.cd.user)}catch(u){Pe("Gadget-ConvenientDiscussions","Unable to generate comment anchor.",u)}if(!s.extensions.cd.anchor)return;let c=`#${s.extensions.cd.anchor}`;return n!==o.local.mwTitleText&&(c=mw.util.getUrl(`${n}${c}`)),c};if(o.isRunCompleted)for(let s of I.getLinks())e(s);mw.hook(`${o.config.prefix}.link.renderSuccess`).add(s=>{s&&e(s)})})});var _n=v(()=>{T();mw.hook(`${o.config.prefix}.page.complete`).add(i=>{var t;if(!i)return;((t=i.getContainer())==null?void 0:t.find('[id^="tw-revert"] a')).each((s,n)=>{n.addEventListener("click",()=>i.close())})})});var zn=v(()=>{T();mw.hook(`${o.config.prefix}.page.beforeDetach`).add(i=>{if(!i)return;let e=i.getDiffTable();typeof wikEd!="undefined"&&wikEd.diffTableLinkified&&(e==null?void 0:e.length)>0&&wikEd.diffTable===e.get(0)&&(wikEd.diffTableLinkified=!1)})});var Kn=v(()=>{T();P();mw.hook("wikipage.content").add(()=>{if(!ke()||mw.config.get("skin")!=="citizen")return;let i=(s,n)=>{try{let r=new URL(s.href);l(r.searchParams.get("diff"))&&(r.searchParams.set("diff","cur"),s.href=r.href),s.dataset.instantdiffsLink="basic",s.dataset.instantdiffsOptions=JSON.stringify({showLink:!1,showPageLink:!1,showAltTitle:!0}),mw.hook(`${o.config.prefix}.process`).fire($(n))}catch(r){Pe("Skin-Citizen","Unable to append the link action.",r)}},e=document.querySelector("#citizen-lastmod-relative"),t=document.querySelector("#citizen-sidebar-lastmod");e&&t&&i(e,t)})});var Ko={};var Qn=v(()=>{Hn();Gn();_n();zn();Kn()});T();var ne={version:"5.5.1",link:"Instant_Diffs",discussion:"Talk:Instant_Diffs",outname:"instantDiffs",outdir:"dist",origin:"https://www.mediawiki.org",server:"https://test.wikipedia.org",prefix:"instantDiffs",messagePrefix:"instant-diffs",settingsPrefix:"userjs-instantDiffs",dependencies:{styles:"/w/index.php?title=User:Serhio_Magpie/instantDiffs.css&action=raw&ctype=text/css",messages:"/w/index.php?title=User:Serhio_Magpie/instantDiffs-i18n/$lang.js&action=raw&ctype=text/javascript",main:["oojs","mediawiki.api","mediawiki.util","mediawiki.user","mediawiki.storage","mediawiki.notification","mediawiki.ForeignApi","mediawiki.Title"],settings:["oojs","oojs-ui-core","oojs-ui-widgets","oojs-ui-windows","oojs-ui.styles.icons-interactions"],window:["oojs","oojs-ui-core","oojs-ui-widgets","oojs-ui-windows","oojs-ui.styles.icons-accessibility","oojs-ui.styles.icons-movement","oojs-ui.styles.icons-content","oojs-ui.styles.icons-alerts","oojs-ui.styles.icons-interactions","oojs-ui.styles.icons-moderation","oojs-ui.styles.icons-editing-core","oojs-ui.styles.icons-editing-advanced","oojs-ui.styles.icons-user","oojs-ui.styles.icons-layout"],content:["jquery.confirmable","mediawiki.DateFormatter","mediawiki.codex.messagebox.styles","mediawiki.interface.helpers.styles","mediawiki.diff","mediawiki.diff.styles","mediawiki.misc-authed-curate","mediawiki.page.watch.ajax","ext.flaggedRevs.basic","ext.visualEditor.diffPage.init"],page:{"*":["ext.thanks.corethank","ext.checkUser.styles","ext.checkUser.userInfoCard"]},revision:{6:["filepage","wikibase.mediainfo.filepage.styles","wikibase.mediainfo.statements","wikibase.mediainfo.statements.styles"],14:["mediawiki.page.gallery.styles"],146:["wikibase.lexeme.styles"]},skins:{minerva:{"*":["codex-styles","skins.minerva.categories.styles"]}}},foreignDependencies:{revision:{styles:{6:["wikibase.mediainfo.filepage.styles","wikibase.mediainfo.statements","wikibase.mediainfo.statements.styles"],146:["wikibase.lexeme.styles"]},links:{6:["MediaWiki:Filepage.css"]},wikibase:{styles:{all:["jquery.wikibase.toolbar.styles","wikibase.view.ControllerViewFactory","wikibase.alltargets"],desktop:["wikibase.desktop"],mobile:["wikibase.mobile"]}}}},settings:{},defaults:{debug:!1,GM:!1,standalone:!1,storageExpiry:86400,logTimers:!0,expEnableWatchlistPopup:!1},include:{pageActions:["view","history"]},exclude:{pages:[],linkActions:["edit","history"]},labels:{page:{ltr:"\u2794",rtl:"\u{1F870}"},diff:"\u2756",revision:"\u272A",error:"\u{1D4D4}"},breakpoints:{mobileUp:"(min-width: 640px)",mobileDown:"(max-width: 639px)"},wikilinkPresets:{link:{page:"[$href $msg]",diff:"[$href $msg]",revision:"[$href $msg]"},special:{page:"[[$prefSpecial:Redirect/page/$1|$msg]]",diff:"[[$prefSpecial:Diff/$1|$msg]]",revision:"[[$prefSpecial:PermanentLink/$1|$msg]]"}},commonsAssetsPath:"https://upload.wikimedia.org/wikipedia/commons",changeLists:["Watchlist","Recentchanges","Recentchangeslinked"],contributionLists:["Contributions","GlobalContributions"],otherLists:["Newpages","PendingChanges","GlobalWatchlist"],specialPages:["Special:Diff","Special:Permalink","Special:PermanentLink","Special:MobileDiff","Special:Redirect","Special:ComparePages","Special:Undelete"],nonEditableContentModels:["wikibase-item","wikibase-property","wikibase-lexeme"],skinBodyClasses:{"vector-2022":["mw-body","vector-body"],vector:["vector-body"],monobook:["monobook-body"],minerva:["content"],timeless:["mw-body"],fandomdesktop:["page-content"],fandommobile:["page-content"]},bodyContentSelector:{minerva:"#content",default:"#bodyContent"},contentSelector:"#mw-content-text",specialPagesLinks:["Special:Diff","Special:Permalink","Special:PermanentLink","Special:MobileDiff","Special:Redirect"],specialPagesLinksSearchRegExp:"^($1)",specialPagesLinksPathRegExp:"$1($2)",specialPagesLinksSelector:'a[title^="$1"]',articlePathRegExp:"^($1)",sectionRegExp:/^\/\*\s*(.*?)\s*\*\/.*$/,linkSelector:["a[data-instantdiffs-link]",'a.external[href^="$1"]',"a.mw-changeslist-date","a.mw-changeslist-diff","a.mw-changeslist-diff-cur","a.mw-changeslist-groupdiff",".mw-changeslist-line a.extiw",".mw-fr-reviewlink a",".mw-enhanced-rc-time a",".mw-history-histlinks a",".mw-diff-bytes + a",".mw-contributions-list .comment a",".mw-fr-pending-changes-table a.cdx-docs-link","#mw-revision-nav a","table.diff #differences-prevlink","table.diff #differences-nextlink",".mw-diff-revision-history-links a",".mw-logevent-loglines a","[data-afl-log-id] a",'li[class^="mw-tag"] a',"a.ext-globalwatchlist-diff",".wikibase-statementview-references a","a.edit-summary-time","#mw-fr-revision-messages a","#mw-fr-revision-details a"],mwLine:{selector:[".mw-changeslist-line",".mw-contributions-list li",".mw-fr-pending-changes-table tr",".mw-logevent-loglines li",".mw-special-AbuseLog [data-afl-log-id]",'.mw-special-EditTags li[class^="mw-tag"]',".ext-globalwatchlist-site li"],seen:["mw-changeslist-line-not-watched","mw-enhanced-not-watched","mw-changeslist-watchedseen"],unseen:["mw-changeslist-line-watched","mw-enhanced-watched","mw-changeslist-watchedunseen"]},mwLineTitle:{selector:[".mw-changeslist-title",".mw-contributions-title",".mw-newpages-pagename",".mw-fr-pending-changes-page-title"]},mwLink:{id:["differences-prevlink","differences-nextlink"],hasClass:["mw-diff-revision-history-link-prev","mw-diff-revision-history-link-next","mw-changeslist-date","mw-changeslist-diff","mw-changeslist-diff-cur","mw-changeslist-groupdiff","mw-newpages-time"],closestTo:[".mw-changeslist-line",".mw-contributions-list",".mw-history-histlinks",".mw-pager-navigation-bar + ul",".mw-fr-hist-difflink","#mw-fr-reviewnotice","#mw-fr-revisiontag","#mw-fr-revisiontag-edit","#mw-fr-revision-tag-edit",".mw-specialpage-summary","#mw-revision-nav",".mw-fr-pending-changes-table",".mw-logevent-loglines",".mw-special-AbuseLog li[data-afl-log-id]",'.mw-special-EditTags li[class^="mw-tag"]',".wikibase-statementview-references",".ext-globalwatchlist-site",".tux-message-editor",".mw-pt-translate-header"]},mwLinkExclude:{hasClass:["mw-contributions-title"]},mwLinkDiffOnly:{id:["differences-prevlink","differences-nextlink"],closestTo:["#mw-revision-nav"]},mwLinkPrepend:{id:["differences-nextlink"],hasClass:["mw-diff-revision-history-link-next"]},mwLinkAltTitle:{closestTo:[".mw-fr-reviewlink",".mw-history-histlinks"]},mwLinkContent:{closestTo:[".mw-parser-output"]},mwLinkContentInside:{closestTo:[".comment"]}},Cs={messages:{},settings:{},defaults:{},require:null,language:null,linkSelector:null,mwIsAnon:!0,mwEndPoint:null,mwEndPointUrl:null,mwAction:null,mwArticlePath:null,mwCanonicalSpecialPageName:null,mwTitle:null,mwTitleText:null,mwServers:[],mwServerNames:[],specialPagesLocalPrefixed:{},specialPagesAliases:{},specialPagesAliasesFlat:[],specialPagesAliasesPrefixed:{},specialPagesAliasesPrefixedFlat:[],specialPagesLinksAliases:{},specialPagesLinksAliasesFlat:[],specialPagesLinksAliasesPrefixed:{},specialPagesLinksAliasesPrefixedFlat:[],specialPagesLinksPathRegExp:null,specialPagesLinksSearchRegExp:null,articlePathRegExp:null,mutationObserver:null,interactionObserver:null},Ms={};P();G();Gt();H();pe();kt();Ne();Wt();ls();fs();pe();kt();ae();var xs=class extends ce{constructor(t){super(j(f({article:{}},t),{ariaHaspopup:!0,handler:()=>this.openDialog()}));a(this,"article");this.article=new V(this.options.article)}openDialog(){let t={onOpen:()=>this.onDialogOpen(),onClose:()=>this.onDialogClose()};if(A.setup(this,t))return this.onDialogRequest(),$.when(A.load()).always(()=>this.onDialogLoad())}onDialogRequest(){this.pending(!0),this.emit("loading")}onDialogLoad(){this.pending(!1),this.emit("loaded")}onDialogOpen(){this.emit("opened")}onDialogClose(){this.emit("closed")}getArticle(){return this.article}},Zt=xs;T();O();var Ds=class extends Zt{constructor(){super(...arguments);a(this,"nodes",{})}openDialog(){this.nodes.$oldid=$('#mw-history-compare input[name="oldid"]:checked'),this.nodes.$oldidLine=this.nodes.$oldid.closest("li"),this.nodes.$diff=$('#mw-history-compare input[name="diff"]:checked'),this.nodes.$diffLine=this.nodes.$diff.closest("li"),this.article.set({type:"diff",title:o.local.mwTitleText,oldid:this.nodes.$oldid.val(),diff:this.nodes.$diff.val()}),super.openDialog()}onDialogOpen(){d.get("highlightLine")&&(this.nodes.$oldidLine.addClass("instantDiffs-line--highlight"),this.nodes.$diffLine.addClass("instantDiffs-line--highlight")),super.onDialogOpen()}onDialogClose(){d.get("highlightLine")&&(this.nodes.$oldidLine.removeClass("instantDiffs-line--highlight"),this.nodes.$diffLine.removeClass("instantDiffs-line--highlight")),super.onDialogClose()}},Ls=Ds;Qi();ae();O();var Qo=As({"../dist/instantDiffs-i18n-bundle.js":()=>Un()});function Jn(){if(!(o.isPageAdjustmentsApplied||!ke())){if(o.isPageAdjustmentsApplied=!0,document.body.classList.add("instantDiffs-enabled"),o.config.changeLists.includes(o.local.mwCanonicalSpecialPageName))return Jo();if(o.config.contributionLists.includes(o.local.mwCanonicalSpecialPageName))return Yo();if(o.local.mwCanonicalSpecialPageName==="GlobalWatchlist")return Xo();if(o.local.mwAction==="history")return er()}}function Jo(){$(".mw-changeslist-line").addClass("instantDiffs-line")}function Yo(){$(".mw-contributions-list .mw-changeslist-links:not(.mw-pager-tools) > span:first-child").each((e,t)=>{let s=$(t);s.find("a").length===0&&s.wrapInner(lt())}),o.local.mwCanonicalSpecialPageName==="GlobalContributions"&&Zo()}function Zo(){$(".mw-contributions-list li").each((e,t)=>{let s=$(t),n=s.find("a.mw-changeslist-date, a.mw-changeslist-history");if(n.length!==0)try{let r=new URL(n.prop("href"));te(s,r.origin)}catch(r){}})}function Xo(){let i=document.getElementById("ext-globalwatchlist-watchlistsfeed");o.local.mutationObserver.observe(i,{childList:!0})}function er(){let i=$("#pagehistory > li, #pagehistory .mw-contributions-list > li").addClass("instantDiffs-line--history");if(i.length<=1)return;i.each((t,s)=>{let n=$(s),r=n.find(".mw-history-histlinks > span:first-child"),c=n.find(".mw-history-histlinks > span:last-child");r.find("a").length===0&&r.wrapInner(lt()),c.find("a").length===0&&c.wrapInner(lt())}),$(".mw-history-compareselectedversions").each((t,s)=>{let r=$(s).find(".mw-history-compareselectedversions-button");new Ls({label:p("compare-label",o.config.labels.diff),title:p("compare-title",p("script-name")),classes:["mw-ui-button","cdx-button","instantDiffs-button--compare"],insertMethod:"insertAfter",container:r}),$("<span>").text(" ").addClass("instantDiffs-spacer").insertAfter(r)})}function tr(i){var n,r,c;o.local.require=i,mw.util.addCSS(".instantDiffs-panel { display:none; }"),A.mixin(),d.mixin(),bi(A),bi(d),OO.mixinClass(ce,OO.EventEmitter),OO.mixinClass($e,OO.EventEmitter),o.local.mwIsAnon=(c=(r=(n=mw.user)==null?void 0:n.isAnon)==null?void 0:r.call(n))!=null?c:!0,o.local.mwEndPoint=`${location.origin}${mw.config.get("wgScript")}`,o.local.mwEndPointUrl=new URL(o.local.mwEndPoint),o.local.mwAction=mw.config.get("wgAction"),o.local.mwArticlePath=mw.config.get("wgArticlePath").replace("$1",""),o.local.mwCanonicalSpecialPageName=mw.config.get("wgCanonicalSpecialPageName"),o.local.mwTitle=new mw.Title(mw.config.get("wgRelevantPageName")),o.local.mwTitleText=o.local.mwTitle.getPrefixedText();let e=ks();mw.config.set("wgMobileServer",e),mw.config.set("wgMobileServerName",ee("hostname",e));let t=[mw.config.get("wgServer"),mw.config.get("wgMobileServer")].filter(u=>!l(u)).map(at);o.local.mwServers=X(t);let s=[mw.config.get("wgServerName"),mw.config.get("wgMobileServerName")].filter(u=>!l(u));return o.local.mwServerNames=X(s),o.local.lastVersion=mw.storage.get(`${o.config.prefix}-version`),mw.storage.set(`${o.config.prefix}-version`,o.config.version),o.local.mutationObserver=new MutationObserver(hr),o.local.interactionObserver=new IntersectionObserver(ur,{threshold:0,rootMargin:d.get("debug")?"0px 0px 0px 0px":"33% 0px 33% 0px"}),window.addEventListener("pageshow",pr),window.addEventListener("beforeunload",gr),Promise.allSettled([k.getSpecialPages(),ir(),...sr()])}function ir(){return m(this,null,function*(){let{general:i}=(yield k.getSiteInfo())||{};if(!W(i)){l(i.mobileserver)||(mw.config.set("wgMobileServer",i.mobileserver),mw.config.set("wgMobileServerName",i.mobileservername));let e=[...o.local.mwServers,i.server,i.mobileserver].filter(s=>!l(s)).map(at);o.local.mwServers=X(e);let t=[...o.local.mwServerNames,i.servername,i.mobileservername].filter(s=>!l(s));o.local.mwServerNames=X(t)}})}function sr(){return["en",mw.config.get("wgUserLanguage")].filter((e,t,s)=>s.indexOf(e)===t&&!o.i18n[e]).map(e=>{let t=o.config.dependencies.messages.replace("$lang",e);return mw.loader.getScript(zt(t))})}function nr(){for(let[i,e]of Object.entries(k.specialPagesLocal))o.local.specialPagesLocalPrefixed[i]=new mw.Title(e).getPrefixedDb(),o.local.specialPagesAliases[i]=Yt(k.specialPagesLocal,i),o.local.specialPagesAliasesPrefixed[i]=Yt(o.local.specialPagesLocalPrefixed,i),o.config.specialPagesLinks.includes(i)&&(o.local.specialPagesLinksAliases[i]=o.local.specialPagesAliases[i],o.local.specialPagesLinksAliasesPrefixed[i]=o.local.specialPagesAliasesPrefixed[i]);o.local.specialPagesAliasesFlat=X(Object.values(o.local.specialPagesAliases).flat()),o.local.specialPagesAliasesPrefixedFlat=X(Object.values(o.local.specialPagesAliasesPrefixed).flat()),o.local.specialPagesLinksAliasesFlat=X(Object.values(o.local.specialPagesLinksAliases).flat()),o.local.specialPagesLinksAliasesPrefixedFlat=X(Object.values(o.local.specialPagesLinksAliasesPrefixed).flat())}function or(){o.local.articlePathRegExp=new RegExp(o.config.articlePathRegExp.replaceAll("$1",o.local.mwArticlePath));let i=[];o.config.linkSelector.forEach(t=>{/\$1/.test(t)?o.local.mwServers.forEach(s=>{i.push(t.replaceAll("$1",s))}):i.push(t)}),o.local.specialPagesLinksAliasesFlat.forEach(t=>{i.push(o.config.specialPagesLinksSelector.replaceAll("$1",t))});let e=o.local.specialPagesLinksAliasesPrefixedFlat.join("|");o.local.specialPagesLinksPathRegExp=new RegExp(o.config.specialPagesLinksPathRegExp.replaceAll("$1",o.local.mwArticlePath).replaceAll("$2",e)),o.local.specialPagesLinksSearchRegExp=new RegExp(o.config.specialPagesLinksSearchRegExp.replaceAll("$1",e)),o.local.linkSelector=i.join(",")}function rr(){var t;ne.settings=f(f({},ps()),ne.settings),ne.defaults=f(f({},gs()),ne.defaults);let i=f(f({},ne.settings),o.settings),e=f(f(f({},ne.defaults),o.defaults),ms());if(o.isRunning){o.isReplaced=fr(i,e),C(o.isReplaced?"error-prepare-replaced":"error-prepare-version",{tag:"app",message:`loaded: ${o.config.version}, concurrent: ${ne.version}`,silent:!0});return}o.isRunning=!0,(t=o).i18n||(t.i18n={}),o.config=ne,o.local=Cs,o.local.settings=i,o.local.defaults=e,o.timers=Ms,o.utils=y,o.modules={Api:k,Article:V,Link:I,Button:ce,ViewButton:Zt,HistoryCompareButton:Ls,Page:$e,LocalPage:Ft,GlobalPage:Vt,Watch:At,view:A,settings:d},o.timers.run=mw.now(),ar(),Kt(),Qn(),lr()}function ar(){let{loaders:i}=Qo(`../${o.config.outdir}/${o.config.outname}-i18n-bundle.js`);for(let e of Object.values(i))e()}function lr(){mw.loader.load(zt(o.config.dependencies.styles),"text/css"),mw.loader.using(o.config.dependencies.main).then(tr).then(()=>$(cr)).fail(i=>{C("error-prepare-generic",{tag:"app",message:i==null?void 0:i.message})})}function cr(){return m(this,null,function*(){if(yield d.processDefaults(),Kt(),mw.config.get("skin")==="minerva"&&!d.get("enableMobile")){C("error-prepare-mobile",{tag:"app",silent:!0});return}o.isReady=!0,nr(),or(),Jn(),o.timers.ready=mw.now(),mw.hook(`${o.config.prefix}.ready`).fire(o),mw.hook("wikipage.content").add(Yn),mw.hook(`${o.config.prefix}.process`).add(Zn),mw.hook(`${o.config.prefix}.replace`).add(dr)})}function Yn(i){!i||!ke()||(o.isFirstRun=!o.isRunCompleted,o.isFirstRun&&(o.isRunCompleted=!0,i=Fe()),Zn(i),d.get("logTimers")&&o.isFirstRun&&(ve("ready time",o.timers.run,o.timers.ready),ve("total time",o.timers.run,o.timers.processEnd)))}function Zn(i){if(!i)return;o.timers.processStart=mw.now(),o.timers.findLinksStart=mw.now();let e=I.findLinks(i);o.timers.findLinksEnd=mw.now();let t=[],s=[];for(let n of e){if(I.hasLink(n))continue;let r=new I(n);t.push(r),r.isValid&&s.push(r)}o.timers.processEnd=mw.now(),d.get("logTimers")&&t.length>0&&(de("info",`links found: ${t.length}`),de("info",`links processed: ${s.length}`),ve("links selector time",o.timers.findLinksStart,o.timers.findLinksEnd),ve("links process time",o.timers.processStart,o.timers.processEnd)),mw.hook(`${o.config.prefix}.processed`).fire(s)}function fr(i,e){return o.modules.settings.get("standalone")&&!e.standalone?(mw.hook(`${o.config.prefix}.replace`).fire(i,e),!0):!1}function dr(i,e){return m(this,null,function*(){!i||!e||(o.local.settings=i,o.local.defaults=e,o.isReady&&(yield d.processDefaults(),o.timers.run=mw.now(),o.timers.ready=mw.now(),Jn(),Yn(Fe())))})}function ur(i){o.isUnloading||i.forEach(e=>{if(!e.isIntersecting)return;let t=I.getLink(e.target);t&&t.onIntersect()})}function hr(i){o.isUnloading||i.forEach(e=>{e.addedNodes.length>0&&mw.hook(`${o.config.prefix}.process`).fire($(e.target))})}function pr(i){i.persisted&&(o.isUnloading=!1)}function gr(){o.isUnloading=!0}rr();})(); /* </nowiki> */ o2isuirs6gfqwlui2c3ctm705327tf6 User:কমলেশ মন্ডল/common.js 2 171554 740985 740945 2026-05-08T12:54:41Z কমলেশ মন্ডল 72403 740985 javascript text/javascript // <nowiki> (function ($, mw) { 'use strict'; const SPECIAL_PAGE_NAME = 'বিশেষ:খালি_পাতা/SideBySide'; const toBengaliNum = n => String(n).replace(/\d/g, d => '০১২৩৪৫৬৭৮৯'[d]); function init() { mw.loader.using(['mediawiki.util'], function () { mw.util.addPortletLink( 'p-tb', mw.util.getUrl(SPECIAL_PAGE_NAME) + '?origin=' + encodeURIComponent(mw.config.get('wgPageName')), 'পাশাপাশি তুলনা', 't-sidebyside', 'বাংলা ও ইংরেজি নিবন্ধ পাশাপাশি তুলনা করুন' ); if (mw.config.get('wgPageName') === SPECIAL_PAGE_NAME) { mw.loader.using(['mediawiki.api', 'mediawiki.util'], loadTool); } }); } /*--- CSS ---*/ function injectCSS() { if ($('#sbs-styles').length) return; $('<style id="sbs-styles">').text(` .sbs-wrap { max-width: 100%; box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; color: #202122; } .sbs-topbar { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; margin-bottom: 12px; padding: 16px; background: #fff; border: 1px solid #a2a9b1; border-radius: 4px; box-shadow: 0 1px 3px rgba(0,0,0,0.05); } .sbs-field { display: flex; flex-direction: column; gap: 5px; flex: 1; min-width: 180px; } .sbs-field label { font-size: 0.8em; font-weight: bold; color: #54595d; text-transform: uppercase; letter-spacing: 0.5px; } .sbs-field input { padding: 8px 10px; font-family: inherit; font-size: 1em; width: 100%; border: 1px solid #a2a9b1; border-radius: 4px; box-sizing: border-box; transition: border-color 0.25s, box-shadow 0.25s; } .sbs-field input:focus { border-color: #3366cc; outline: none; box-shadow: 0 0 0 2px rgba(51,102,204,0.2); } .sbs-field input:read-only { background: #f8f9fa; color: #72777d; cursor: default; } .sbs-btn-group { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; } .sbs-btn { padding: 8px 18px; border: 1px solid transparent; border-radius: 4px; font-size: 0.95em; font-weight: bold; cursor: pointer; transition: all 0.15s; white-space: nowrap; line-height: 1.4; } .sbs-btn:disabled { opacity: 0.45; cursor: not-allowed; } .sbs-btn.primary { background: #3366cc; color: #fff; } .sbs-btn.primary:hover:not(:disabled) { background: #2a4b8d; } .sbs-btn.success { background: #14866d; color: #fff; } .sbs-btn.success:hover:not(:disabled) { background: #0f6b56; } .sbs-btn.neutral { background: #f8f9fa; color: #202122; border-color: #a2a9b1; } .sbs-btn.neutral:hover:not(:disabled) { background: #fff; border-color: #3366cc; color: #3366cc; } .sbs-btn.danger { background: #fff; color: #d33; border-color: #d33; } .sbs-btn.danger:hover:not(:disabled) { background: #fee7e6; } .sbs-btn.locked { background: #3366cc; color: #fff; border-color: #3366cc; } .sbs-undo-group { display: flex; gap: 6px; align-items: flex-end; } .sbs-icon-btn { width: 38px; height: 38px; border: 1px solid #a2a9b1; border-radius: 4px; background: #f8f9fa; cursor: pointer; font-size: 1.3em; display: flex; align-items: center; justify-content: center; transition: all 0.15s; color: #202122; flex-shrink: 0; font-weight: bold; line-height: 1; } .sbs-icon-btn:hover:not(:disabled) { background: #fff; border-color: #3366cc; color: #3366cc; } .sbs-icon-btn:disabled { opacity: 0.4; cursor: not-allowed; } .sbs-status { font-size: 0.9em; color: #54595d; margin-bottom: 10px; min-height: 1.4em; font-weight: 500; } .sbs-count-bar { display: none; font-size: 0.88em; color: #3366cc; font-weight: 600; margin-bottom: 10px; padding: 7px 14px; background: #eaf3fb; border-radius: 4px; border: 1px solid #c8d8f0; } .sbs-grid-wrap { display: none; border: 1px solid #a2a9b1; border-radius: 4px; background: #fff; box-shadow: 0 2px 6px rgba(0,0,0,0.05); overflow: hidden; } .sbs-col-headers { display: grid; grid-template-columns: 1fr 1fr; background: #eaecf0; border-bottom: 2px solid #c8ccd1; position: relative; z-index: 5; } .sbs-col-header { padding: 10px 16px; font-size: 0.82em; font-weight: bold; color: #202122; text-transform: uppercase; letter-spacing: 0.4px; } .sbs-col-header:first-child { border-right: 1px solid #c8ccd1; } .sbs-panels { display: grid; grid-template-columns: 1fr 1fr; max-height: 76vh; overflow: hidden; } .sbs-panel-en, .sbs-panel-bn { position: relative; overflow-y: scroll; overflow-x: hidden; max-height: 76vh; box-sizing: border-box; } .sbs-panel-en { border-right: 1px solid #a2a9b1; background: #f8f9fa; } .sbs-panel-bn { background: #fff; } .sbs-sec-hdr-en, .sbs-sec-hdr-bn { padding: 9px 16px; font-size: 0.92em; font-weight: bold; color: #3366cc; background: #eaf3fb; border-top: 2px solid #a2a9b1; border-bottom: 1px solid #c8d8f0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: flex; align-items: center; } .sbs-sec-num { display: inline-block; background: #3366cc; color: #fff; border-radius: 10px; padding: 0 6px; font-size: 0.75em; margin-right: 4px; vertical-align: middle; font-weight: bold; line-height: 1.7; } .sbs-cell-en { padding: 20px 18px; font-size: 1em; line-height: 1.75; color: #202122; white-space: pre-wrap; word-break: break-word; box-sizing: border-box; border-bottom: 1px solid #eaecf0; min-height: 100px; } .sbs-cell-bn { box-sizing: border-box; border-bottom: 1px solid #eaecf0; min-height: 100px; } .sbs-cell-bn textarea { width: 100%; border: none; font-family: inherit; font-size: 1em; line-height: 1.75; resize: none; background: transparent; padding: 20px 18px; color: #202122; outline: none; box-sizing: border-box; overflow: hidden; min-height: 100px; display: block; } @media (max-width: 768px) { .sbs-col-headers, .sbs-panels { grid-template-columns: 1fr; } .sbs-panel-en { border-right: none; border-bottom: 1px solid #a2a9b1; max-height: 40vh; } .sbs-panel-bn { max-height: 50vh; } } `).appendTo('head'); } /*--- Wikitext helpers ---*/ function parseByHeadings(wikitext) { const lines = wikitext.split('\n'); const sections = []; let current = { heading: null, level: 0, content: [] }; for (const line of lines) { const m = line.match(/^(={1,6})\s*(.+?)\s*\1\s*$/); if (m) { sections.push(current); current = { heading: m[2].trim(), level: m[1].length, content: [] }; } else { current.content.push(line); } } sections.push(current); return sections.filter(s => s.heading != null || s.content.join('\n').trim().length > 0); } function sectionToText(sec) { return sec.content.join('\n').trim(); } function sectionsToWikitext(sections) { return sections.filter(sec => { const body = sec.content.join('\n').trim(); return body.length > 0; }).map(sec => { const h = '='.repeat(sec.level); if (sec.heading === null) return sec.content.join('\n').trimEnd(); return h + ' ' + sec.heading + ' ' + h + '\n' + sec.content.join('\n').trimEnd(); }).join('\n\n'); } function deepClone(sections) { return sections.map(s => ({ heading: s.heading, level: s.level, content: [...s.content], isPlaceholder: s.isPlaceholder })); } /* Count bar */ function updateCountBar(bnSections, $bar) { const total = bnSections.length; const withText = bnSections.filter(s => sectionToText(s).length > 0).length; const empty = total - withText; $bar.html( '<strong>' + toBengaliNum(total) + '</strong> টি বিভাগ' + '&nbsp;&nbsp;|&nbsp;&nbsp;' + '<strong style="color: #14866d">' + toBengaliNum(withText) + '</strong> টি পাঠ্য সহ' + '&nbsp;&nbsp;|&nbsp;&nbsp;' + '<strong style="color: #d33">' + toBengaliNum(empty) + '</strong> টি খালি' ).show(); } /*--- API helpers ---*/ async function getEnTitle(bnTitle, api) { try { const r = await api.get({ action: 'query', titles: bnTitle, prop: 'pageprops', ppprop: 'wikibase_item', formatversion: 2 }); const page = r.query.pages[0]; if (!page || page.missing) return null; const qid = page.pageprops && page.pageprops.wikibase_item; if (!qid) return null; const wdApi = new mw.ForeignApi('https://www.wikidata.org/w/api.php'); const wd = await wdApi.get({ action: 'wbgetentities', ids: qid, props: 'sitelinks', sitefilter: 'enwikibooks', formatversion: 2 }); const sl = wd.entities[qid] && wd.entities[qid].sitelinks && wd.entities[qid].sitelinks.enwikibooks; return sl ? sl.title : null; } catch (e) { return null; } } async function fetchWikitext(title, isEn) { const apiobj = isEn ? new mw.ForeignApi('https://en.wikibooks.org/w/api.php') : new mw.Api(); const data = await apiobj.get({ action: 'query', titles: title, prop: 'revisions', rvprop: 'content', rvslots: 'main', formatversion: 2 }); const page = data.query.pages[0]; if (page.missing) throw new Error('পাতা পাওয়া যায়নি: ' + title); return page.revisions[0].slots.main.content; } /* Main tool */ function loadTool() { document.title = 'পাশাপাশি তুলনা - বাংলা উইকিবই'; $('#firstHeading').text('পাশাপাশি তুলনা সরঞ্জাম'); $('#mw-content-text').empty(); injectCSS(); const api = new mw.Api(); const urlParams = new URLSearchParams(window.location.search); const originPage = urlParams.get('origin') || ''; const wrap = $('<div>').addClass('sbs-wrap'); $('#mw-content-text').append(wrap); /* Top bar */ const topbar = $('<div>').addClass('sbs-topbar'); const bnField = $('<div>').addClass('sbs-field'); const bnInput = $('<input type="text">').val(originPage).attr('placeholder', 'বাংলা শিরোনাম'); bnField.append($('<label>').text('বাংলা নিবন্ধ'), bnInput); const enField = $('<div>').addClass('sbs-field'); const enInput = $('<input type="text">').attr('placeholder', 'English title'); enField.append($('<label>').text('ইংরেজি নিবন্ধ'), enInput); const btnGroup = $('<div>').addClass('sbs-btn-group'); const mainBtn = $('<button>').addClass('sbs-btn primary').text('লোড করুন'); const discardBtn = $('<button>').addClass('sbs-btn danger').text('বাতিল').hide(); const undoGroup = $('<div>').addClass('sbs-undo-group').hide(); const undoBtn = $('<button>').addClass('sbs-icon-btn').attr('title', 'পূর্বাবস্থায় ফেরান').html('&#8592;'); const redoBtn = $('<button>').addClass('sbs-icon-btn').attr('title', 'পুনরায় করুন').html('&#8594;'); undoGroup.append(undoBtn, redoBtn); const scrollLockBtn = $('<button>').addClass('sbs-btn neutral').attr('title', 'স্ক্রল লক').text('স্ক্রল মুক্ত').hide(); btnGroup.append(mainBtn, discardBtn, scrollLockBtn, undoGroup); topbar.append(bnField, enField, btnGroup); wrap.append(topbar); const status = $('<div>').addClass('sbs-status'); wrap.append(status); let statusTimeout; function setStatus(msg, autoClear = false) { status.text(msg); clearTimeout(statusTimeout); if (autoClear) { statusTimeout = setTimeout(() => status.text(''), 4000); } } const countBar = $('<div>').addClass('sbs-count-bar'); wrap.append(countBar); /* Grid: col-headers + two scroll panels */ const gridWrap = $('<div>').addClass('sbs-grid-wrap'); const colHeaders = $('<div>').addClass('sbs-col-headers').append( $('<div>').addClass('sbs-col-header').text('ইংরেজি (শুধু পড়ুন)'), $('<div>').addClass('sbs-col-header').text('বাংলা (সম্পাদনা যোগ্য)') ); const panels = $('<div>').addClass('sbs-panels'); const panelEn = $('<div>').addClass('sbs-panel-en'); const panelBn = $('<div>').addClass('sbs-panel-bn'); panels.append(panelEn, panelBn); gridWrap.append(colHeaders, panels); wrap.append(gridWrap); /* Scroll lock */ let scrollLocked = false; let isSyncing = false; function syncScroll(source, target) { if (!scrollLocked || isSyncing) return; isSyncing = true; const sourceNodes = source.children('.sbs-sec-hdr-en, .sbs-sec-hdr-bn'); const targetNodes = target.children('.sbs-sec-hdr-en, .sbs-sec-hdr-bn'); const sourceScrollTop = source[0].scrollTop; let topIdx = 0; sourceNodes.each(function (i) { if (this.offsetTop < sourceScrollTop + 5) { topIdx = i; } else { return false; } }); const srcElem = sourceNodes[topIdx]; const tgtElem = targetNodes[topIdx]; if (srcElem && tgtElem) { const srcCell = $(srcElem).next()[0]; const tgtCell = $(tgtElem).next()[0]; const scrolledPastElem = sourceScrollTop - srcElem.offsetTop; const srcHeight = (srcElem.offsetHeight + (srcCell ? srcCell.offsetHeight : 0)) || 1; const tgtHeight = tgtElem.offsetHeight + (tgtCell ? tgtCell.offsetHeight : 0); const ratio = Math.max(0, scrolledPastElem / srcHeight); target[0].scrollTop = tgtElem.offsetTop + (tgtHeight * ratio); } else { const ratio = source[0].scrollTop / Math.max(1, source[0].scrollHeight - source[0].clientHeight); target[0].scrollTop = ratio * (target[0].scrollHeight - target[0].clientHeight); } isSyncing = false; } panelEn.on('scroll', () => syncScroll(panelEn, panelBn)); panelBn.on('scroll', () => syncScroll(panelBn, panelEn)); scrollLockBtn.on('click', () => { scrollLocked = !scrollLocked; if (scrollLocked) { scrollLockBtn.text('স্ক্রল লক').addClass('locked'); syncScroll(panelBn, panelEn); } else { scrollLockBtn.text('স্ক্রল মুক্ত').removeClass('locked'); } }); /* State */ let enSections = [], bnSections = [], baselineSections = []; let currentBnTitle = ''; let activeTA = null, undoStack = [], redoStack = []; let phase = 'load'; function resizeTA(ta) { ta.style.height = 'auto'; ta.style.height = ta.scrollHeight + 'px'; } /* Undo / Redo */ function applyUndoRedo(val) { if (!activeTA) return; activeTA.val(val); const idx = activeTA.data('idx'); bnSections[idx].content = val.split('\n'); resizeTA(activeTA[0]); updateCountBar(bnSections, countBar); } function holdToRepeat(btn, action) { let holdTimer = null; let repeatTimer = null; function stop() { clearTimeout(holdTimer); clearInterval(repeatTimer); holdTimer = null; repeatTimer = null; } btn[0].addEventListener('pointerdown', function (e) { if (e.button !== undefined && e.button !== 0) return; e.preventDefault(); this.setPointerCapture(e.pointerId); action(); holdTimer = setTimeout(function () { repeatTimer = setInterval(action, 80); }, 400); }); btn[0].addEventListener('pointerup', stop); btn[0].addEventListener('pointercancel', stop); } holdToRepeat(undoBtn, () => { if (!activeTA || !undoStack.length) return; redoStack.push(activeTA.val()); applyUndoRedo(undoStack.pop()); }); holdToRepeat(redoBtn, () => { if (!activeTA || !redoStack.length) return; undoStack.push(activeTA.val()); applyUndoRedo(redoStack.pop()); }); function lockInputs() { bnInput.prop('readonly', true); enInput.prop('readonly', true); } function unlockInputs() { bnInput.prop('readonly', false); enInput.prop('readonly', false); } function setPhase(p) { phase = p; if (p === 'load') { mainBtn.text('লোড করুন').removeClass('success neutral').addClass('primary'); discardBtn.hide(); undoGroup.hide(); gridWrap.hide(); countBar.hide(); scrollLockBtn.hide(); unlockInputs(); } else if (p === 'save') { mainBtn.text('সংরক্ষণ করুন').removeClass('primary neutral').addClass('success'); discardBtn.show(); undoGroup.show(); gridWrap.show(); scrollLockBtn.show(); lockInputs(); } else if (p === 'back') { mainBtn.text('মূল পাতায় ফিরুন').removeClass('primary success').addClass('neutral'); discardBtn.show(); undoGroup.show(); scrollLockBtn.show(); lockInputs(); } } /* Build grid */ function buildGrid() { panelEn.empty(); panelBn.empty(); activeTA = null; undoStack = []; redoStack = []; const isLead = s => s.heading == null; const isHeading = s => s.heading != null; const enLeads = enSections.filter(isLead); const bnLeads = bnSections.filter(isLead); const enHeads = enSections.filter(isHeading); const bnHeads = bnSections.filter(isHeading); const displayPairs = []; const maxLeads = Math.max(enLeads.length, bnLeads.length); for (let i = 0; i < maxLeads; i++) displayPairs.push({ en: enLeads[i] || null, bn: bnLeads[i] || null }); const maxHeads = Math.max(enHeads.length, bnHeads.length); for (let i = 0; i < maxHeads; i++) displayPairs.push({ en: enHeads[i] || null, bn: bnHeads[i] || null }); bnSections = displayPairs.map(pair => { if (pair.bn) return pair.bn; return { heading: pair.en ? pair.en.heading : null, level: pair.en ? pair.en.level : 2, content: [], isPlaceholder: true }; }); updateCountBar(bnSections, countBar); displayPairs.forEach((pair, i) => { const enSec = pair.en; const bnSec = bnSections[i]; const enText = enSec ? sectionToText(enSec) : ''; const bnText = sectionToText(bnSec); const num = toBengaliNum(i + 1); const enTitle = enSec ? (enSec.heading !== null ? enSec.heading : '(ভূমিকা)') : '(অনুপস্থিত)'; const bnTitleFallback = enSec && enSec.heading !== null ? enSec.heading : '(ভূমিকা)'; const bnTitleVal = bnSec.heading !== null ? bnSec.heading : ''; const numBadge = () => $('<span>').addClass('sbs-sec-num').text(num); const enHdr = $('<div>').addClass('sbs-sec-hdr-en').append(numBadge(), document.createTextNode(' ' + enTitle)); const enCell = $('<div>').addClass('sbs-cell-en').text(enText); panelEn.append(enHdr, enCell); const isIntroSection = bnTitleFallback === '(ভূমিকা)'; const bnHdr = $('<div>').addClass('sbs-sec-hdr-bn'); const bnHdrInput = $('<input type="text">') .val(bnTitleVal) .attr('placeholder', bnTitleFallback) .css({ 'background': 'transparent', 'border': 'none', 'border-bottom': '1px solid transparent', 'color': 'inherit', 'font-family': 'inherit', 'font-size': 'inherit', 'font-weight': 'inherit', 'width': 'calc(100% - 35px)', 'outline': 'none', 'padding': '0 4px', 'margin-left': '4px', 'cursor': isIntroSection ? 'default' : 'text' }); if (isIntroSection) { bnHdrInput.attr('readonly', true); } else { bnHdrInput .on('focus', function () { $(this).css({ 'background': '#fff', 'border-bottom': '1px solid #3366cc' }); }) .on('blur', function () { $(this).css({ 'background': 'transparent', 'border-bottom': '1px solid transparent' }); }) .on('input', function () { bnSec.heading = $(this).val().trim() || null; if (phase === 'back') setPhase('save'); }); } bnHdr.append(numBadge(), bnHdrInput); const bnCell = $('<div>').addClass('sbs-cell-bn'); const ta = $('<textarea>').val(bnText).attr('placeholder', 'অনুবাদ লিখুন...').data('idx', i); ta.on('focus', () => { if (activeTA && activeTA[0] !== ta[0]) { undoStack = []; redoStack = []; } activeTA = ta; }); ta.on('input', (function (idx) { return function () { resizeTA(ta[0]); undoStack.push(sectionToText(bnSections[idx])); if (undoStack.length > 50) undoStack.shift(); redoStack = []; bnSections[idx].content = ta.val().split('\n'); updateCountBar(bnSections, countBar); if (phase === 'back') setPhase('save'); }; })(i)); /* Paste fix: preserve panel scroll position so the cursor does not disappear behind the sticky header div on paste. The scroll event listeners and syncScroll logic are completely untouched. */ ta.on('paste', function () { const panel = panelBn[0]; const savedScrollTop = panel.scrollTop; requestAnimationFrame(function () { resizeTA(ta[0]); panel.scrollTop = savedScrollTop; }); }); bnCell.append(ta); panelBn.append(bnHdr, bnCell); setTimeout(() => resizeTA(ta[0]), 0); }); } /* Wikidata auto-fetch */ if (originPage) { setStatus('উইকিডেটা থেকে ইংরেজি শিরোনাম খোঁজা হচ্ছে...'); getEnTitle(originPage, api).then(t => { if (t) { enInput.val(t); setStatus('ইংরেজি শিরোনাম পাওয়া গেছে।', true); } else { setStatus('উইকিডেটায় সংযোগ পাওয়া যায়নি। নিজে লিখুন।', true); } }); } /* Discard */ discardBtn.on('click', () => { if (!confirm('পরিবর্তনগুলো বাতিল করবেন?')) return; bnSections = deepClone(baselineSections); buildGrid(); setPhase('back'); mw.notify('পরিবর্তন বাতিল করা হয়েছে।', { type: 'info' }); setStatus('', true); }); /* Main button */ mainBtn.on('click', async () => { const bnTitle = bnInput.val().trim(); const enTitle = enInput.val().trim(); if (phase === 'load') { if (!bnTitle || !enTitle) { setStatus('দুটি শিরোনামই লিখুন।', true); return; } try { mainBtn.prop('disabled', true).text('লোড হচ্ছে...'); setStatus('নিবন্ধ লোড হচ্ছে...'); const [enWT, bnWT] = await Promise.all([ fetchWikitext(enTitle, true), fetchWikitext(bnTitle, false) ]); currentBnTitle = bnTitle; enSections = parseByHeadings(enWT); bnSections = parseByHeadings(bnWT); baselineSections = deepClone(bnSections); buildGrid(); setPhase('save'); setStatus('লোড সম্পন্ন।', true); } catch (e) { setStatus('ত্রুটি: ' + e.message); mainBtn.prop('disabled', false).text('লোড করুন'); } mainBtn.prop('disabled', false); } else if (phase === 'save') { mainBtn.prop('disabled', true).text('সংরক্ষণ করা হচ্ছে...'); try { await api.postWithToken('csrf', { action: 'edit', title: currentBnTitle, text: sectionsToWikitext(bnSections), summary: 'পাশাপাশি সরঞ্জাম (স্ক্রিপ্ট)' }); baselineSections = deepClone(bnSections); setPhase('back'); setStatus('সংরক্ষণ সম্পন্ন হয়েছে।', true); mw.notify('সংরক্ষণ সম্পন্ন হয়েছে।', { type: 'success' }); } catch (e) { setStatus('সংরক্ষণ ব্যর্থ: ' + e); mw.notify('সংরক্ষণ ব্যর্থ: ' + e, { type: 'error' }); } mainBtn.prop('disabled', false); } else if (phase === 'back') { const ret = originPage || currentBnTitle; if (ret) window.location.href = mw.util.getUrl(ret); } }); setPhase('load'); } $(document).ready(init); })(jQuery, mediaWiki); // </nowiki> 675drudp0hyh1u0eshxv8p80gcvftu3 740991 740985 2026-05-08T13:08:10Z কমলেশ মন্ডল 72403 740991 javascript text/javascript // <nowiki> (function ($, mw) { 'use strict'; const SPECIAL_PAGE_NAME = 'বিশেষ:খালি_পাতা/SideBySide'; const toBengaliNum = n => String(n).replace(/\d/g, d => '০১২৩৪৫৬৭৮৯'[d]); function init() { mw.loader.using(['mediawiki.util'], function () { mw.util.addPortletLink( 'p-tb', mw.util.getUrl(SPECIAL_PAGE_NAME) + '?origin=' + encodeURIComponent(mw.config.get('wgPageName')), 'পাশাপাশি তুলনা', 't-sidebyside', 'বাংলা ও ইংরেজি নিবন্ধ পাশাপাশি তুলনা করুন' ); if (mw.config.get('wgPageName') === SPECIAL_PAGE_NAME) { mw.loader.using(['mediawiki.api', 'mediawiki.util'], loadTool); } }); } /*--- CSS ---*/ function injectCSS() { if ($('#sbs-styles').length) return; $('<style id="sbs-styles">').text(` .sbs-wrap { max-width: 100%; box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; color: #202122; } .sbs-topbar { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; margin-bottom: 12px; padding: 16px; background: #fff; border: 1px solid #a2a9b1; border-radius: 4px; box-shadow: 0 1px 3px rgba(0,0,0,0.05); } .sbs-field { display: flex; flex-direction: column; gap: 5px; flex: 1; min-width: 180px; } .sbs-field label { font-size: 0.8em; font-weight: bold; color: #54595d; text-transform: uppercase; letter-spacing: 0.5px; } .sbs-field input { padding: 8px 10px; font-family: inherit; font-size: 1em; width: 100%; border: 1px solid #a2a9b1; border-radius: 4px; box-sizing: border-box; transition: border-color 0.25s, box-shadow 0.25s; } .sbs-field input:focus { border-color: #3366cc; outline: none; box-shadow: 0 0 0 2px rgba(51,102,204,0.2); } .sbs-field input:read-only { background: #f8f9fa; color: #72777d; cursor: default; } .sbs-btn-group { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; } .sbs-btn { padding: 8px 18px; border: 1px solid transparent; border-radius: 4px; font-size: 0.95em; font-weight: bold; cursor: pointer; transition: all 0.15s; white-space: nowrap; line-height: 1.4; } .sbs-btn:disabled { opacity: 0.45; cursor: not-allowed; } .sbs-btn.primary { background: #3366cc; color: #fff; } .sbs-btn.primary:hover:not(:disabled) { background: #2a4b8d; } .sbs-btn.success { background: #14866d; color: #fff; } .sbs-btn.success:hover:not(:disabled) { background: #0f6b56; } .sbs-btn.neutral { background: #f8f9fa; color: #202122; border-color: #a2a9b1; } .sbs-btn.neutral:hover:not(:disabled) { background: #fff; border-color: #3366cc; color: #3366cc; } .sbs-btn.danger { background: #fff; color: #d33; border-color: #d33; } .sbs-btn.danger:hover:not(:disabled) { background: #fee7e6; } .sbs-btn.locked { background: #3366cc; color: #fff; border-color: #3366cc; } .sbs-undo-group { display: flex; gap: 6px; align-items: flex-end; } .sbs-icon-btn { width: 38px; height: 38px; border: 1px solid #a2a9b1; border-radius: 4px; background: #f8f9fa; cursor: pointer; font-size: 1.3em; display: flex; align-items: center; justify-content: center; transition: all 0.15s; color: #202122; flex-shrink: 0; font-weight: bold; line-height: 1; } .sbs-icon-btn:hover:not(:disabled) { background: #fff; border-color: #3366cc; color: #3366cc; } .sbs-icon-btn:disabled { opacity: 0.4; cursor: not-allowed; } .sbs-status { font-size: 0.9em; color: #54595d; margin-bottom: 10px; min-height: 1.4em; font-weight: 500; } .sbs-count-bar { display: none; font-size: 0.88em; color: #3366cc; font-weight: 600; margin-bottom: 10px; padding: 7px 14px; background: #eaf3fb; border-radius: 4px; border: 1px solid #c8d8f0; } .sbs-grid-wrap { display: none; border: 1px solid #a2a9b1; border-radius: 4px; background: #fff; box-shadow: 0 2px 6px rgba(0,0,0,0.05); overflow: hidden; } .sbs-col-headers { display: grid; grid-template-columns: 1fr 1fr; background: #eaecf0; border-bottom: 2px solid #c8ccd1; position: relative; z-index: 5; } .sbs-col-header { padding: 10px 16px; font-size: 0.82em; font-weight: bold; color: #202122; text-transform: uppercase; letter-spacing: 0.4px; } .sbs-col-header:first-child { border-right: 1px solid #c8ccd1; } .sbs-panels { display: grid; grid-template-columns: 1fr 1fr; max-height: 76vh; overflow: hidden; } .sbs-panel-en, .sbs-panel-bn { position: relative; overflow-y: scroll; overflow-x: hidden; max-height: 76vh; box-sizing: border-box; } .sbs-panel-en { border-right: 1px solid #a2a9b1; background: #f8f9fa; } .sbs-panel-bn { background: #fff; } .sbs-sec-hdr-en, .sbs-sec-hdr-bn { padding: 9px 16px; font-size: 0.92em; font-weight: bold; color: #3366cc; background: #eaf3fb; border-top: 2px solid #a2a9b1; border-bottom: 1px solid #c8d8f0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: flex; align-items: center; } .sbs-sec-num { display: inline-block; background: #3366cc; color: #fff; border-radius: 10px; padding: 0 6px; font-size: 0.75em; margin-right: 4px; vertical-align: middle; font-weight: bold; line-height: 1.7; } .sbs-cell-en { padding: 20px 18px; font-size: 1em; line-height: 1.75; color: #202122; white-space: pre-wrap; word-break: break-word; box-sizing: border-box; border-bottom: 1px solid #eaecf0; min-height: 100px; } .sbs-cell-bn { box-sizing: border-box; border-bottom: 1px solid #eaecf0; min-height: 100px; } .sbs-cell-bn textarea { width: 100%; border: none; font-family: inherit; font-size: 1em; line-height: 1.75; resize: none; background: transparent; padding: 20px 18px; color: #202122; outline: none; box-sizing: border-box; overflow: hidden; min-height: 100px; display: block; } @media (max-width: 768px) { .sbs-col-headers, .sbs-panels { grid-template-columns: 1fr; } .sbs-panel-en { border-right: none; border-bottom: 1px solid #a2a9b1; max-height: 40vh; } .sbs-panel-bn { max-height: 50vh; } } `).appendTo('head'); } /*--- Wikitext helpers ---*/ function parseByHeadings(wikitext) { const lines = wikitext.split('\n'); const sections = []; let current = { heading: null, level: 0, content: [] }; for (const line of lines) { const m = line.match(/^(={1,6})\s*(.+?)\s*\1\s*$/); if (m) { sections.push(current); current = { heading: m[2].trim(), level: m[1].length, content: [] }; } else { current.content.push(line); } } sections.push(current); return sections.filter(s => s.heading != null || s.content.join('\n').trim().length > 0); } function sectionToText(sec) { return sec.content.join('\n').trim(); } function sectionsToWikitext(sections) { return sections.filter(sec => { const body = sec.content.join('\n').trim(); return body.length > 0; }).map(sec => { const h = '='.repeat(sec.level); if (sec.heading === null) return sec.content.join('\n').trimEnd(); return h + ' ' + sec.heading + ' ' + h + '\n' + sec.content.join('\n').trimEnd(); }).join('\n\n'); } function deepClone(sections) { return sections.map(s => ({ heading: s.heading, level: s.level, content: [...s.content], isPlaceholder: s.isPlaceholder })); } /* Count bar */ function updateCountBar(bnSections, $bar) { const total = bnSections.length; const withText = bnSections.filter(s => sectionToText(s).length > 0).length; const empty = total - withText; $bar.html( '<strong>' + toBengaliNum(total) + '</strong> টি বিভাগ' + '&nbsp;&nbsp;|&nbsp;&nbsp;' + '<strong style="color: #14866d">' + toBengaliNum(withText) + '</strong> টি পাঠ্য সহ' + '&nbsp;&nbsp;|&nbsp;&nbsp;' + '<strong style="color: #d33">' + toBengaliNum(empty) + '</strong> টি খালি' ).show(); } /*--- API helpers ---*/ async function getEnTitle(bnTitle, api) { try { const r = await api.get({ action: 'query', titles: bnTitle, prop: 'pageprops', ppprop: 'wikibase_item', formatversion: 2 }); const page = r.query.pages[0]; if (!page || page.missing) return null; const qid = page.pageprops && page.pageprops.wikibase_item; if (!qid) return null; const wdApi = new mw.ForeignApi('https://www.wikidata.org/w/api.php'); const wd = await wdApi.get({ action: 'wbgetentities', ids: qid, props: 'sitelinks', sitefilter: 'enwikibooks', formatversion: 2 }); const sl = wd.entities[qid] && wd.entities[qid].sitelinks && wd.entities[qid].sitelinks.enwikibooks; return sl ? sl.title : null; } catch (e) { return null; } } async function fetchWikitext(title, isEn) { const apiobj = isEn ? new mw.ForeignApi('https://en.wikibooks.org/w/api.php') : new mw.Api(); const data = await apiobj.get({ action: 'query', titles: title, prop: 'revisions', rvprop: 'content', rvslots: 'main', formatversion: 2 }); const page = data.query.pages[0]; if (page.missing) throw new Error('পাতা পাওয়া যায়নি: ' + title); return page.revisions[0].slots.main.content; } /* Main tool */ function loadTool() { document.title = 'পাশাপাশি তুলনা - বাংলা উইকিবই'; $('#firstHeading').text('পাশাপাশি তুলনা সরঞ্জাম'); $('#mw-content-text').empty(); injectCSS(); const api = new mw.Api(); const urlParams = new URLSearchParams(window.location.search); const originPage = urlParams.get('origin') || ''; const wrap = $('<div>').addClass('sbs-wrap'); $('#mw-content-text').append(wrap); /* Top bar */ const topbar = $('<div>').addClass('sbs-topbar'); const bnField = $('<div>').addClass('sbs-field'); const bnInput = $('<input type="text">').val(originPage).attr('placeholder', 'বাংলা শিরোনাম'); bnField.append($('<label>').text('বাংলা নিবন্ধ'), bnInput); const enField = $('<div>').addClass('sbs-field'); const enInput = $('<input type="text">').attr('placeholder', 'English title'); enField.append($('<label>').text('ইংরেজি নিবন্ধ'), enInput); const btnGroup = $('<div>').addClass('sbs-btn-group'); const mainBtn = $('<button>').addClass('sbs-btn primary').text('লোড করুন'); const discardBtn = $('<button>').addClass('sbs-btn danger').text('বাতিল').hide(); const undoGroup = $('<div>').addClass('sbs-undo-group').hide(); const undoBtn = $('<button>').addClass('sbs-icon-btn').attr('title', 'পূর্বাবস্থায় ফেরান').html('&#8592;'); const redoBtn = $('<button>').addClass('sbs-icon-btn').attr('title', 'পুনরায় করুন').html('&#8594;'); undoGroup.append(undoBtn, redoBtn); const scrollLockBtn = $('<button>').addClass('sbs-btn neutral').attr('title', 'স্ক্রল লক').text('স্ক্রল মুক্ত').hide(); btnGroup.append(mainBtn, discardBtn, scrollLockBtn, undoGroup); topbar.append(bnField, enField, btnGroup); wrap.append(topbar); const status = $('<div>').addClass('sbs-status'); wrap.append(status); let statusTimeout; function setStatus(msg, autoClear = false) { status.text(msg); clearTimeout(statusTimeout); if (autoClear) { statusTimeout = setTimeout(() => status.text(''), 4000); } } const countBar = $('<div>').addClass('sbs-count-bar'); wrap.append(countBar); /* Grid: col-headers + two scroll panels */ const gridWrap = $('<div>').addClass('sbs-grid-wrap'); const colHeaders = $('<div>').addClass('sbs-col-headers').append( $('<div>').addClass('sbs-col-header').text('ইংরেজি (শুধু পড়ুন)'), $('<div>').addClass('sbs-col-header').text('বাংলা (সম্পাদনা যোগ্য)') ); const panels = $('<div>').addClass('sbs-panels'); const panelEn = $('<div>').addClass('sbs-panel-en'); const panelBn = $('<div>').addClass('sbs-panel-bn'); panels.append(panelEn, panelBn); gridWrap.append(colHeaders, panels); wrap.append(gridWrap); /* Scroll lock */ let scrollLocked = false; let isSyncing = false; function syncScroll(source, target) { if (!scrollLocked || isSyncing) return; isSyncing = true; const sourceNodes = source.children('.sbs-sec-hdr-en, .sbs-sec-hdr-bn'); const targetNodes = target.children('.sbs-sec-hdr-en, .sbs-sec-hdr-bn'); const sourceScrollTop = source[0].scrollTop; let topIdx = 0; sourceNodes.each(function (i) { if (this.offsetTop < sourceScrollTop + 5) { topIdx = i; } else { return false; } }); const srcElem = sourceNodes[topIdx]; const tgtElem = targetNodes[topIdx]; if (srcElem && tgtElem) { const srcCell = $(srcElem).next()[0]; const tgtCell = $(tgtElem).next()[0]; const scrolledPastElem = sourceScrollTop - srcElem.offsetTop; const srcHeight = (srcElem.offsetHeight + (srcCell ? srcCell.offsetHeight : 0)) || 1; const tgtHeight = tgtElem.offsetHeight + (tgtCell ? tgtCell.offsetHeight : 0); const ratio = Math.max(0, scrolledPastElem / srcHeight); target[0].scrollTop = tgtElem.offsetTop + (tgtHeight * ratio); } else { const ratio = source[0].scrollTop / Math.max(1, source[0].scrollHeight - source[0].clientHeight); target[0].scrollTop = ratio * (target[0].scrollHeight - target[0].clientHeight); } isSyncing = false; } panelEn.on('scroll', () => syncScroll(panelEn, panelBn)); panelBn.on('scroll', () => syncScroll(panelBn, panelEn)); scrollLockBtn.on('click', () => { scrollLocked = !scrollLocked; if (scrollLocked) { scrollLockBtn.text('স্ক্রল লক').addClass('locked'); syncScroll(panelBn, panelEn); } else { scrollLockBtn.text('স্ক্রল মুক্ত').removeClass('locked'); } }); /* State */ let enSections = [], bnSections = [], baselineSections = []; let currentBnTitle = ''; let activeTA = null, undoStack = [], redoStack = []; let phase = 'load'; function resizeTA(ta) { ta.style.height = 'auto'; ta.style.height = ta.scrollHeight + 'px'; } /* Undo / Redo */ function applyUndoRedo(val) { if (!activeTA) return; activeTA.val(val); const idx = activeTA.data('idx'); bnSections[idx].content = val.split('\n'); const panel = panelBn[0]; const savedScrollTop = panel.scrollTop; resizeTA(activeTA[0]); panel.scrollTop = savedScrollTop; updateCountBar(bnSections, countBar); } function holdToRepeat(btn, action) { let holdTimer = null; let repeatTimer = null; function stop() { clearTimeout(holdTimer); clearInterval(repeatTimer); holdTimer = null; repeatTimer = null; } btn[0].addEventListener('pointerdown', function (e) { if (e.button !== undefined && e.button !== 0) return; e.preventDefault(); this.setPointerCapture(e.pointerId); action(); holdTimer = setTimeout(function () { repeatTimer = setInterval(action, 80); }, 400); }); btn[0].addEventListener('pointerup', stop); btn[0].addEventListener('pointercancel', stop); } holdToRepeat(undoBtn, () => { if (!activeTA || !undoStack.length) return; redoStack.push(activeTA.val()); applyUndoRedo(undoStack.pop()); }); holdToRepeat(redoBtn, () => { if (!activeTA || !redoStack.length) return; undoStack.push(activeTA.val()); applyUndoRedo(redoStack.pop()); }); function lockInputs() { bnInput.prop('readonly', true); enInput.prop('readonly', true); } function unlockInputs() { bnInput.prop('readonly', false); enInput.prop('readonly', false); } function setPhase(p) { phase = p; if (p === 'load') { mainBtn.text('লোড করুন').removeClass('success neutral').addClass('primary'); discardBtn.hide(); undoGroup.hide(); gridWrap.hide(); countBar.hide(); scrollLockBtn.hide(); unlockInputs(); } else if (p === 'save') { mainBtn.text('সংরক্ষণ করুন').removeClass('primary neutral').addClass('success'); discardBtn.show(); undoGroup.show(); gridWrap.show(); scrollLockBtn.show(); lockInputs(); } else if (p === 'back') { mainBtn.text('মূল পাতায় ফিরুন').removeClass('primary success').addClass('neutral'); discardBtn.show(); undoGroup.show(); scrollLockBtn.show(); lockInputs(); } } /* Build grid */ function buildGrid() { panelEn.empty(); panelBn.empty(); activeTA = null; undoStack = []; redoStack = []; const isLead = s => s.heading == null; const isHeading = s => s.heading != null; const enLeads = enSections.filter(isLead); const bnLeads = bnSections.filter(isLead); const enHeads = enSections.filter(isHeading); const bnHeads = bnSections.filter(isHeading); const displayPairs = []; const maxLeads = Math.max(enLeads.length, bnLeads.length); for (let i = 0; i < maxLeads; i++) displayPairs.push({ en: enLeads[i] || null, bn: bnLeads[i] || null }); const maxHeads = Math.max(enHeads.length, bnHeads.length); for (let i = 0; i < maxHeads; i++) displayPairs.push({ en: enHeads[i] || null, bn: bnHeads[i] || null }); bnSections = displayPairs.map(pair => { if (pair.bn) return pair.bn; return { heading: pair.en ? pair.en.heading : null, level: pair.en ? pair.en.level : 2, content: [], isPlaceholder: true }; }); updateCountBar(bnSections, countBar); displayPairs.forEach((pair, i) => { const enSec = pair.en; const bnSec = bnSections[i]; const enText = enSec ? sectionToText(enSec) : ''; const bnText = sectionToText(bnSec); const num = toBengaliNum(i + 1); const enTitle = enSec ? (enSec.heading !== null ? enSec.heading : '(ভূমিকা)') : '(অনুপস্থিত)'; const bnTitleFallback = enSec && enSec.heading !== null ? enSec.heading : '(ভূমিকা)'; const bnTitleVal = bnSec.heading !== null ? bnSec.heading : ''; const numBadge = () => $('<span>').addClass('sbs-sec-num').text(num); const enHdr = $('<div>').addClass('sbs-sec-hdr-en').append(numBadge(), document.createTextNode(' ' + enTitle)); const enCell = $('<div>').addClass('sbs-cell-en').text(enText); panelEn.append(enHdr, enCell); const isIntroSection = bnTitleFallback === '(ভূমিকা)'; const bnHdr = $('<div>').addClass('sbs-sec-hdr-bn'); const bnHdrInput = $('<input type="text">') .val(bnTitleVal) .attr('placeholder', bnTitleFallback) .css({ 'background': 'transparent', 'border': 'none', 'border-bottom': '1px solid transparent', 'color': 'inherit', 'font-family': 'inherit', 'font-size': 'inherit', 'font-weight': 'inherit', 'width': 'calc(100% - 35px)', 'outline': 'none', 'padding': '0 4px', 'margin-left': '4px', 'cursor': isIntroSection ? 'default' : 'text' }); if (isIntroSection) { bnHdrInput.attr('readonly', true); } else { bnHdrInput .on('focus', function () { $(this).css({ 'background': '#fff', 'border-bottom': '1px solid #3366cc' }); }) .on('blur', function () { $(this).css({ 'background': 'transparent', 'border-bottom': '1px solid transparent' }); }) .on('input', function () { bnSec.heading = $(this).val().trim() || null; if (phase === 'back') setPhase('save'); }); } bnHdr.append(numBadge(), bnHdrInput); const bnCell = $('<div>').addClass('sbs-cell-bn'); const ta = $('<textarea>').val(bnText).attr('placeholder', 'অনুবাদ লিখুন...').data('idx', i); ta.on('focus', () => { if (activeTA && activeTA[0] !== ta[0]) { undoStack = []; redoStack = []; } activeTA = ta; }); ta.on('input', (function (idx) { return function () { resizeTA(ta[0]); undoStack.push(sectionToText(bnSections[idx])); if (undoStack.length > 50) undoStack.shift(); redoStack = []; bnSections[idx].content = ta.val().split('\n'); updateCountBar(bnSections, countBar); if (phase === 'back') setPhase('save'); }; })(i)); /* Paste fix: preserve panel scroll position so the cursor does not disappear behind the sticky header div on paste. The scroll event listeners and syncScroll logic are completely untouched. */ ta.on('paste', function () { const panel = panelBn[0]; const savedScrollTop = panel.scrollTop; requestAnimationFrame(function () { resizeTA(ta[0]); panel.scrollTop = savedScrollTop; }); }); bnCell.append(ta); panelBn.append(bnHdr, bnCell); setTimeout(() => resizeTA(ta[0]), 0); }); } /* Wikidata auto-fetch */ if (originPage) { setStatus('উইকিডেটা থেকে ইংরেজি শিরোনাম খোঁজা হচ্ছে...'); getEnTitle(originPage, api).then(t => { if (t) { enInput.val(t); setStatus('ইংরেজি শিরোনাম পাওয়া গেছে।', true); } else { setStatus('উইকিডেটায় সংযোগ পাওয়া যায়নি। নিজে লিখুন।', true); } }); } /* Discard */ discardBtn.on('click', () => { if (!confirm('পরিবর্তনগুলো বাতিল করবেন?')) return; bnSections = deepClone(baselineSections); buildGrid(); setPhase('back'); mw.notify('পরিবর্তন বাতিল করা হয়েছে।', { type: 'info' }); setStatus('', true); }); /* Main button */ mainBtn.on('click', async () => { const bnTitle = bnInput.val().trim(); const enTitle = enInput.val().trim(); if (phase === 'load') { if (!bnTitle || !enTitle) { setStatus('দুটি শিরোনামই লিখুন।', true); return; } try { mainBtn.prop('disabled', true).text('লোড হচ্ছে...'); setStatus('নিবন্ধ লোড হচ্ছে...'); const [enWT, bnWT] = await Promise.all([ fetchWikitext(enTitle, true), fetchWikitext(bnTitle, false) ]); currentBnTitle = bnTitle; enSections = parseByHeadings(enWT); bnSections = parseByHeadings(bnWT); baselineSections = deepClone(bnSections); buildGrid(); setPhase('save'); setStatus('লোড সম্পন্ন।', true); } catch (e) { setStatus('ত্রুটি: ' + e.message); mainBtn.prop('disabled', false).text('লোড করুন'); } mainBtn.prop('disabled', false); } else if (phase === 'save') { mainBtn.prop('disabled', true).text('সংরক্ষণ করা হচ্ছে...'); try { await api.postWithToken('csrf', { action: 'edit', title: currentBnTitle, text: sectionsToWikitext(bnSections), summary: 'পাশাপাশি সরঞ্জাম (স্ক্রিপ্ট)' }); baselineSections = deepClone(bnSections); setPhase('back'); setStatus('সংরক্ষণ সম্পন্ন হয়েছে।', true); mw.notify('সংরক্ষণ সম্পন্ন হয়েছে।', { type: 'success' }); } catch (e) { setStatus('সংরক্ষণ ব্যর্থ: ' + e); mw.notify('সংরক্ষণ ব্যর্থ: ' + e, { type: 'error' }); } mainBtn.prop('disabled', false); } else if (phase === 'back') { const ret = originPage || currentBnTitle; if (ret) window.location.href = mw.util.getUrl(ret); } }); setPhase('load'); } $(document).ready(init); })(jQuery, mediaWiki); // </nowiki> d3a5ho4f2iz45pesnii8pmjkzwx2j2n 740993 740991 2026-05-08T13:15:19Z কমলেশ মন্ডল 72403 740993 javascript text/javascript // <nowiki> (function ($, mw) { 'use strict'; const SPECIAL_PAGE_NAME = 'বিশেষ:খালি_পাতা/SideBySide'; const toBengaliNum = n => String(n).replace(/\d/g, d => '০১২৩৪৫৬৭৮৯'[d]); function init() { mw.loader.using(['mediawiki.util'], function () { mw.util.addPortletLink( 'p-tb', mw.util.getUrl(SPECIAL_PAGE_NAME) + '?origin=' + encodeURIComponent(mw.config.get('wgPageName')), 'পাশাপাশি তুলনা', 't-sidebyside', 'বাংলা ও ইংরেজি নিবন্ধ পাশাপাশি তুলনা করুন' ); if (mw.config.get('wgPageName') === SPECIAL_PAGE_NAME) { mw.loader.using(['mediawiki.api', 'mediawiki.util'], loadTool); } }); } /*--- CSS ---*/ function injectCSS() { if ($('#sbs-styles').length) return; $('<style id="sbs-styles">').text(` .sbs-wrap { max-width: 100%; box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; color: #202122; } .sbs-topbar { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; margin-bottom: 12px; padding: 16px; background: #fff; border: 1px solid #a2a9b1; border-radius: 4px; box-shadow: 0 1px 3px rgba(0,0,0,0.05); } .sbs-field { display: flex; flex-direction: column; gap: 5px; flex: 1; min-width: 180px; } .sbs-field label { font-size: 0.8em; font-weight: bold; color: #54595d; text-transform: uppercase; letter-spacing: 0.5px; } .sbs-field input { padding: 8px 10px; font-family: inherit; font-size: 1em; width: 100%; border: 1px solid #a2a9b1; border-radius: 4px; box-sizing: border-box; transition: border-color 0.25s, box-shadow 0.25s; } .sbs-field input:focus { border-color: #3366cc; outline: none; box-shadow: 0 0 0 2px rgba(51,102,204,0.2); } .sbs-field input:read-only { background: #f8f9fa; color: #72777d; cursor: default; } .sbs-btn-group { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; } .sbs-btn { padding: 8px 18px; border: 1px solid transparent; border-radius: 4px; font-size: 0.95em; font-weight: bold; cursor: pointer; transition: all 0.15s; white-space: nowrap; line-height: 1.4; } .sbs-btn:disabled { opacity: 0.45; cursor: not-allowed; } .sbs-btn.primary { background: #3366cc; color: #fff; } .sbs-btn.primary:hover:not(:disabled) { background: #2a4b8d; } .sbs-btn.success { background: #14866d; color: #fff; } .sbs-btn.success:hover:not(:disabled) { background: #0f6b56; } .sbs-btn.neutral { background: #f8f9fa; color: #202122; border-color: #a2a9b1; } .sbs-btn.neutral:hover:not(:disabled) { background: #fff; border-color: #3366cc; color: #3366cc; } .sbs-btn.danger { background: #fff; color: #d33; border-color: #d33; } .sbs-btn.danger:hover:not(:disabled) { background: #fee7e6; } .sbs-btn.locked { background: #3366cc; color: #fff; border-color: #3366cc; } .sbs-undo-group { display: flex; gap: 6px; align-items: flex-end; } .sbs-icon-btn { width: 38px; height: 38px; border: 1px solid #a2a9b1; border-radius: 4px; background: #f8f9fa; cursor: pointer; font-size: 1.3em; display: flex; align-items: center; justify-content: center; transition: all 0.15s; color: #202122; flex-shrink: 0; font-weight: bold; line-height: 1; } .sbs-icon-btn:hover:not(:disabled) { background: #fff; border-color: #3366cc; color: #3366cc; } .sbs-icon-btn:disabled { opacity: 0.4; cursor: not-allowed; } .sbs-status { font-size: 0.9em; color: #54595d; margin-bottom: 10px; min-height: 1.4em; font-weight: 500; } .sbs-count-bar { display: none; font-size: 0.88em; color: #3366cc; font-weight: 600; margin-bottom: 10px; padding: 7px 14px; background: #eaf3fb; border-radius: 4px; border: 1px solid #c8d8f0; } .sbs-grid-wrap { display: none; border: 1px solid #a2a9b1; border-radius: 4px; background: #fff; box-shadow: 0 2px 6px rgba(0,0,0,0.05); overflow: hidden; } .sbs-col-headers { display: grid; grid-template-columns: 1fr 1fr; background: #eaecf0; border-bottom: 2px solid #c8ccd1; position: relative; z-index: 5; } .sbs-col-header { padding: 10px 16px; font-size: 0.82em; font-weight: bold; color: #202122; text-transform: uppercase; letter-spacing: 0.4px; } .sbs-col-header:first-child { border-right: 1px solid #c8ccd1; } .sbs-panels { display: grid; grid-template-columns: 1fr 1fr; max-height: 76vh; overflow: hidden; } .sbs-panel-en, .sbs-panel-bn { position: relative; overflow-y: scroll; overflow-x: hidden; max-height: 76vh; box-sizing: border-box; } .sbs-panel-en { border-right: 1px solid #a2a9b1; background: #f8f9fa; } .sbs-panel-bn { background: #fff; } .sbs-sec-hdr-en, .sbs-sec-hdr-bn { padding: 9px 16px; font-size: 0.92em; font-weight: bold; color: #3366cc; background: #eaf3fb; border-top: 2px solid #a2a9b1; border-bottom: 1px solid #c8d8f0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: flex; align-items: center; } .sbs-sec-num { display: inline-block; background: #3366cc; color: #fff; border-radius: 10px; padding: 0 6px; font-size: 0.75em; margin-right: 4px; vertical-align: middle; font-weight: bold; line-height: 1.7; } .sbs-cell-en { padding: 20px 18px; font-size: 1em; line-height: 1.75; color: #202122; white-space: pre-wrap; word-break: break-word; box-sizing: border-box; border-bottom: 1px solid #eaecf0; min-height: 100px; } .sbs-cell-bn { box-sizing: border-box; border-bottom: 1px solid #eaecf0; min-height: 100px; } .sbs-cell-bn textarea { width: 100%; border: none; font-family: inherit; font-size: 1em; line-height: 1.75; resize: none; background: transparent; padding: 20px 18px; color: #202122; outline: none; box-sizing: border-box; overflow: hidden; min-height: 100px; display: block; } @media (max-width: 768px) { .sbs-col-headers, .sbs-panels { grid-template-columns: 1fr; } .sbs-panel-en { border-right: none; border-bottom: 1px solid #a2a9b1; max-height: 40vh; } .sbs-panel-bn { max-height: 50vh; } } `).appendTo('head'); } /*--- Wikitext helpers ---*/ function parseByHeadings(wikitext) { const lines = wikitext.split('\n'); const sections = []; let current = { heading: null, level: 0, content: [] }; for (const line of lines) { const m = line.match(/^(={1,6})\s*(.+?)\s*\1\s*$/); if (m) { sections.push(current); current = { heading: m[2].trim(), level: m[1].length, content: [] }; } else { current.content.push(line); } } sections.push(current); return sections.filter(s => s.heading != null || s.content.join('\n').trim().length > 0); } function sectionToText(sec) { return sec.content.join('\n').trim(); } function sectionsToWikitext(sections) { return sections.filter(sec => { const body = sec.content.join('\n').trim(); return body.length > 0; }).map(sec => { const h = '='.repeat(sec.level); if (sec.heading === null) return sec.content.join('\n').trimEnd(); return h + ' ' + sec.heading + ' ' + h + '\n' + sec.content.join('\n').trimEnd(); }).join('\n\n'); } function deepClone(sections) { return sections.map(s => ({ heading: s.heading, level: s.level, content: [...s.content], isPlaceholder: s.isPlaceholder })); } /* Count bar */ function updateCountBar(bnSections, $bar) { const total = bnSections.length; const withText = bnSections.filter(s => sectionToText(s).length > 0).length; const empty = total - withText; $bar.html( '<strong>' + toBengaliNum(total) + '</strong> টি বিভাগ' + '&nbsp;&nbsp;|&nbsp;&nbsp;' + '<strong style="color: #14866d">' + toBengaliNum(withText) + '</strong> টি পাঠ্য সহ' + '&nbsp;&nbsp;|&nbsp;&nbsp;' + '<strong style="color: #d33">' + toBengaliNum(empty) + '</strong> টি খালি' ).show(); } /*--- API helpers ---*/ async function getEnTitle(bnTitle, api) { try { const r = await api.get({ action: 'query', titles: bnTitle, prop: 'pageprops', ppprop: 'wikibase_item', formatversion: 2 }); const page = r.query.pages[0]; if (!page || page.missing) return null; const qid = page.pageprops && page.pageprops.wikibase_item; if (!qid) return null; const wdApi = new mw.ForeignApi('https://www.wikidata.org/w/api.php'); const wd = await wdApi.get({ action: 'wbgetentities', ids: qid, props: 'sitelinks', sitefilter: 'enwikibooks', formatversion: 2 }); const sl = wd.entities[qid] && wd.entities[qid].sitelinks && wd.entities[qid].sitelinks.enwikibooks; return sl ? sl.title : null; } catch (e) { return null; } } async function fetchWikitext(title, isEn) { const apiobj = isEn ? new mw.ForeignApi('https://en.wikibooks.org/w/api.php') : new mw.Api(); const data = await apiobj.get({ action: 'query', titles: title, prop: 'revisions', rvprop: 'content', rvslots: 'main', formatversion: 2 }); const page = data.query.pages[0]; if (page.missing) throw new Error('পাতা পাওয়া যায়নি: ' + title); return page.revisions[0].slots.main.content; } /* Main tool */ function loadTool() { document.title = 'পাশাপাশি তুলনা - বাংলা উইকিবই'; $('#firstHeading').text('পাশাপাশি তুলনা সরঞ্জাম'); $('#mw-content-text').empty(); injectCSS(); const api = new mw.Api(); const urlParams = new URLSearchParams(window.location.search); const originPage = urlParams.get('origin') || ''; const wrap = $('<div>').addClass('sbs-wrap'); $('#mw-content-text').append(wrap); /* Top bar */ const topbar = $('<div>').addClass('sbs-topbar'); const bnField = $('<div>').addClass('sbs-field'); const bnInput = $('<input type="text">').val(originPage).attr('placeholder', 'বাংলা শিরোনাম'); bnField.append($('<label>').text('বাংলা নিবন্ধ'), bnInput); const enField = $('<div>').addClass('sbs-field'); const enInput = $('<input type="text">').attr('placeholder', 'English title'); enField.append($('<label>').text('ইংরেজি নিবন্ধ'), enInput); const btnGroup = $('<div>').addClass('sbs-btn-group'); const mainBtn = $('<button>').addClass('sbs-btn primary').text('লোড করুন'); const discardBtn = $('<button>').addClass('sbs-btn danger').text('বাতিল').hide(); const undoGroup = $('<div>').addClass('sbs-undo-group').hide(); const undoBtn = $('<button>').addClass('sbs-icon-btn').attr('title', 'পূর্বাবস্থায় ফেরান').html('&#8592;'); const redoBtn = $('<button>').addClass('sbs-icon-btn').attr('title', 'পুনরায় করুন').html('&#8594;'); undoGroup.append(undoBtn, redoBtn); const scrollLockBtn = $('<button>').addClass('sbs-btn neutral').attr('title', 'স্ক্রল লক').text('স্ক্রল মুক্ত').hide(); btnGroup.append(mainBtn, discardBtn, scrollLockBtn, undoGroup); topbar.append(bnField, enField, btnGroup); wrap.append(topbar); const status = $('<div>').addClass('sbs-status'); wrap.append(status); let statusTimeout; function setStatus(msg, autoClear = false) { status.text(msg); clearTimeout(statusTimeout); if (autoClear) { statusTimeout = setTimeout(() => status.text(''), 4000); } } const countBar = $('<div>').addClass('sbs-count-bar'); wrap.append(countBar); /* Grid: col-headers + two scroll panels */ const gridWrap = $('<div>').addClass('sbs-grid-wrap'); const colHeaders = $('<div>').addClass('sbs-col-headers').append( $('<div>').addClass('sbs-col-header').text('ইংরেজি (শুধু পড়ুন)'), $('<div>').addClass('sbs-col-header').text('বাংলা (সম্পাদনা যোগ্য)') ); const panels = $('<div>').addClass('sbs-panels'); const panelEn = $('<div>').addClass('sbs-panel-en'); const panelBn = $('<div>').addClass('sbs-panel-bn'); panels.append(panelEn, panelBn); gridWrap.append(colHeaders, panels); wrap.append(gridWrap); /* Scroll lock */ let scrollLocked = false; let isSyncing = false; function syncScroll(source, target) { if (!scrollLocked || isSyncing) return; isSyncing = true; const sourceNodes = source.children('.sbs-sec-hdr-en, .sbs-sec-hdr-bn'); const targetNodes = target.children('.sbs-sec-hdr-en, .sbs-sec-hdr-bn'); const sourceScrollTop = source[0].scrollTop; let topIdx = 0; sourceNodes.each(function (i) { if (this.offsetTop < sourceScrollTop + 5) { topIdx = i; } else { return false; } }); const srcElem = sourceNodes[topIdx]; const tgtElem = targetNodes[topIdx]; if (srcElem && tgtElem) { const srcCell = $(srcElem).next()[0]; const tgtCell = $(tgtElem).next()[0]; const scrolledPastElem = sourceScrollTop - srcElem.offsetTop; const srcHeight = (srcElem.offsetHeight + (srcCell ? srcCell.offsetHeight : 0)) || 1; const tgtHeight = tgtElem.offsetHeight + (tgtCell ? tgtCell.offsetHeight : 0); const ratio = Math.max(0, scrolledPastElem / srcHeight); target[0].scrollTop = tgtElem.offsetTop + (tgtHeight * ratio); } else { const ratio = source[0].scrollTop / Math.max(1, source[0].scrollHeight - source[0].clientHeight); target[0].scrollTop = ratio * (target[0].scrollHeight - target[0].clientHeight); } isSyncing = false; } panelEn.on('scroll', () => syncScroll(panelEn, panelBn)); panelBn.on('scroll', () => syncScroll(panelBn, panelEn)); scrollLockBtn.on('click', () => { scrollLocked = !scrollLocked; if (scrollLocked) { scrollLockBtn.text('স্ক্রল লক').addClass('locked'); syncScroll(panelBn, panelEn); } else { scrollLockBtn.text('স্ক্রল মুক্ত').removeClass('locked'); } }); /* State */ let enSections = [], bnSections = [], baselineSections = []; let currentBnTitle = ''; let activeTA = null, undoStack = [], redoStack = []; let phase = 'load'; function resizeTA(ta) { ta.style.height = 'auto'; ta.style.height = ta.scrollHeight + 'px'; } /* Undo / Redo */ function applyUndoRedo(val) { if (!activeTA) return; activeTA.val(val); const idx = activeTA.data('idx'); bnSections[idx].content = val.split('\n'); /* Lock the page scroll so resizeTA's height='auto' step cannot trigger a browser scrollIntoView that zooms the page and hides the topbar buttons. */ const savedPageY = window.scrollY; resizeTA(activeTA[0]); if (window.scrollY !== savedPageY) { window.scrollTo({ top: savedPageY, behavior: 'instant' }); } /* Scroll the panel (not the page) to keep the active textarea visible, with a small offset so it isn't flush against the edge. */ const panel = panelBn[0]; const ta = activeTA[0]; const taTop = ta.offsetTop; const taBottom = taTop + ta.offsetHeight; const panelTop = panel.scrollTop; const panelBottom = panelTop + panel.clientHeight; if (taTop < panelTop) { panel.scrollTop = taTop - 20; } else if (taBottom > panelBottom) { panel.scrollTop = taBottom - panel.clientHeight + 20; } updateCountBar(bnSections, countBar); } function holdToRepeat(btn, action) { let holdTimer = null; let repeatTimer = null; function stop() { clearTimeout(holdTimer); clearInterval(repeatTimer); holdTimer = null; repeatTimer = null; } btn[0].addEventListener('pointerdown', function (e) { if (e.button !== undefined && e.button !== 0) return; e.preventDefault(); this.setPointerCapture(e.pointerId); action(); holdTimer = setTimeout(function () { repeatTimer = setInterval(action, 80); }, 400); }); btn[0].addEventListener('pointerup', stop); btn[0].addEventListener('pointercancel', stop); } holdToRepeat(undoBtn, () => { if (!activeTA || !undoStack.length) return; redoStack.push(activeTA.val()); applyUndoRedo(undoStack.pop()); }); holdToRepeat(redoBtn, () => { if (!activeTA || !redoStack.length) return; undoStack.push(activeTA.val()); applyUndoRedo(redoStack.pop()); }); function lockInputs() { bnInput.prop('readonly', true); enInput.prop('readonly', true); } function unlockInputs() { bnInput.prop('readonly', false); enInput.prop('readonly', false); } function setPhase(p) { phase = p; if (p === 'load') { mainBtn.text('লোড করুন').removeClass('success neutral').addClass('primary'); discardBtn.hide(); undoGroup.hide(); gridWrap.hide(); countBar.hide(); scrollLockBtn.hide(); unlockInputs(); } else if (p === 'save') { mainBtn.text('সংরক্ষণ করুন').removeClass('primary neutral').addClass('success'); discardBtn.show(); undoGroup.show(); gridWrap.show(); scrollLockBtn.show(); lockInputs(); } else if (p === 'back') { mainBtn.text('মূল পাতায় ফিরুন').removeClass('primary success').addClass('neutral'); discardBtn.show(); undoGroup.show(); scrollLockBtn.show(); lockInputs(); } } /* Build grid */ function buildGrid() { panelEn.empty(); panelBn.empty(); activeTA = null; undoStack = []; redoStack = []; const isLead = s => s.heading == null; const isHeading = s => s.heading != null; const enLeads = enSections.filter(isLead); const bnLeads = bnSections.filter(isLead); const enHeads = enSections.filter(isHeading); const bnHeads = bnSections.filter(isHeading); const displayPairs = []; const maxLeads = Math.max(enLeads.length, bnLeads.length); for (let i = 0; i < maxLeads; i++) displayPairs.push({ en: enLeads[i] || null, bn: bnLeads[i] || null }); const maxHeads = Math.max(enHeads.length, bnHeads.length); for (let i = 0; i < maxHeads; i++) displayPairs.push({ en: enHeads[i] || null, bn: bnHeads[i] || null }); bnSections = displayPairs.map(pair => { if (pair.bn) return pair.bn; return { heading: pair.en ? pair.en.heading : null, level: pair.en ? pair.en.level : 2, content: [], isPlaceholder: true }; }); updateCountBar(bnSections, countBar); displayPairs.forEach((pair, i) => { const enSec = pair.en; const bnSec = bnSections[i]; const enText = enSec ? sectionToText(enSec) : ''; const bnText = sectionToText(bnSec); const num = toBengaliNum(i + 1); const enTitle = enSec ? (enSec.heading !== null ? enSec.heading : '(ভূমিকা)') : '(অনুপস্থিত)'; const bnTitleFallback = enSec && enSec.heading !== null ? enSec.heading : '(ভূমিকা)'; const bnTitleVal = bnSec.heading !== null ? bnSec.heading : ''; const numBadge = () => $('<span>').addClass('sbs-sec-num').text(num); const enHdr = $('<div>').addClass('sbs-sec-hdr-en').append(numBadge(), document.createTextNode(' ' + enTitle)); const enCell = $('<div>').addClass('sbs-cell-en').text(enText); panelEn.append(enHdr, enCell); const isIntroSection = bnTitleFallback === '(ভূমিকা)'; const bnHdr = $('<div>').addClass('sbs-sec-hdr-bn'); const bnHdrInput = $('<input type="text">') .val(bnTitleVal) .attr('placeholder', bnTitleFallback) .css({ 'background': 'transparent', 'border': 'none', 'border-bottom': '1px solid transparent', 'color': 'inherit', 'font-family': 'inherit', 'font-size': 'inherit', 'font-weight': 'inherit', 'width': 'calc(100% - 35px)', 'outline': 'none', 'padding': '0 4px', 'margin-left': '4px', 'cursor': isIntroSection ? 'default' : 'text' }); if (isIntroSection) { bnHdrInput.attr('readonly', true); } else { bnHdrInput .on('focus', function () { $(this).css({ 'background': '#fff', 'border-bottom': '1px solid #3366cc' }); }) .on('blur', function () { $(this).css({ 'background': 'transparent', 'border-bottom': '1px solid transparent' }); }) .on('input', function () { bnSec.heading = $(this).val().trim() || null; if (phase === 'back') setPhase('save'); }); } bnHdr.append(numBadge(), bnHdrInput); const bnCell = $('<div>').addClass('sbs-cell-bn'); const ta = $('<textarea>').val(bnText).attr('placeholder', 'অনুবাদ লিখুন...').data('idx', i); ta.on('focus', () => { if (activeTA && activeTA[0] !== ta[0]) { undoStack = []; redoStack = []; } activeTA = ta; }); ta.on('input', (function (idx) { return function () { resizeTA(ta[0]); undoStack.push(sectionToText(bnSections[idx])); if (undoStack.length > 50) undoStack.shift(); redoStack = []; bnSections[idx].content = ta.val().split('\n'); updateCountBar(bnSections, countBar); if (phase === 'back') setPhase('save'); }; })(i)); /* Paste fix: preserve panel scroll position so the cursor does not disappear behind the sticky header div on paste. The scroll event listeners and syncScroll logic are completely untouched. */ ta.on('paste', function () { const panel = panelBn[0]; const savedScrollTop = panel.scrollTop; requestAnimationFrame(function () { resizeTA(ta[0]); panel.scrollTop = savedScrollTop; }); }); bnCell.append(ta); panelBn.append(bnHdr, bnCell); setTimeout(() => resizeTA(ta[0]), 0); }); } /* Wikidata auto-fetch */ if (originPage) { setStatus('উইকিডেটা থেকে ইংরেজি শিরোনাম খোঁজা হচ্ছে...'); getEnTitle(originPage, api).then(t => { if (t) { enInput.val(t); setStatus('ইংরেজি শিরোনাম পাওয়া গেছে।', true); } else { setStatus('উইকিডেটায় সংযোগ পাওয়া যায়নি। নিজে লিখুন।', true); } }); } /* Discard */ discardBtn.on('click', () => { if (!confirm('পরিবর্তনগুলো বাতিল করবেন?')) return; bnSections = deepClone(baselineSections); buildGrid(); setPhase('back'); mw.notify('পরিবর্তন বাতিল করা হয়েছে।', { type: 'info' }); setStatus('', true); }); /* Main button */ mainBtn.on('click', async () => { const bnTitle = bnInput.val().trim(); const enTitle = enInput.val().trim(); if (phase === 'load') { if (!bnTitle || !enTitle) { setStatus('দুটি শিরোনামই লিখুন।', true); return; } try { mainBtn.prop('disabled', true).text('লোড হচ্ছে...'); setStatus('নিবন্ধ লোড হচ্ছে...'); const [enWT, bnWT] = await Promise.all([ fetchWikitext(enTitle, true), fetchWikitext(bnTitle, false) ]); currentBnTitle = bnTitle; enSections = parseByHeadings(enWT); bnSections = parseByHeadings(bnWT); baselineSections = deepClone(bnSections); buildGrid(); setPhase('save'); setStatus('লোড সম্পন্ন।', true); } catch (e) { setStatus('ত্রুটি: ' + e.message); mainBtn.prop('disabled', false).text('লোড করুন'); } mainBtn.prop('disabled', false); } else if (phase === 'save') { mainBtn.prop('disabled', true).text('সংরক্ষণ করা হচ্ছে...'); try { await api.postWithToken('csrf', { action: 'edit', title: currentBnTitle, text: sectionsToWikitext(bnSections), summary: 'পাশাপাশি সরঞ্জাম (স্ক্রিপ্ট)' }); baselineSections = deepClone(bnSections); setPhase('back'); setStatus('সংরক্ষণ সম্পন্ন হয়েছে।', true); mw.notify('সংরক্ষণ সম্পন্ন হয়েছে।', { type: 'success' }); } catch (e) { setStatus('সংরক্ষণ ব্যর্থ: ' + e); mw.notify('সংরক্ষণ ব্যর্থ: ' + e, { type: 'error' }); } mainBtn.prop('disabled', false); } else if (phase === 'back') { const ret = originPage || currentBnTitle; if (ret) window.location.href = mw.util.getUrl(ret); } }); setPhase('load'); } $(document).ready(init); })(jQuery, mediaWiki); // </nowiki> a12pn3pyiqsigm0yagrg65v79du0nx5 740994 740993 2026-05-08T13:23:20Z কমলেশ মন্ডল 72403 740994 javascript text/javascript // <nowiki> (function ($, mw) { 'use strict'; const SPECIAL_PAGE_NAME = 'বিশেষ:খালি_পাতা/SideBySide'; const toBengaliNum = n => String(n).replace(/\d/g, d => '০১২৩৪৫৬৭৮৯'[d]); function init() { mw.loader.using(['mediawiki.util'], function () { mw.util.addPortletLink( 'p-tb', mw.util.getUrl(SPECIAL_PAGE_NAME) + '?origin=' + encodeURIComponent(mw.config.get('wgPageName')), 'পাশাপাশি তুলনা', 't-sidebyside', 'বাংলা ও ইংরেজি নিবন্ধ পাশাপাশি তুলনা করুন' ); if (mw.config.get('wgPageName') === SPECIAL_PAGE_NAME) { mw.loader.using(['mediawiki.api', 'mediawiki.util'], loadTool); } }); } /*--- CSS ---*/ function injectCSS() { if ($('#sbs-styles').length) return; $('<style id="sbs-styles">').text(` .sbs-wrap { max-width: 100%; box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; color: #202122; } .sbs-topbar { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; margin-bottom: 12px; padding: 16px; background: #fff; border: 1px solid #a2a9b1; border-radius: 4px; box-shadow: 0 1px 3px rgba(0,0,0,0.05); } .sbs-field { display: flex; flex-direction: column; gap: 5px; flex: 1; min-width: 180px; } .sbs-field label { font-size: 0.8em; font-weight: bold; color: #54595d; text-transform: uppercase; letter-spacing: 0.5px; } .sbs-field input { padding: 8px 10px; font-family: inherit; font-size: 1em; width: 100%; border: 1px solid #a2a9b1; border-radius: 4px; box-sizing: border-box; transition: border-color 0.25s, box-shadow 0.25s; } .sbs-field input:focus { border-color: #3366cc; outline: none; box-shadow: 0 0 0 2px rgba(51,102,204,0.2); } .sbs-field input:read-only { background: #f8f9fa; color: #72777d; cursor: default; } .sbs-btn-group { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; } .sbs-btn { padding: 8px 18px; border: 1px solid transparent; border-radius: 4px; font-size: 0.95em; font-weight: bold; cursor: pointer; transition: all 0.15s; white-space: nowrap; line-height: 1.4; } .sbs-btn:disabled { opacity: 0.45; cursor: not-allowed; } .sbs-btn.primary { background: #3366cc; color: #fff; } .sbs-btn.primary:hover:not(:disabled) { background: #2a4b8d; } .sbs-btn.success { background: #14866d; color: #fff; } .sbs-btn.success:hover:not(:disabled) { background: #0f6b56; } .sbs-btn.neutral { background: #f8f9fa; color: #202122; border-color: #a2a9b1; } .sbs-btn.neutral:hover:not(:disabled) { background: #fff; border-color: #3366cc; color: #3366cc; } .sbs-btn.danger { background: #fff; color: #d33; border-color: #d33; } .sbs-btn.danger:hover:not(:disabled) { background: #fee7e6; } .sbs-btn.locked { background: #3366cc; color: #fff; border-color: #3366cc; } .sbs-undo-group { display: flex; gap: 6px; align-items: flex-end; } .sbs-icon-btn { width: 38px; height: 38px; border: 1px solid #a2a9b1; border-radius: 4px; background: #f8f9fa; cursor: pointer; font-size: 1.3em; display: flex; align-items: center; justify-content: center; transition: all 0.15s; color: #202122; flex-shrink: 0; font-weight: bold; line-height: 1; } .sbs-icon-btn:hover:not(:disabled) { background: #fff; border-color: #3366cc; color: #3366cc; } .sbs-icon-btn:disabled { opacity: 0.4; cursor: not-allowed; } .sbs-status { font-size: 0.9em; color: #54595d; margin-bottom: 10px; min-height: 1.4em; font-weight: 500; } .sbs-count-bar { display: none; font-size: 0.88em; color: #3366cc; font-weight: 600; margin-bottom: 10px; padding: 7px 14px; background: #eaf3fb; border-radius: 4px; border: 1px solid #c8d8f0; } .sbs-grid-wrap { display: none; border: 1px solid #a2a9b1; border-radius: 4px; background: #fff; box-shadow: 0 2px 6px rgba(0,0,0,0.05); overflow: hidden; } .sbs-col-headers { display: grid; grid-template-columns: 1fr 1fr; background: #eaecf0; border-bottom: 2px solid #c8ccd1; position: relative; z-index: 5; } .sbs-col-header { padding: 10px 16px; font-size: 0.82em; font-weight: bold; color: #202122; text-transform: uppercase; letter-spacing: 0.4px; } .sbs-col-header:first-child { border-right: 1px solid #c8ccd1; } .sbs-panels { display: grid; grid-template-columns: 1fr 1fr; max-height: 76vh; overflow: hidden; } .sbs-panel-en, .sbs-panel-bn { position: relative; overflow-y: scroll; overflow-x: hidden; max-height: 76vh; box-sizing: border-box; } .sbs-panel-en { border-right: 1px solid #a2a9b1; background: #f8f9fa; } .sbs-panel-bn { background: #fff; } .sbs-sec-hdr-en, .sbs-sec-hdr-bn { padding: 9px 16px; font-size: 0.92em; font-weight: bold; color: #3366cc; background: #eaf3fb; border-top: 2px solid #a2a9b1; border-bottom: 1px solid #c8d8f0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: flex; align-items: center; } .sbs-sec-num { display: inline-block; background: #3366cc; color: #fff; border-radius: 10px; padding: 0 6px; font-size: 0.75em; margin-right: 4px; vertical-align: middle; font-weight: bold; line-height: 1.7; } .sbs-cell-en { padding: 20px 18px; font-size: 1em; line-height: 1.75; color: #202122; white-space: pre-wrap; word-break: break-word; box-sizing: border-box; border-bottom: 1px solid #eaecf0; min-height: 100px; } .sbs-cell-bn { box-sizing: border-box; border-bottom: 1px solid #eaecf0; min-height: 100px; } .sbs-cell-bn textarea { width: 100%; border: none; font-family: inherit; font-size: 1em; line-height: 1.75; resize: none; background: transparent; padding: 20px 18px; color: #202122; outline: none; box-sizing: border-box; overflow: hidden; min-height: 100px; display: block; } @media (max-width: 768px) { .sbs-col-headers, .sbs-panels { grid-template-columns: 1fr; } .sbs-panel-en { border-right: none; border-bottom: 1px solid #a2a9b1; max-height: 40vh; } .sbs-panel-bn { max-height: 50vh; } } `).appendTo('head'); } /*--- Wikitext helpers ---*/ function parseByHeadings(wikitext) { const lines = wikitext.split('\n'); const sections = []; let current = { heading: null, level: 0, content: [] }; for (const line of lines) { const m = line.match(/^(={1,6})\s*(.+?)\s*\1\s*$/); if (m) { sections.push(current); current = { heading: m[2].trim(), level: m[1].length, content: [] }; } else { current.content.push(line); } } sections.push(current); return sections.filter(s => s.heading != null || s.content.join('\n').trim().length > 0); } function sectionToText(sec) { return sec.content.join('\n').trim(); } function sectionsToWikitext(sections) { return sections.filter(sec => { const body = sec.content.join('\n').trim(); return body.length > 0; }).map(sec => { const h = '='.repeat(sec.level); if (sec.heading === null) return sec.content.join('\n').trimEnd(); return h + ' ' + sec.heading + ' ' + h + '\n' + sec.content.join('\n').trimEnd(); }).join('\n\n'); } function deepClone(sections) { return sections.map(s => ({ heading: s.heading, level: s.level, content: [...s.content], isPlaceholder: s.isPlaceholder })); } /* Count bar */ function updateCountBar(bnSections, $bar) { const total = bnSections.length; const withText = bnSections.filter(s => sectionToText(s).length > 0).length; const empty = total - withText; $bar.html( '<strong>' + toBengaliNum(total) + '</strong> টি বিভাগ' + '&nbsp;&nbsp;|&nbsp;&nbsp;' + '<strong style="color: #14866d">' + toBengaliNum(withText) + '</strong> টি পাঠ্য সহ' + '&nbsp;&nbsp;|&nbsp;&nbsp;' + '<strong style="color: #d33">' + toBengaliNum(empty) + '</strong> টি খালি' ).show(); } /*--- API helpers ---*/ async function getEnTitle(bnTitle, api) { try { const r = await api.get({ action: 'query', titles: bnTitle, prop: 'pageprops', ppprop: 'wikibase_item', formatversion: 2 }); const page = r.query.pages[0]; if (!page || page.missing) return null; const qid = page.pageprops && page.pageprops.wikibase_item; if (!qid) return null; const wdApi = new mw.ForeignApi('https://www.wikidata.org/w/api.php'); const wd = await wdApi.get({ action: 'wbgetentities', ids: qid, props: 'sitelinks', sitefilter: 'enwikibooks', formatversion: 2 }); const sl = wd.entities[qid] && wd.entities[qid].sitelinks && wd.entities[qid].sitelinks.enwikibooks; return sl ? sl.title : null; } catch (e) { return null; } } async function fetchWikitext(title, isEn) { const apiobj = isEn ? new mw.ForeignApi('https://en.wikibooks.org/w/api.php') : new mw.Api(); const data = await apiobj.get({ action: 'query', titles: title, prop: 'revisions', rvprop: 'content', rvslots: 'main', formatversion: 2 }); const page = data.query.pages[0]; if (page.missing) throw new Error('পাতা পাওয়া যায়নি: ' + title); return page.revisions[0].slots.main.content; } /* Main tool */ function loadTool() { document.title = 'পাশাপাশি তুলনা - বাংলা উইকিবই'; $('#firstHeading').text('পাশাপাশি তুলনা সরঞ্জাম'); $('#mw-content-text').empty(); injectCSS(); const api = new mw.Api(); const urlParams = new URLSearchParams(window.location.search); const originPage = urlParams.get('origin') || ''; const wrap = $('<div>').addClass('sbs-wrap'); $('#mw-content-text').append(wrap); /* Top bar */ const topbar = $('<div>').addClass('sbs-topbar'); const bnField = $('<div>').addClass('sbs-field'); const bnInput = $('<input type="text">').val(originPage).attr('placeholder', 'বাংলা শিরোনাম'); bnField.append($('<label>').text('বাংলা নিবন্ধ'), bnInput); const enField = $('<div>').addClass('sbs-field'); const enInput = $('<input type="text">').attr('placeholder', 'English title'); enField.append($('<label>').text('ইংরেজি নিবন্ধ'), enInput); const btnGroup = $('<div>').addClass('sbs-btn-group'); const mainBtn = $('<button>').addClass('sbs-btn primary').text('লোড করুন'); const discardBtn = $('<button>').addClass('sbs-btn danger').text('বাতিল').hide(); const undoGroup = $('<div>').addClass('sbs-undo-group').hide(); const undoBtn = $('<button>').addClass('sbs-icon-btn').attr('title', 'পূর্বাবস্থায় ফেরান').html('&#8592;'); const redoBtn = $('<button>').addClass('sbs-icon-btn').attr('title', 'পুনরায় করুন').html('&#8594;'); undoGroup.append(undoBtn, redoBtn); const scrollLockBtn = $('<button>').addClass('sbs-btn neutral').attr('title', 'স্ক্রল লক').text('স্ক্রল মুক্ত').hide(); btnGroup.append(mainBtn, discardBtn, scrollLockBtn, undoGroup); topbar.append(bnField, enField, btnGroup); wrap.append(topbar); const status = $('<div>').addClass('sbs-status'); wrap.append(status); let statusTimeout; function setStatus(msg, autoClear = false) { status.text(msg); clearTimeout(statusTimeout); if (autoClear) { statusTimeout = setTimeout(() => status.text(''), 4000); } } const countBar = $('<div>').addClass('sbs-count-bar'); wrap.append(countBar); /* Grid: col-headers + two scroll panels */ const gridWrap = $('<div>').addClass('sbs-grid-wrap'); const colHeaders = $('<div>').addClass('sbs-col-headers').append( $('<div>').addClass('sbs-col-header').text('ইংরেজি (শুধু পড়ুন)'), $('<div>').addClass('sbs-col-header').text('বাংলা (সম্পাদনা যোগ্য)') ); const panels = $('<div>').addClass('sbs-panels'); const panelEn = $('<div>').addClass('sbs-panel-en'); const panelBn = $('<div>').addClass('sbs-panel-bn'); panels.append(panelEn, panelBn); gridWrap.append(colHeaders, panels); wrap.append(gridWrap); /* Scroll lock */ let scrollLocked = false; let isSyncing = false; function syncScroll(source, target) { if (!scrollLocked || isSyncing) return; isSyncing = true; const sourceNodes = source.children('.sbs-sec-hdr-en, .sbs-sec-hdr-bn'); const targetNodes = target.children('.sbs-sec-hdr-en, .sbs-sec-hdr-bn'); const sourceScrollTop = source[0].scrollTop; let topIdx = 0; sourceNodes.each(function (i) { if (this.offsetTop < sourceScrollTop + 5) { topIdx = i; } else { return false; } }); const srcElem = sourceNodes[topIdx]; const tgtElem = targetNodes[topIdx]; if (srcElem && tgtElem) { const srcCell = $(srcElem).next()[0]; const tgtCell = $(tgtElem).next()[0]; const scrolledPastElem = sourceScrollTop - srcElem.offsetTop; const srcHeight = (srcElem.offsetHeight + (srcCell ? srcCell.offsetHeight : 0)) || 1; const tgtHeight = tgtElem.offsetHeight + (tgtCell ? tgtCell.offsetHeight : 0); const ratio = Math.max(0, scrolledPastElem / srcHeight); target[0].scrollTop = tgtElem.offsetTop + (tgtHeight * ratio); } else { const ratio = source[0].scrollTop / Math.max(1, source[0].scrollHeight - source[0].clientHeight); target[0].scrollTop = ratio * (target[0].scrollHeight - target[0].clientHeight); } isSyncing = false; } panelEn.on('scroll', () => syncScroll(panelEn, panelBn)); panelBn.on('scroll', () => syncScroll(panelBn, panelEn)); scrollLockBtn.on('click', () => { scrollLocked = !scrollLocked; if (scrollLocked) { scrollLockBtn.text('স্ক্রল লক').addClass('locked'); syncScroll(panelBn, panelEn); } else { scrollLockBtn.text('স্ক্রল মুক্ত').removeClass('locked'); } }); /* State */ let enSections = [], bnSections = [], baselineSections = []; let currentBnTitle = ''; let activeTA = null, undoStack = [], redoStack = []; let phase = 'load'; function resizeTA(ta) { ta.style.height = 'auto'; ta.style.height = ta.scrollHeight + 'px'; } /* Undo / Redo */ function applyUndoRedo(val) { if (!activeTA) return; /* Snapshot page scroll BEFORE touching the DOM. resizeTA triggers a browser-native scrollIntoView asynchronously, so we must restore inside a rAF that runs after that scroll fires. */ const savedPageY = window.scrollY; const panel = panelBn[0]; const ta = activeTA[0]; activeTA.val(val); const idx = activeTA.data('idx'); bnSections[idx].content = val.split('\n'); resizeTA(ta); updateCountBar(bnSections, countBar); requestAnimationFrame(() => { /* Undo the page-level scroll the browser performed. */ window.scrollTo(0, savedPageY); /* Now scroll only the panel so the textarea is visible. */ const taTop = ta.offsetTop; const taBottom = taTop + ta.offsetHeight; const panelTop = panel.scrollTop; const panelBottom = panelTop + panel.clientHeight; if (taTop < panelTop) { panel.scrollTop = taTop - 20; } else if (taBottom > panelBottom) { panel.scrollTop = taBottom - panel.clientHeight + 20; } }); } function holdToRepeat(btn, action) { let holdTimer = null; let repeatTimer = null; function stop() { clearTimeout(holdTimer); clearInterval(repeatTimer); holdTimer = null; repeatTimer = null; } btn[0].addEventListener('pointerdown', function (e) { if (e.button !== undefined && e.button !== 0) return; e.preventDefault(); this.setPointerCapture(e.pointerId); action(); holdTimer = setTimeout(function () { repeatTimer = setInterval(action, 80); }, 400); }); btn[0].addEventListener('pointerup', stop); btn[0].addEventListener('pointercancel', stop); } holdToRepeat(undoBtn, () => { if (!activeTA || !undoStack.length) return; redoStack.push(activeTA.val()); applyUndoRedo(undoStack.pop()); }); holdToRepeat(redoBtn, () => { if (!activeTA || !redoStack.length) return; undoStack.push(activeTA.val()); applyUndoRedo(redoStack.pop()); }); function lockInputs() { bnInput.prop('readonly', true); enInput.prop('readonly', true); } function unlockInputs() { bnInput.prop('readonly', false); enInput.prop('readonly', false); } function setPhase(p) { phase = p; if (p === 'load') { mainBtn.text('লোড করুন').removeClass('success neutral').addClass('primary'); discardBtn.hide(); undoGroup.hide(); gridWrap.hide(); countBar.hide(); scrollLockBtn.hide(); unlockInputs(); } else if (p === 'save') { mainBtn.text('সংরক্ষণ করুন').removeClass('primary neutral').addClass('success'); discardBtn.show(); undoGroup.show(); gridWrap.show(); scrollLockBtn.show(); lockInputs(); } else if (p === 'back') { mainBtn.text('মূল পাতায় ফিরুন').removeClass('primary success').addClass('neutral'); discardBtn.show(); undoGroup.show(); scrollLockBtn.show(); lockInputs(); } } /* Build grid */ function buildGrid() { panelEn.empty(); panelBn.empty(); activeTA = null; undoStack = []; redoStack = []; const isLead = s => s.heading == null; const isHeading = s => s.heading != null; const enLeads = enSections.filter(isLead); const bnLeads = bnSections.filter(isLead); const enHeads = enSections.filter(isHeading); const bnHeads = bnSections.filter(isHeading); const displayPairs = []; const maxLeads = Math.max(enLeads.length, bnLeads.length); for (let i = 0; i < maxLeads; i++) displayPairs.push({ en: enLeads[i] || null, bn: bnLeads[i] || null }); const maxHeads = Math.max(enHeads.length, bnHeads.length); for (let i = 0; i < maxHeads; i++) displayPairs.push({ en: enHeads[i] || null, bn: bnHeads[i] || null }); bnSections = displayPairs.map(pair => { if (pair.bn) return pair.bn; return { heading: pair.en ? pair.en.heading : null, level: pair.en ? pair.en.level : 2, content: [], isPlaceholder: true }; }); updateCountBar(bnSections, countBar); displayPairs.forEach((pair, i) => { const enSec = pair.en; const bnSec = bnSections[i]; const enText = enSec ? sectionToText(enSec) : ''; const bnText = sectionToText(bnSec); const num = toBengaliNum(i + 1); const enTitle = enSec ? (enSec.heading !== null ? enSec.heading : '(ভূমিকা)') : '(অনুপস্থিত)'; const bnTitleFallback = enSec && enSec.heading !== null ? enSec.heading : '(ভূমিকা)'; const bnTitleVal = bnSec.heading !== null ? bnSec.heading : ''; const numBadge = () => $('<span>').addClass('sbs-sec-num').text(num); const enHdr = $('<div>').addClass('sbs-sec-hdr-en').append(numBadge(), document.createTextNode(' ' + enTitle)); const enCell = $('<div>').addClass('sbs-cell-en').text(enText); panelEn.append(enHdr, enCell); const isIntroSection = bnTitleFallback === '(ভূমিকা)'; const bnHdr = $('<div>').addClass('sbs-sec-hdr-bn'); const bnHdrInput = $('<input type="text">') .val(bnTitleVal) .attr('placeholder', bnTitleFallback) .css({ 'background': 'transparent', 'border': 'none', 'border-bottom': '1px solid transparent', 'color': 'inherit', 'font-family': 'inherit', 'font-size': 'inherit', 'font-weight': 'inherit', 'width': 'calc(100% - 35px)', 'outline': 'none', 'padding': '0 4px', 'margin-left': '4px', 'cursor': isIntroSection ? 'default' : 'text' }); if (isIntroSection) { bnHdrInput.attr('readonly', true); } else { bnHdrInput .on('focus', function () { $(this).css({ 'background': '#fff', 'border-bottom': '1px solid #3366cc' }); }) .on('blur', function () { $(this).css({ 'background': 'transparent', 'border-bottom': '1px solid transparent' }); }) .on('input', function () { bnSec.heading = $(this).val().trim() || null; if (phase === 'back') setPhase('save'); }); } bnHdr.append(numBadge(), bnHdrInput); const bnCell = $('<div>').addClass('sbs-cell-bn'); const ta = $('<textarea>').val(bnText).attr('placeholder', 'অনুবাদ লিখুন...').data('idx', i); ta.on('focus', () => { if (activeTA && activeTA[0] !== ta[0]) { undoStack = []; redoStack = []; } activeTA = ta; }); ta.on('input', (function (idx) { return function () { resizeTA(ta[0]); undoStack.push(sectionToText(bnSections[idx])); if (undoStack.length > 50) undoStack.shift(); redoStack = []; bnSections[idx].content = ta.val().split('\n'); updateCountBar(bnSections, countBar); if (phase === 'back') setPhase('save'); }; })(i)); /* Paste fix: preserve panel scroll position so the cursor does not disappear behind the sticky header div on paste. The scroll event listeners and syncScroll logic are completely untouched. */ ta.on('paste', function () { const panel = panelBn[0]; const savedScrollTop = panel.scrollTop; requestAnimationFrame(function () { resizeTA(ta[0]); panel.scrollTop = savedScrollTop; }); }); bnCell.append(ta); panelBn.append(bnHdr, bnCell); setTimeout(() => resizeTA(ta[0]), 0); }); } /* Wikidata auto-fetch */ if (originPage) { setStatus('উইকিডেটা থেকে ইংরেজি শিরোনাম খোঁজা হচ্ছে...'); getEnTitle(originPage, api).then(t => { if (t) { enInput.val(t); setStatus('ইংরেজি শিরোনাম পাওয়া গেছে।', true); } else { setStatus('উইকিডেটায় সংযোগ পাওয়া যায়নি। নিজে লিখুন।', true); } }); } /* Discard */ discardBtn.on('click', () => { if (!confirm('পরিবর্তনগুলো বাতিল করবেন?')) return; bnSections = deepClone(baselineSections); buildGrid(); setPhase('back'); mw.notify('পরিবর্তন বাতিল করা হয়েছে।', { type: 'info' }); setStatus('', true); }); /* Main button */ mainBtn.on('click', async () => { const bnTitle = bnInput.val().trim(); const enTitle = enInput.val().trim(); if (phase === 'load') { if (!bnTitle || !enTitle) { setStatus('দুটি শিরোনামই লিখুন।', true); return; } try { mainBtn.prop('disabled', true).text('লোড হচ্ছে...'); setStatus('নিবন্ধ লোড হচ্ছে...'); const [enWT, bnWT] = await Promise.all([ fetchWikitext(enTitle, true), fetchWikitext(bnTitle, false) ]); currentBnTitle = bnTitle; enSections = parseByHeadings(enWT); bnSections = parseByHeadings(bnWT); baselineSections = deepClone(bnSections); buildGrid(); setPhase('save'); setStatus('লোড সম্পন্ন।', true); } catch (e) { setStatus('ত্রুটি: ' + e.message); mainBtn.prop('disabled', false).text('লোড করুন'); } mainBtn.prop('disabled', false); } else if (phase === 'save') { mainBtn.prop('disabled', true).text('সংরক্ষণ করা হচ্ছে...'); try { await api.postWithToken('csrf', { action: 'edit', title: currentBnTitle, text: sectionsToWikitext(bnSections), summary: 'পাশাপাশি সরঞ্জাম (স্ক্রিপ্ট)' }); baselineSections = deepClone(bnSections); setPhase('back'); setStatus('সংরক্ষণ সম্পন্ন হয়েছে।', true); mw.notify('সংরক্ষণ সম্পন্ন হয়েছে।', { type: 'success' }); } catch (e) { setStatus('সংরক্ষণ ব্যর্থ: ' + e); mw.notify('সংরক্ষণ ব্যর্থ: ' + e, { type: 'error' }); } mainBtn.prop('disabled', false); } else if (phase === 'back') { const ret = originPage || currentBnTitle; if (ret) window.location.href = mw.util.getUrl(ret); } }); setPhase('load'); } $(document).ready(init); })(jQuery, mediaWiki); // </nowiki> e0wxulwf9803ps8quop44g0gkpzazhu User:Enbi/common.js 2 172174 741031 739794 2026-05-08T16:45:37Z Enbi 72574 741031 javascript text/javascript importScript('User:Enbi/UnnamedScript.js'); importScript('User:Enbi/testScript.js'); importScript('User:Enbi/simul.js'); importScript('User:Enbi/newUserFilter.js'); importScript('User:Enbi/new.js'); importScript('User:Enbi/wikiCMD.js'); importScript('User:enbi/LTA-undo.js'); importScript('User:Enbi/LACsuppresssed.js'); importScript('w:en:MediaWiki:Gadget-script-installer.js') importScript('User:Enbi/highlightUsernamePatterns.js'); // Backlink: [[User:Enbi/highlightUsernamePatterns.js]] importScript('User:Enbi/testScript2.js'); // Backlink: [[User:Enbi/testScript2.js]] importScript('User:Enbi/editAlert.js'); // Backlink: [[User:Enbi/editAlert.js]] importScript('User:Enbi/searchReplace.js'); // Backlink: [[User:Enbi/searchReplace.js]] importScript('User:Enbi/LACSRG.js'); // Backlink: [[User:Enbi/LACSRG.js]] importScript('User:Enbi/test2.js'); // Backlink: [[User:Enbi/test2.js]] if (mw.config.get('wgPageName') === 'User:Enbi/Gateway/run') { importScript('User:Enbi/Gateway.js'); } qljprfrgj8e2a1g4ifrhexvf2nzb0ak User:OUT is this/common.js 2 175239 740976 740974 2026-05-08T12:04:53Z OUT is this 73801 Undid revision [[Special:Diff/740974|740974]] by [[Special:Contributions/OUT is this|OUT is this]] ([[User talk:OUT is this|talk]]) 740976 javascript text/javascript //テスト mw.loader.load( '/w/index.php?title=User:OUT is this/SimpleBookmark.js&action=raw&ctype=text/javascript' ); //絞り込みおまかせ表示 [[利用者:OUT is this/advancedRandom.js]] mw.loader.load( '/w/index.php?title=利用者:OUT is this/advancedRandom.js&action=raw&ctype=text/javascript' ); /* --- マネージャー本体の読み込み --- インポート元:[[利用者:OUT_is_this/ScriptManager.js]]*/ mw.loader.load( '//test.wikipedia.org/w/index.php?title=User:OUT_is_this/ScriptManager.js&action=raw&ctype=text/javascript' ); o08zrbjvo9odt6s74aqqxm96gqrlbf0 740977 740976 2026-05-08T12:05:22Z OUT is this 73801 [[:test:User:OUT is this/SimpleBookmark.js]] を ScriptManager に追加 (ブックマーク) 740977 javascript text/javascript window.scriptManagerList = [ // [[:test:User:OUT is this/SimpleBookmark.js]] { name: 'ブックマーク', lang: 'test', title: 'User:OUT is this/SimpleBookmark.js' }, ]; //テスト //絞り込みおまかせ表示 [[利用者:OUT is this/advancedRandom.js]] mw.loader.load( '/w/index.php?title=利用者:OUT is this/advancedRandom.js&action=raw&ctype=text/javascript' ); /* --- マネージャー本体の読み込み --- インポート元:[[利用者:OUT_is_this/ScriptManager.js]]*/ mw.loader.load( '//test.wikipedia.org/w/index.php?title=User:OUT_is_this/ScriptManager.js&action=raw&ctype=text/javascript' ); t9qrll55828ntojm9mc5uel8xe8ajba 740978 740977 2026-05-08T12:08:55Z OUT is this 73801 Undid revision [[Special:Diff/740977|740977]] by [[Special:Contributions/OUT is this|OUT is this]] ([[User talk:OUT is this|talk]]) 740978 javascript text/javascript //テスト mw.loader.load( '/w/index.php?title=User:OUT is this/SimpleBookmark.js&action=raw&ctype=text/javascript' ); //絞り込みおまかせ表示 [[利用者:OUT is this/advancedRandom.js]] mw.loader.load( '/w/index.php?title=利用者:OUT is this/advancedRandom.js&action=raw&ctype=text/javascript' ); /* --- マネージャー本体の読み込み --- インポート元:[[利用者:OUT_is_this/ScriptManager.js]]*/ mw.loader.load( '//test.wikipedia.org/w/index.php?title=User:OUT_is_this/ScriptManager.js&action=raw&ctype=text/javascript' ); o08zrbjvo9odt6s74aqqxm96gqrlbf0 740984 740978 2026-05-08T12:34:35Z OUT is this 73801 [[:test:User:OUT is this/SimpleBookmark.js]] を ScriptManager に追加 (OUT is this/SimpleBookmark.js) 740984 javascript text/javascript window.scriptManagerList = [ // [[:test:User:OUT is this/SimpleBookmark.js]] { name: 'OUT is this/SimpleBookmark.js', lang: 'test', title: 'User:OUT is this/SimpleBookmark.js' }, ]; //テスト //絞り込みおまかせ表示 [[利用者:OUT is this/advancedRandom.js]] mw.loader.load( '/w/index.php?title=利用者:OUT is this/advancedRandom.js&action=raw&ctype=text/javascript' ); /* --- マネージャー本体の読み込み --- インポート元:[[利用者:OUT_is_this/ScriptManager.js]]*/ mw.loader.load( '//test.wikipedia.org/w/index.php?title=User:OUT_is_this/ScriptManager.js&action=raw&ctype=text/javascript' ); d8iyexf2qjy2t8mrmbmzq8x5hra3clc User:OUT is this/ScriptManager.js 2 175250 740975 740973 2026-05-08T12:02:56Z OUT is this 73801 740975 javascript text/javascript (function($, mw) { 'use strict'; // --- 1. スクリプト情報の整理 --- var rawList = window.scriptManagerList || []; var usedIds = {}; var scriptList = rawList.map(function(script) { var finalUrl = ''; // --- URL生成ロジック --- if (script.url) { finalUrl = script.url; } else { var langCode = (script.lang === undefined) ? 'ja' : script.lang; var langPrefix = (langCode !== '') ? langCode + '.' : ''; var domain = script.domain || 'wikipedia.org'; var title = script.title || ''; finalUrl = '//' + langPrefix + domain + '/w/index.php?title=' + encodeURIComponent(title) + '&action=raw&ctype=text/javascript'; } var match = finalUrl.match(/[?&]title=([^&]+)/); var pageTitle = match ? decodeURIComponent(match[1]) : 'Unknown'; var idBase = 'unknown'; if (match) { idBase = pageTitle .replace(/^(User|利用者):[^/]+\//i, '') .replace(/\.js$/i, '') .replace(/[ _ %]+/g, '_') .replace(/[^a-zA-Z0-9_]/g, ''); } var finalId = idBase; var counter = 2; while (usedIds[finalId]) { finalId = idBase + '_' + counter; counter++; } usedIds[finalId] = true; return { id: finalId, name: script.name, url: finalUrl, pageTitle: pageTitle }; }); // --- 2. 現在の状態の取得 --- var userSettings = JSON.parse(localStorage.getItem('wp-script-manager-v4') || '{}'); var pageName = mw.config.get('wgPageName').replace(/[ _ ]+/g, '').toLowerCase(); var action = mw.config.get('wgAction'); var ns = mw.config.get('wgNamespaceNumber'); var isDiff = !!mw.config.get('wgDiffNewId'); var isPreview = ['submit', 'preview'].indexOf(action) !== -1 && $('#wikiPreview').length > 0; var isMainNS = (ns === 0 || ns === 4); var isUserNS = (ns === 2 || ns === 3); var isTalkNS = (ns % 2 !== 0 && ns > 0); var isSpecialNS = (ns === -1); var isEditMode = (action === 'edit' || action === 'submit'); // --- 3. メニューへのリンク追加 --- $(function() { var smPageUrl = mw.util.getUrl('Special:SM'); var smLinks = $( ['', '-sticky-header'] .map(function(suffix) { var parentId = $('#p-user-menu-pages' + suffix).length ? 'p-user-menu-pages' : 'p-personal'; return mw.util.addPortletLink( parentId + suffix, smPageUrl, 'スクリプト管理画面', 'pt-scriptmanager' + suffix, 'Script Managerを開く', null, '#pt-logout' + suffix ); }) .filter(function(elOrNull) { return elOrNull !== null; }) ); if (smLinks.length > 0) { const style = ` li[id^="pt-scriptmanager"] a { width: auto !important; padding-left: 25px; white-space: nowrap; height: 20px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><path d="M20 10c0-.7-.1-1.3-.2-1.9l-2.3-.4c-.2-.7-.4-1.4-.8-2l1.4-1.9c-.5-.7-1.1-1.3-1.8-1.8l-1.9 1.4c-.6-.4-1.3-.6-2-.8l-.4-2.3c-.7-.1-1.3-.2-1.9-.2s-1.3.1-1.9.2l-.4 2.3c-.7.2-1.4.4-2 .8L4.1 2c-.7.5-1.3 1.1-1.8 1.8l1.4 1.9c-.4.6-.6 1.3-.8 2l-2.3.4c-.1.6-.2 1.2-.2 1.9s.1 1.3.2 1.9l2.3.4c.2.7.4 1.4.8 2l-1.4 1.9c.5.7 1.1 1.3 1.8 1.8l1.9-1.4c.6.4 1.3.6 2 .8l.4 2.3c.6.1 1.2.2 1.9.2s1.3-.1 1.9-.2l.4-2.3c.7-.2 1.4-.4 2-.8l1.9 1.4c.7-.5 1.3-1.1 1.8-1.8l-1.4-1.9c.4-.6.6-1.3.8-2l2.3-.4c.1-.6.2-1.2.2-1.9z" fill="%23202122"/><text x="10" y="13" font-family="sans-serif" font-weight="bold" font-size="8px" fill="white" text-anchor="middle">JS</text></svg>'); background-repeat: no-repeat; background-size: 20px 20px; background-position: center left; } `; $('<style>').text(style).appendTo('head'); } }); // --- 4. スクリプトのロード判定ロジック --- scriptList.forEach(function(script) { var s = userSettings[script.id]; if (!s || !s.enabled) return; var shouldLoad = false; if (s.isBlacklistMode) { var blocked = false; if (isDiff && !s.onDiff) blocked = true; else if (isPreview && !s.onPreview) blocked = true; else if (isEditMode && !s.onEdit) blocked = true; else if (action === 'view' && !isDiff) { if (isMainNS && !s.onMain) blocked = true; else if (isUserNS && !s.onUser) blocked = true; else if (isTalkNS && !s.onTalk) blocked = true; else if (isSpecialNS && !s.onSpecial) blocked = true; } shouldLoad = !blocked; } else { if (isDiff && s.onDiff) shouldLoad = true; else if (isPreview && s.onPreview) shouldLoad = true; else if (isEditMode && s.onEdit) shouldLoad = true; else if (action === 'view' && !isDiff) { if (isMainNS && s.onMain) shouldLoad = true; else if (isUserNS && s.onUser) shouldLoad = true; else if (isTalkNS && s.onTalk) shouldLoad = true; else if (isSpecialNS && s.onSpecial) shouldLoad = true; } } if (shouldLoad) mw.loader.load(script.url); }); // --- 5. 管理画面(Special:SM)の構築 --- if (/^(special|特別):(scriptmanager|sm)$/i.test(pageName)) { document.title = 'Script Manager'; $('#firstHeading').text('Script Manager'); var $body = $('#mw-content-text').empty(); $('<style>').text(` #sm-container { font-family: sans-serif; color: #202122; max-width: 1000px; margin: 20px 0; } .sm-card { background: #fff; border: 1px solid #c8ccd1; border-left: 5px solid #36c; border-radius: 8px; padding: 14px; margin-bottom: 16px; display: flex; align-items: center; transition: all 0.3s ease; } .sm-info { flex-grow: 1; min-width: 160px; overflow: hidden; margin-right: 10px; } .sm-name { font-weight: bold; font-size: 1.1em; display: flex; align-items: center; color: #202122; } .sm-id-row { font-size: 0.8em; color: #72777d; font-family: monospace; margin-top: 4px; display: flex; align-items: center; gap: 8px; } .sm-js-link { color: #36c; text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 250px; border-bottom: 1px solid transparent; } .sm-js-link:hover { border-bottom-color: #36c; } .sm-status-badge { font-size: 10px; padding: 2px 6px; border-radius: 10px; margin-left: 10px; text-transform: uppercase; border: 1px solid #c8ccd1; background: #f8f9fa; color: #72777d; } .status-on { background: #eaf3ff; color: #36c; border-color: #36c; } .sm-mode-switch { padding: 0 10px; border-right: 1px solid #eaecf0; margin-right: 10px; text-align: center; } .sm-mode-toggle { border: 1px solid #a2a9b1; border-radius: 4px; padding: 4px 8px; cursor: pointer; font-size: 10.5px; background: #fff; color: #202122; white-space: nowrap; } .sm-main-toggle { border-right: 2px solid #eaecf0; padding-right: 10px; margin-right: 10px; flex-shrink: 0; } .sm-sub-options { display: flex; gap: 8px; flex-wrap: wrap; flex-shrink: 0; } .sm-checkbox-label { display: flex; flex-direction: column; align-items: center; font-size: 0.75em; color: #54595d; cursor: pointer; min-width: 46px; text-align: center; } .sm-checkbox-label input { margin-bottom: 4px; cursor: pointer; } .mode-bl-active .sm-sub-checkbox:not(:checked) { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #d33; background: #d33; position: relative; border-radius: 2px; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after, .mode-bl-active .sm-sub-checkbox:not(:checked)::before { content: ''; position: absolute; width: 10px; height: 1.8px; background-color: white; top: 50%; left: 50%; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after { transform: translate(-50%, -50%) rotate(45deg); } .mode-bl-active .sm-sub-checkbox:not(:checked)::before { transform: translate(-50%, -50%) rotate(-45deg); } .mode-bl-active .sm-sub-checkbox:checked { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #a2a9b1; border-radius: 2px; background: #fff; } .mode-bl-active { border-left-color: #d33 !important; } .mode-bl-active .status-on { background: #fee7e6; color: #d33; border-color: #d33; } .sm-card.disabled { background: #f8f9fa !important; opacity: 0.6; filter: grayscale(1); } .sm-footer-actions { position: sticky; bottom: 20px; float: right; display: flex; gap: 10px; z-index: 100; } .sm-btn { border: none; padding: 12px 24px; border-radius: 4px; font-weight: bold; cursor: pointer; transition: background 0.2s; } #sm-save-btn { background: #36c; color: #fff; } #sm-common-js-btn { background: #f8f9fa; color: #202122; border: 1px solid #a2a9b1; text-decoration: none; font-size: 0.95em; display: flex; align-items: center; } /* 管理スクリプトがない時の案内用スタイル */ .sm-guide-box { background: #f8f9fa; border: 1px dashed #a2a9b1; padding: 20px; border-radius: 8px; text-align: center; margin: 20px 0; } .sm-guide-box h3 { margin-top: 0; } .sm-step { display: inline-block; text-align: left; margin: 10px 0; vertical-align: top; width: 250px; padding: 10px; } `).appendTo('head'); var $container = $('<div id="sm-container"></div>'); if (scriptList.length === 0) { var manualUrl = 'https://ja.wikipedia.org/wiki/' + encodeURIComponent('利用者:OUT_is_this/ScriptManager'); $container.append(` <div class="sm-guide-box"> <h3>スクリプトが登録されていません</h3> <p>以下の手順でスクリプトを追加してください:</p> <div class="sm-step"><b>1. 探す</b><br>他の人の <code>.js</code> ページを開きます。</div> <div class="sm-step"><b>2. 追加する</b><br>ページ上部の「ScriptManagerに追加」ボタンを押します。</div> <div class="sm-step"><b>3. 保存</b><br>名前を付けて保存すると自動で common.js に書き込まれます。</div> <div style="margin-top:20px; padding-top:15px; border-top:1px solid #eaecf0;"> <a href="${manualUrl}" target="_blank" style="font-weight:bold; text-decoration:none; color:#36c;"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 20 20" style="margin-right:6px;"><path d="M10 0C4.48 0 0 4.48 0 10s4.48 10 10 10 10-4.48 10-10S15.52 0 10 0zm0 15c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1s1 .45 1 1v4c0 .55-.45 1-1 1zm1-8H9V5h2v2z" fill="#36c"/> </svg> common.js に手入力で書き込む方法や、詳しい使い方はこちら(解説ページ) </a> </div> </div> `); } scriptList.forEach(function(script) { var s = userSettings[script.id] || { enabled: false, isBlacklistMode: false, onMain: true, onUser: true, onTalk: true, onSpecial: true, onEdit: true, onPreview: true, onDiff: true }; var $card = $('<div class="sm-card">').toggleClass('disabled', !s.enabled); if (s.isBlacklistMode) $card.addClass('mode-bl-active'); var $status = $('<span class="sm-status-badge"></span>').addClass(s.enabled ? 'status-on' : '').text(s.enabled ? 'ON' : 'OFF'); var viewUrl = script.url.replace(/[?&]action=raw/, '').replace(/[?&]ctype=[^&]+/, ''); var $info = $('<div class="sm-info">').append( $('<div class="sm-name">').text(script.name).append($status), $('<div class="sm-id-row">').append( $('<span>').text(script.id), $('<a>').attr({href: viewUrl, target: '_blank', title: script.pageTitle}) .addClass('sm-js-link').text('⇨ ' + script.pageTitle) ) ); var $modeBtn = $('<div class="sm-mode-toggle">').text(s.isBlacklistMode ? '制限ベース' : '許可ベース'); $modeBtn.on('click', function() { var isBl = $(this).text() === '許可ベース'; $(this).text(isBl ? '制限ベース' : '許可ベース'); $card.toggleClass('mode-bl-active', isBl); }); var $mainToggle = $('<div class="sm-main-toggle">').append( $('<label class="sm-checkbox-label">').append($('<input type="checkbox" class="sm-master">').prop('checked', s.enabled).attr('data-id', script.id), '<b>有効</b>') ); function createOption(label, key, val) { var $input = $('<input type="checkbox" class="sm-sub-checkbox">').addClass('sm-' + key).prop('checked', val); return $('<label class="sm-checkbox-label">').append($input, label); } var $subOptions = $('<div class="sm-sub-options">').append( createOption('記事/WP', 'main', s.onMain), createOption('利用者', 'user', s.onUser), createOption('ノート', 'talk', s.onTalk), createOption('特別', 'special', s.onSpecial), createOption('編集', 'edit', s.onEdit), createOption('プレビュー', 'preview', s.onPreview), createOption('差分', 'diff', s.onDiff) ); $mainToggle.find('.sm-master').on('change', function() { var checked = $(this).is(':checked'); $card.toggleClass('disabled', !checked); $card.find('.sm-status-badge').toggleClass('status-on', checked).text(checked ? 'ON' : 'OFF'); }); $container.append($card.append($info, $('<div class="sm-mode-switch">').append($modeBtn), $mainToggle, $subOptions)); }); $body.append($container, $('<div class="sm-footer-actions">').append( $('<a>').attr({id: 'sm-common-js-btn', href: mw.util.getUrl('Special:MyPage/common.js'), target: '_blank'}).addClass('sm-btn').text('common.js を編集'), $('<button id="sm-save-btn">設定を保存して適用</button>').addClass('sm-btn').on('click', function() { var newSettings = {}; $('.sm-card').each(function() { var $c = $(this); var id = $c.find('.sm-master').attr('data-id'); newSettings[id] = { enabled: $c.find('.sm-master').is(':checked'), isBlacklistMode: $c.find('.sm-mode-toggle').text() === '制限ベース', onMain: $c.find('.sm-main').is(':checked'), onUser: $c.find('.sm-user').is(':checked'), onTalk: $c.find('.sm-talk').is(':checked'), onSpecial: $c.find('.sm-special').is(':checked'), onEdit: $c.find('.sm-edit').is(':checked'), onPreview: $c.find('.sm-preview').is(':checked'), onDiff: $c.find('.sm-diff').is(':checked') }; }); localStorage.setItem('wp-script-manager-v4', JSON.stringify(newSettings)); mw.notify('設定を保存しました。'); var returnUrl = document.referrer; setTimeout(function() { location.href = (returnUrl && returnUrl.indexOf(location.hostname) !== -1) ? returnUrl : mw.util.getUrl('Main_Page'); }, 800); }) )); } $(function() { // 1. 基本情報の取得 const pageName = mw.config.get('wgPageName').replace(/_/g, ' '); const action = mw.config.get('wgAction'); const userName = mw.config.get('wgUserName') const userNs = mw.config.get('wgFormattedNamespaces')[2]; const myCommonJs = userNs + ':' + userName + '/common.js'; const isJsPage = pageName.endsWith('.js'); const isManagerScript = pageName.endsWith('ScriptManager.js'); const isDiff = !!mw.config.get('wgDiffNewId'); // 2. 登録済み判定 function checkRegistration() { if (!window.scriptManagerList) return false; return window.scriptManagerList.some(script => { const savedTitle = (script.title || '').replace(/_/g, ' '); return savedTitle === pageName; }); } const isAlreadyRegistered = checkRegistration(); // --- 表示条件 --- // ・JSページである // ・現在のページが「自分のcommon.js」もしくは ScriptManager.jsでは表示しない。 // ・未登録である // ・閲覧モードかつ差分表示ではない // --- ボタンのデザイン変更(青い四角の箱) --- if (isJsPage && pageName !== myCommonJs && !isManagerScript && !isAlreadyRegistered && action === 'view' && !isDiff) { const $smInstallBtn = $('<button>') .text('ScriptManagerに追加') .addClass('mw-ui-button mw-ui-progressive') .css({ 'margin-left': '12px', 'vertical-align': 'middle', 'border-radius': '2px', 'padding': '0 12px', 'height': '32px', 'font-weight': 'bold', 'box-shadow': 'none' }) .on('click', function() { const scriptName = prompt('このスクリプトに名前をつけてください:', mw.config.get('wgTitle')); if (scriptName) { installScript(pageName, scriptName, $(this)); } }); $('#firstHeading').append($smInstallBtn); } // 3. common.js への追加処理 function installScript(targetPage, label, $button) { const api = new mw.Api(); // --- 1. ドメインと言語の判定ロジック(省略) --- const rawDomain = mw.config.get('wgServerName'); let lang = ''; let domain = rawDomain; const parts = rawDomain.split('.'); if (parts.length >= 3 && parts.slice(-2).join('.') === 'wikipedia.org') { lang = parts[0]; domain = 'wikipedia.org'; } if (domain === 'wikipedia.org') domain = ''; if (lang === 'ja') lang = ''; // --- 2. エントリとウィキリンクの作成(省略) --- let entryParts = [`name: '${label}'`]; if (lang !== '') entryParts.push(`lang: '${lang}'`); if (domain !== '') entryParts.push(`domain: '${domain}'`); entryParts.push(`title: '${targetPage}'`); let wikiLink = (domain !== '' && domain !== 'wikipedia.org') ? `[${location.protocol}//${rawDomain}/wiki/${encodeURI(targetPage)} ${targetPage}]` : `[[${(lang !== '' && lang !== 'ja') ? ':' + lang + ':' : ''}${targetPage}]]`; // --- 最終的な書き出し形式の組み立て --- // 1行目にコメント、2行目にオブジェクト(インデント付き) const newEntry = ` // ${wikiLink}\n { ${entryParts.join(', ')} },`; api.get({ action: 'query', prop: 'revisions', titles: myCommonJs, rvprop: 'content', rvslots: 'main' }).done(function(data) { const page = Object.values(data.query.pages)[0]; let content = (page && page.revisions) ? page.revisions[0].slots.main['*'] : ''; // --- 重複コードの検出と削除 (既存) --- const escapedPage = targetPage.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/[ _]/g, '[ _]'); const loadPattern = new RegExp(`(mw\\.loader\\.load|importScript)\\s*\\(\\s*['"\`].*?${escapedPage}.*?['"\`]\\s*\\);?`, 'g'); if (loadPattern.test(content)) { if (!confirm(`注意:common.js 内にこのスクリプトの既存の読み込みコードが見つかりました。\n\n「OK」:既存のコードを削除して移行します。\n「キャンセル」:中止します。`)) return; content = content.replace(loadPattern, '').replace(/\n{3,}/g, '\n\n'); } // --- コンテンツの更新 --- // 配列の開始位置のすぐ後ろに「コメント + オブジェクト」を挿入 if (content.includes('window.scriptManagerList = [')) { content = content.replace('window.scriptManagerList = [', `window.scriptManagerList = [\n${newEntry}`); } else { content = `window.scriptManagerList = [\n${newEntry}\n];\n\n` + content; } api.postWithToken('csrf', { action: 'edit', title: myCommonJs, text: content, summary: `${wikiLink} を ScriptManager に追加 (${label})` }).done(function(saveData) { if (saveData.edit && saveData.edit.result === 'Success') { mw.notify(label + ' を追加しました。'); $button.fadeOut(); if (!window.scriptManagerList) window.scriptManagerList = []; window.scriptManagerList.push({ name: label, lang: lang, domain: domain, title: targetPage }); } }); }); } }); })(jQuery, mediaWiki); l7a6drg527cb4qfezycnnysjt16c9hi 740979 740975 2026-05-08T12:18:32Z OUT is this 73801 740979 javascript text/javascript (function($, mw) { 'use strict'; // --- 1. スクリプト情報の整理 --- var rawList = window.scriptManagerList || []; var usedIds = {}; var scriptList = rawList.map(function(script) { var finalUrl = ''; // --- URL生成ロジック --- if (script.url) { finalUrl = script.url; } else { var langCode = (script.lang === undefined) ? 'ja' : script.lang; var langPrefix = (langCode !== '') ? langCode + '.' : ''; var domain = script.domain || 'wikipedia.org'; var title = script.title || ''; finalUrl = '//' + langPrefix + domain + '/w/index.php?title=' + encodeURIComponent(title) + '&action=raw&ctype=text/javascript'; } var match = finalUrl.match(/[?&]title=([^&]+)/); var pageTitle = match ? decodeURIComponent(match[1]) : 'Unknown'; var idBase = 'unknown'; if (match) { idBase = pageTitle .replace(/^(User|利用者):[^/]+\//i, '') .replace(/\.js$/i, '') .replace(/[ _ %]+/g, '_') .replace(/[^a-zA-Z0-9_]/g, ''); } var finalId = idBase; var counter = 2; while (usedIds[finalId]) { finalId = idBase + '_' + counter; counter++; } usedIds[finalId] = true; return { id: finalId, name: script.name, url: finalUrl, pageTitle: pageTitle }; }); // --- 2. 現在の状態の取得 --- var userSettings = JSON.parse(localStorage.getItem('wp-script-manager-v4') || '{}'); var pageName = mw.config.get('wgPageName').replace(/[ _ ]+/g, '').toLowerCase(); var action = mw.config.get('wgAction'); var ns = mw.config.get('wgNamespaceNumber'); var isDiff = !!mw.config.get('wgDiffNewId'); var isPreview = ['submit', 'preview'].indexOf(action) !== -1 && $('#wikiPreview').length > 0; var isMainNS = (ns === 0 || ns === 4); var isUserNS = (ns === 2 || ns === 3); var isTalkNS = (ns % 2 !== 0 && ns > 0); var isSpecialNS = (ns === -1); var isEditMode = (action === 'edit' || action === 'submit'); // --- 3. メニューへのリンク追加 --- $(function() { var smPageUrl = mw.util.getUrl('Special:SM'); var smLinks = $( ['', '-sticky-header'] .map(function(suffix) { var parentId = $('#p-user-menu-pages' + suffix).length ? 'p-user-menu-pages' : 'p-personal'; return mw.util.addPortletLink( parentId + suffix, smPageUrl, 'スクリプト管理画面', 'pt-scriptmanager' + suffix, 'Script Managerを開く', null, '#pt-logout' + suffix ); }) .filter(function(elOrNull) { return elOrNull !== null; }) ); if (smLinks.length > 0) { const style = ` li[id^="pt-scriptmanager"] a { width: auto !important; padding-left: 25px; white-space: nowrap; height: 20px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><path d="M20 10c0-.7-.1-1.3-.2-1.9l-2.3-.4c-.2-.7-.4-1.4-.8-2l1.4-1.9c-.5-.7-1.1-1.3-1.8-1.8l-1.9 1.4c-.6-.4-1.3-.6-2-.8l-.4-2.3c-.7-.1-1.3-.2-1.9-.2s-1.3.1-1.9.2l-.4 2.3c-.7.2-1.4.4-2 .8L4.1 2c-.7.5-1.3 1.1-1.8 1.8l1.4 1.9c-.4.6-.6 1.3-.8 2l-2.3.4c-.1.6-.2 1.2-.2 1.9s.1 1.3.2 1.9l2.3.4c.2.7.4 1.4.8 2l-1.4 1.9c.5.7 1.1 1.3 1.8 1.8l1.9-1.4c.6.4 1.3.6 2 .8l.4 2.3c.6.1 1.2.2 1.9.2s1.3-.1 1.9-.2l.4-2.3c.7-.2 1.4-.4 2-.8l1.9 1.4c.7-.5 1.3-1.1 1.8-1.8l-1.4-1.9c.4-.6.6-1.3.8-2l2.3-.4c.1-.6.2-1.2.2-1.9z" fill="%23202122"/><text x="10" y="13" font-family="sans-serif" font-weight="bold" font-size="8px" fill="white" text-anchor="middle">JS</text></svg>'); background-repeat: no-repeat; background-size: 20px 20px; background-position: center left; } `; $('<style>').text(style).appendTo('head'); } }); // --- 4. スクリプトのロード判定ロジック --- scriptList.forEach(function(script) { var s = userSettings[script.id]; if (!s || !s.enabled) return; var shouldLoad = false; if (s.isBlacklistMode) { var blocked = false; if (isDiff && !s.onDiff) blocked = true; else if (isPreview && !s.onPreview) blocked = true; else if (isEditMode && !s.onEdit) blocked = true; else if (action === 'view' && !isDiff) { if (isMainNS && !s.onMain) blocked = true; else if (isUserNS && !s.onUser) blocked = true; else if (isTalkNS && !s.onTalk) blocked = true; else if (isSpecialNS && !s.onSpecial) blocked = true; } shouldLoad = !blocked; } else { if (isDiff && s.onDiff) shouldLoad = true; else if (isPreview && s.onPreview) shouldLoad = true; else if (isEditMode && s.onEdit) shouldLoad = true; else if (action === 'view' && !isDiff) { if (isMainNS && s.onMain) shouldLoad = true; else if (isUserNS && s.onUser) shouldLoad = true; else if (isTalkNS && s.onTalk) shouldLoad = true; else if (isSpecialNS && s.onSpecial) shouldLoad = true; } } if (shouldLoad) mw.loader.load(script.url); }); // --- 5. 管理画面(Special:SM)の構築 --- if (/^(special|特別):(scriptmanager|sm)$/i.test(pageName)) { document.title = 'Script Manager'; $('#firstHeading').text('Script Manager'); var $body = $('#mw-content-text').empty(); $('<style>').text(` #sm-container { font-family: sans-serif; color: #202122; max-width: 1000px; margin: 20px 0; } .sm-card { background: #fff; border: 1px solid #c8ccd1; border-left: 5px solid #36c; border-radius: 8px; padding: 14px; margin-bottom: 16px; display: flex; align-items: center; transition: all 0.3s ease; } .sm-info { flex-grow: 1; min-width: 160px; overflow: hidden; margin-right: 10px; } .sm-name { font-weight: bold; font-size: 1.1em; display: flex; align-items: center; color: #202122; } .sm-id-row { font-size: 0.8em; color: #72777d; font-family: monospace; margin-top: 4px; display: flex; align-items: center; gap: 8px; } .sm-js-link { color: #36c; text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 250px; border-bottom: 1px solid transparent; } .sm-js-link:hover { border-bottom-color: #36c; } .sm-status-badge { font-size: 10px; padding: 2px 6px; border-radius: 10px; margin-left: 10px; text-transform: uppercase; border: 1px solid #c8ccd1; background: #f8f9fa; color: #72777d; } .status-on { background: #eaf3ff; color: #36c; border-color: #36c; } .sm-mode-switch { padding: 0 10px; border-right: 1px solid #eaecf0; margin-right: 10px; text-align: center; } .sm-mode-toggle { border: 1px solid #a2a9b1; border-radius: 4px; padding: 4px 8px; cursor: pointer; font-size: 10.5px; background: #fff; color: #202122; white-space: nowrap; } .sm-main-toggle { border-right: 2px solid #eaecf0; padding-right: 10px; margin-right: 10px; flex-shrink: 0; } .sm-sub-options { display: flex; gap: 8px; flex-wrap: wrap; flex-shrink: 0; } .sm-checkbox-label { display: flex; flex-direction: column; align-items: center; font-size: 0.75em; color: #54595d; cursor: pointer; min-width: 46px; text-align: center; } .sm-checkbox-label input { margin-bottom: 4px; cursor: pointer; } .mode-bl-active .sm-sub-checkbox:not(:checked) { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #d33; background: #d33; position: relative; border-radius: 2px; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after, .mode-bl-active .sm-sub-checkbox:not(:checked)::before { content: ''; position: absolute; width: 10px; height: 1.8px; background-color: white; top: 50%; left: 50%; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after { transform: translate(-50%, -50%) rotate(45deg); } .mode-bl-active .sm-sub-checkbox:not(:checked)::before { transform: translate(-50%, -50%) rotate(-45deg); } .mode-bl-active .sm-sub-checkbox:checked { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #a2a9b1; border-radius: 2px; background: #fff; } .mode-bl-active { border-left-color: #d33 !important; } .mode-bl-active .status-on { background: #fee7e6; color: #d33; border-color: #d33; } .sm-card.disabled { background: #f8f9fa !important; opacity: 0.6; filter: grayscale(1); } .sm-footer-actions { position: sticky; bottom: 20px; float: right; display: flex; gap: 10px; z-index: 100; } .sm-btn { border: none; padding: 12px 24px; border-radius: 4px; font-weight: bold; cursor: pointer; transition: background 0.2s; } #sm-save-btn { background: #36c; color: #fff; } #sm-common-js-btn { background: #f8f9fa; color: #202122; border: 1px solid #a2a9b1; text-decoration: none; font-size: 0.95em; display: flex; align-items: center; } /* 管理スクリプトがない時の案内用スタイル */ .sm-guide-box { background: #f8f9fa; border: 1px dashed #a2a9b1; padding: 20px; border-radius: 8px; text-align: center; margin: 20px 0; } .sm-guide-box h3 { margin-top: 0; } .sm-step { display: inline-block; text-align: left; margin: 10px 0; vertical-align: top; width: 250px; padding: 10px; } `).appendTo('head'); var $container = $('<div id="sm-container"></div>'); if (scriptList.length === 0) { var manualUrl = 'https://ja.wikipedia.org/wiki/' + encodeURIComponent('利用者:OUT_is_this/ScriptManager'); $container.append(` <div class="sm-guide-box"> <h3>スクリプトが登録されていません</h3> <p>以下の手順でスクリプトを追加してください:</p> <div class="sm-step"><b>1. 探す</b><br>他の人の <code>.js</code> ページを開きます。</div> <div class="sm-step"><b>2. 追加する</b><br>ページ上部の「ScriptManagerに追加」ボタンを押します。</div> <div class="sm-step"><b>3. 保存</b><br>名前を付けて保存すると自動で common.js に書き込まれます。</div> <div style="margin-top:20px; padding-top:15px; border-top:1px solid #eaecf0;"> <a href="${manualUrl}" target="_blank" style="font-weight:bold; text-decoration:none; color:#36c; display:inline-flex; align-items:center;"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 20 20" style="flex-shrink:0; vertical-align:middle; margin-right:6px;"> <path d="M10 0C4.48 0 0 4.48 0 10s4.48 10 10 10 10-4.48 10-10S15.52 0 10 0zm0 15c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1s1 .45 1 1v4c0 .55-.45 1-1 1zm1-8H9V5h2v2z" fill="#36c"/> </svg> <span> common.js に手入力で書き込む方法や他ドメインのjsを指定する方法、<br />その他詳しい使い方は <a href="${manualUrl}" target="_blank" style="font-weight:bold; text-decoration:none; color:#36c;">こちら(解説ページ)</a> </span> </a> </div> </div> `); } scriptList.forEach(function(script) { var s = userSettings[script.id] || { enabled: false, isBlacklistMode: false, onMain: true, onUser: true, onTalk: true, onSpecial: true, onEdit: true, onPreview: true, onDiff: true }; var $card = $('<div class="sm-card">').toggleClass('disabled', !s.enabled); if (s.isBlacklistMode) $card.addClass('mode-bl-active'); var $status = $('<span class="sm-status-badge"></span>').addClass(s.enabled ? 'status-on' : '').text(s.enabled ? 'ON' : 'OFF'); var viewUrl = script.url.replace(/[?&]action=raw/, '').replace(/[?&]ctype=[^&]+/, ''); var $info = $('<div class="sm-info">').append( $('<div class="sm-name">').text(script.name).append($status), $('<div class="sm-id-row">').append( $('<span>').text(script.id), $('<a>').attr({href: viewUrl, target: '_blank', title: script.pageTitle}) .addClass('sm-js-link').text('⇨ ' + script.pageTitle) ) ); var $modeBtn = $('<div class="sm-mode-toggle">').text(s.isBlacklistMode ? '制限ベース' : '許可ベース'); $modeBtn.on('click', function() { var isBl = $(this).text() === '許可ベース'; $(this).text(isBl ? '制限ベース' : '許可ベース'); $card.toggleClass('mode-bl-active', isBl); }); var $mainToggle = $('<div class="sm-main-toggle">').append( $('<label class="sm-checkbox-label">').append($('<input type="checkbox" class="sm-master">').prop('checked', s.enabled).attr('data-id', script.id), '<b>有効</b>') ); function createOption(label, key, val) { var $input = $('<input type="checkbox" class="sm-sub-checkbox">').addClass('sm-' + key).prop('checked', val); return $('<label class="sm-checkbox-label">').append($input, label); } var $subOptions = $('<div class="sm-sub-options">').append( createOption('記事/WP', 'main', s.onMain), createOption('利用者', 'user', s.onUser), createOption('ノート', 'talk', s.onTalk), createOption('特別', 'special', s.onSpecial), createOption('編集', 'edit', s.onEdit), createOption('プレビュー', 'preview', s.onPreview), createOption('差分', 'diff', s.onDiff) ); $mainToggle.find('.sm-master').on('change', function() { var checked = $(this).is(':checked'); $card.toggleClass('disabled', !checked); $card.find('.sm-status-badge').toggleClass('status-on', checked).text(checked ? 'ON' : 'OFF'); }); $container.append($card.append($info, $('<div class="sm-mode-switch">').append($modeBtn), $mainToggle, $subOptions)); }); $body.append($container, $('<div class="sm-footer-actions">').append( $('<a>').attr({id: 'sm-common-js-btn', href: mw.util.getUrl('Special:MyPage/common.js'), target: '_blank'}).addClass('sm-btn').text('common.js を編集'), $('<button id="sm-save-btn">設定を保存して適用</button>').addClass('sm-btn').on('click', function() { var newSettings = {}; $('.sm-card').each(function() { var $c = $(this); var id = $c.find('.sm-master').attr('data-id'); newSettings[id] = { enabled: $c.find('.sm-master').is(':checked'), isBlacklistMode: $c.find('.sm-mode-toggle').text() === '制限ベース', onMain: $c.find('.sm-main').is(':checked'), onUser: $c.find('.sm-user').is(':checked'), onTalk: $c.find('.sm-talk').is(':checked'), onSpecial: $c.find('.sm-special').is(':checked'), onEdit: $c.find('.sm-edit').is(':checked'), onPreview: $c.find('.sm-preview').is(':checked'), onDiff: $c.find('.sm-diff').is(':checked') }; }); localStorage.setItem('wp-script-manager-v4', JSON.stringify(newSettings)); mw.notify('設定を保存しました。'); var returnUrl = document.referrer; setTimeout(function() { location.href = (returnUrl && returnUrl.indexOf(location.hostname) !== -1) ? returnUrl : mw.util.getUrl('Main_Page'); }, 800); }) )); } $(function() { // 1. 基本情報の取得 const pageName = mw.config.get('wgPageName').replace(/_/g, ' '); const action = mw.config.get('wgAction'); const userName = mw.config.get('wgUserName') const userNs = mw.config.get('wgFormattedNamespaces')[2]; const myCommonJs = userNs + ':' + userName + '/common.js'; const isJsPage = pageName.endsWith('.js'); const isManagerScript = pageName.endsWith('ScriptManager.js'); const isDiff = !!mw.config.get('wgDiffNewId'); // 2. 登録済み判定 function checkRegistration() { if (!window.scriptManagerList) return false; return window.scriptManagerList.some(script => { const savedTitle = (script.title || '').replace(/_/g, ' '); return savedTitle === pageName; }); } const isAlreadyRegistered = checkRegistration(); // --- 表示条件 --- // ・JSページである // ・現在のページが「自分のcommon.js」もしくは ScriptManager.jsでは表示しない。 // ・未登録である // ・閲覧モードかつ差分表示ではない // --- ボタンのデザイン変更(青い四角の箱) --- if (isJsPage && pageName !== myCommonJs && !isManagerScript && !isAlreadyRegistered && action === 'view' && !isDiff) { const $smInstallBtn = $('<button>') .text('ScriptManagerに追加') .addClass('mw-ui-button mw-ui-progressive') .css({ 'margin-left': '12px', 'vertical-align': 'middle', 'border-radius': '2px', 'padding': '0 12px', 'height': '32px', 'font-weight': 'bold', 'box-shadow': 'none' }) .on('click', function() { const scriptName = prompt('このスクリプトに名前をつけてください:', mw.config.get('wgTitle')); if (scriptName) { installScript(pageName, scriptName, $(this)); } }); $('#firstHeading').append($smInstallBtn); } // 3. common.js への追加処理 function installScript(targetPage, label, $button) { const api = new mw.Api(); // --- 1. ドメインと言語の判定ロジック(省略) --- const rawDomain = mw.config.get('wgServerName'); let lang = ''; let domain = rawDomain; const parts = rawDomain.split('.'); if (parts.length >= 3 && parts.slice(-2).join('.') === 'wikipedia.org') { lang = parts[0]; domain = 'wikipedia.org'; } if (domain === 'wikipedia.org') domain = ''; if (lang === 'ja') lang = ''; // --- 2. エントリとウィキリンクの作成(省略) --- let entryParts = [`name: '${label}'`]; if (lang !== '') entryParts.push(`lang: '${lang}'`); if (domain !== '') entryParts.push(`domain: '${domain}'`); entryParts.push(`title: '${targetPage}'`); let wikiLink = (domain !== '' && domain !== 'wikipedia.org') ? `[${location.protocol}//${rawDomain}/wiki/${encodeURI(targetPage)} ${targetPage}]` : `[[${(lang !== '' && lang !== 'ja') ? ':' + lang + ':' : ''}${targetPage}]]`; // --- 最終的な書き出し形式の組み立て --- // 1行目にコメント、2行目にオブジェクト(インデント付き) const newEntry = ` // ${wikiLink}\n { ${entryParts.join(', ')} },`; api.get({ action: 'query', prop: 'revisions', titles: myCommonJs, rvprop: 'content', rvslots: 'main' }).done(function(data) { const page = Object.values(data.query.pages)[0]; let content = (page && page.revisions) ? page.revisions[0].slots.main['*'] : ''; // --- 重複コードの検出と削除 (既存) --- const escapedPage = targetPage.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/[ _]/g, '[ _]'); const loadPattern = new RegExp(`(mw\\.loader\\.load|importScript)\\s*\\(\\s*['"\`].*?${escapedPage}.*?['"\`]\\s*\\);?`, 'g'); if (loadPattern.test(content)) { if (!confirm(`注意:common.js 内にこのスクリプトの既存の読み込みコードが見つかりました。\n\n「OK」:既存のコードを削除して移行します。\n「キャンセル」:中止します。`)) return; content = content.replace(loadPattern, '').replace(/\n{3,}/g, '\n\n'); } // --- コンテンツの更新 --- // 配列の開始位置のすぐ後ろに「コメント + オブジェクト」を挿入 if (content.includes('window.scriptManagerList = [')) { content = content.replace('window.scriptManagerList = [', `window.scriptManagerList = [\n${newEntry}`); } else { content = `window.scriptManagerList = [\n${newEntry}\n];\n\n` + content; } api.postWithToken('csrf', { action: 'edit', title: myCommonJs, text: content, summary: `${wikiLink} を ScriptManager に追加 (${label})` }).done(function(saveData) { if (saveData.edit && saveData.edit.result === 'Success') { mw.notify(label + ' を追加しました。'); $button.fadeOut(); if (!window.scriptManagerList) window.scriptManagerList = []; window.scriptManagerList.push({ name: label, lang: lang, domain: domain, title: targetPage }); } }); }); } }); })(jQuery, mediaWiki); oc679k4j6g6l66pisdp02ohsn1yogdf 740980 740979 2026-05-08T12:21:15Z OUT is this 73801 740980 javascript text/javascript (function($, mw) { 'use strict'; // --- 1. スクリプト情報の整理 --- var rawList = window.scriptManagerList || []; var usedIds = {}; var scriptList = rawList.map(function(script) { var finalUrl = ''; // --- URL生成ロジック --- if (script.url) { finalUrl = script.url; } else { var langCode = (script.lang === undefined) ? 'ja' : script.lang; var langPrefix = (langCode !== '') ? langCode + '.' : ''; var domain = script.domain || 'wikipedia.org'; var title = script.title || ''; finalUrl = '//' + langPrefix + domain + '/w/index.php?title=' + encodeURIComponent(title) + '&action=raw&ctype=text/javascript'; } var match = finalUrl.match(/[?&]title=([^&]+)/); var pageTitle = match ? decodeURIComponent(match[1]) : 'Unknown'; var idBase = 'unknown'; if (match) { idBase = pageTitle .replace(/^(User|利用者):[^/]+\//i, '') .replace(/\.js$/i, '') .replace(/[ _ %]+/g, '_') .replace(/[^a-zA-Z0-9_]/g, ''); } var finalId = idBase; var counter = 2; while (usedIds[finalId]) { finalId = idBase + '_' + counter; counter++; } usedIds[finalId] = true; return { id: finalId, name: script.name, url: finalUrl, pageTitle: pageTitle }; }); // --- 2. 現在の状態の取得 --- var userSettings = JSON.parse(localStorage.getItem('wp-script-manager-v4') || '{}'); var pageName = mw.config.get('wgPageName').replace(/[ _ ]+/g, '').toLowerCase(); var action = mw.config.get('wgAction'); var ns = mw.config.get('wgNamespaceNumber'); var isDiff = !!mw.config.get('wgDiffNewId'); var isPreview = ['submit', 'preview'].indexOf(action) !== -1 && $('#wikiPreview').length > 0; var isMainNS = (ns === 0 || ns === 4); var isUserNS = (ns === 2 || ns === 3); var isTalkNS = (ns % 2 !== 0 && ns > 0); var isSpecialNS = (ns === -1); var isEditMode = (action === 'edit' || action === 'submit'); // --- 3. メニューへのリンク追加 --- $(function() { var smPageUrl = mw.util.getUrl('Special:SM'); var smLinks = $( ['', '-sticky-header'] .map(function(suffix) { var parentId = $('#p-user-menu-pages' + suffix).length ? 'p-user-menu-pages' : 'p-personal'; return mw.util.addPortletLink( parentId + suffix, smPageUrl, 'スクリプト管理画面', 'pt-scriptmanager' + suffix, 'Script Managerを開く', null, '#pt-logout' + suffix ); }) .filter(function(elOrNull) { return elOrNull !== null; }) ); if (smLinks.length > 0) { const style = ` li[id^="pt-scriptmanager"] a { width: auto !important; padding-left: 25px; white-space: nowrap; height: 20px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><path d="M20 10c0-.7-.1-1.3-.2-1.9l-2.3-.4c-.2-.7-.4-1.4-.8-2l1.4-1.9c-.5-.7-1.1-1.3-1.8-1.8l-1.9 1.4c-.6-.4-1.3-.6-2-.8l-.4-2.3c-.7-.1-1.3-.2-1.9-.2s-1.3.1-1.9.2l-.4 2.3c-.7.2-1.4.4-2 .8L4.1 2c-.7.5-1.3 1.1-1.8 1.8l1.4 1.9c-.4.6-.6 1.3-.8 2l-2.3.4c-.1.6-.2 1.2-.2 1.9s.1 1.3.2 1.9l2.3.4c.2.7.4 1.4.8 2l-1.4 1.9c.5.7 1.1 1.3 1.8 1.8l1.9-1.4c.6.4 1.3.6 2 .8l.4 2.3c.6.1 1.2.2 1.9.2s1.3-.1 1.9-.2l.4-2.3c.7-.2 1.4-.4 2-.8l1.9 1.4c.7-.5 1.3-1.1 1.8-1.8l-1.4-1.9c.4-.6.6-1.3.8-2l2.3-.4c.1-.6.2-1.2.2-1.9z" fill="%23202122"/><text x="10" y="13" font-family="sans-serif" font-weight="bold" font-size="8px" fill="white" text-anchor="middle">JS</text></svg>'); background-repeat: no-repeat; background-size: 20px 20px; background-position: center left; } `; $('<style>').text(style).appendTo('head'); } }); // --- 4. スクリプトのロード判定ロジック --- scriptList.forEach(function(script) { var s = userSettings[script.id]; if (!s || !s.enabled) return; var shouldLoad = false; if (s.isBlacklistMode) { var blocked = false; if (isDiff && !s.onDiff) blocked = true; else if (isPreview && !s.onPreview) blocked = true; else if (isEditMode && !s.onEdit) blocked = true; else if (action === 'view' && !isDiff) { if (isMainNS && !s.onMain) blocked = true; else if (isUserNS && !s.onUser) blocked = true; else if (isTalkNS && !s.onTalk) blocked = true; else if (isSpecialNS && !s.onSpecial) blocked = true; } shouldLoad = !blocked; } else { if (isDiff && s.onDiff) shouldLoad = true; else if (isPreview && s.onPreview) shouldLoad = true; else if (isEditMode && s.onEdit) shouldLoad = true; else if (action === 'view' && !isDiff) { if (isMainNS && s.onMain) shouldLoad = true; else if (isUserNS && s.onUser) shouldLoad = true; else if (isTalkNS && s.onTalk) shouldLoad = true; else if (isSpecialNS && s.onSpecial) shouldLoad = true; } } if (shouldLoad) mw.loader.load(script.url); }); // --- 5. 管理画面(Special:SM)の構築 --- if (/^(special|特別):(scriptmanager|sm)$/i.test(pageName)) { document.title = 'Script Manager'; $('#firstHeading').text('Script Manager'); var $body = $('#mw-content-text').empty(); $('<style>').text(` #sm-container { font-family: sans-serif; color: #202122; max-width: 1000px; margin: 20px 0; } .sm-card { background: #fff; border: 1px solid #c8ccd1; border-left: 5px solid #36c; border-radius: 8px; padding: 14px; margin-bottom: 16px; display: flex; align-items: center; transition: all 0.3s ease; } .sm-info { flex-grow: 1; min-width: 160px; overflow: hidden; margin-right: 10px; } .sm-name { font-weight: bold; font-size: 1.1em; display: flex; align-items: center; color: #202122; } .sm-id-row { font-size: 0.8em; color: #72777d; font-family: monospace; margin-top: 4px; display: flex; align-items: center; gap: 8px; } .sm-js-link { color: #36c; text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 250px; border-bottom: 1px solid transparent; } .sm-js-link:hover { border-bottom-color: #36c; } .sm-status-badge { font-size: 10px; padding: 2px 6px; border-radius: 10px; margin-left: 10px; text-transform: uppercase; border: 1px solid #c8ccd1; background: #f8f9fa; color: #72777d; } .status-on { background: #eaf3ff; color: #36c; border-color: #36c; } .sm-mode-switch { padding: 0 10px; border-right: 1px solid #eaecf0; margin-right: 10px; text-align: center; } .sm-mode-toggle { border: 1px solid #a2a9b1; border-radius: 4px; padding: 4px 8px; cursor: pointer; font-size: 10.5px; background: #fff; color: #202122; white-space: nowrap; } .sm-main-toggle { border-right: 2px solid #eaecf0; padding-right: 10px; margin-right: 10px; flex-shrink: 0; } .sm-sub-options { display: flex; gap: 8px; flex-wrap: wrap; flex-shrink: 0; } .sm-checkbox-label { display: flex; flex-direction: column; align-items: center; font-size: 0.75em; color: #54595d; cursor: pointer; min-width: 46px; text-align: center; } .sm-checkbox-label input { margin-bottom: 4px; cursor: pointer; } .mode-bl-active .sm-sub-checkbox:not(:checked) { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #d33; background: #d33; position: relative; border-radius: 2px; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after, .mode-bl-active .sm-sub-checkbox:not(:checked)::before { content: ''; position: absolute; width: 10px; height: 1.8px; background-color: white; top: 50%; left: 50%; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after { transform: translate(-50%, -50%) rotate(45deg); } .mode-bl-active .sm-sub-checkbox:not(:checked)::before { transform: translate(-50%, -50%) rotate(-45deg); } .mode-bl-active .sm-sub-checkbox:checked { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #a2a9b1; border-radius: 2px; background: #fff; } .mode-bl-active { border-left-color: #d33 !important; } .mode-bl-active .status-on { background: #fee7e6; color: #d33; border-color: #d33; } .sm-card.disabled { background: #f8f9fa !important; opacity: 0.6; filter: grayscale(1); } .sm-footer-actions { position: sticky; bottom: 20px; float: right; display: flex; gap: 10px; z-index: 100; } .sm-btn { border: none; padding: 12px 24px; border-radius: 4px; font-weight: bold; cursor: pointer; transition: background 0.2s; } #sm-save-btn { background: #36c; color: #fff; } #sm-common-js-btn { background: #f8f9fa; color: #202122; border: 1px solid #a2a9b1; text-decoration: none; font-size: 0.95em; display: flex; align-items: center; } /* 管理スクリプトがない時の案内用スタイル */ .sm-guide-box { background: #f8f9fa; border: 1px dashed #a2a9b1; padding: 20px; border-radius: 8px; text-align: center; margin: 20px 0; } .sm-guide-box h3 { margin-top: 0; } .sm-step { display: inline-block; text-align: left; margin: 10px 0; vertical-align: top; width: 250px; padding: 10px; } `).appendTo('head'); var $container = $('<div id="sm-container"></div>'); if (scriptList.length === 0) { var manualUrl = 'https://ja.wikipedia.org/wiki/' + encodeURIComponent('利用者:OUT_is_this/ScriptManager'); $container.append(` <div class="sm-guide-box"> <h3>スクリプトが登録されていません</h3> <p>以下の手順でスクリプトを追加してください:</p> <div class="sm-step"><b>1. 探す</b><br>他の人の <code>.js</code> ページを開きます。</div> <div class="sm-step"><b>2. 追加する</b><br>ページ上部の「ScriptManagerに追加」ボタンを押します。</div> <div class="sm-step"><b>3. 保存</b><br>名前を付けて保存すると自動で common.js に書き込まれます。</div> <div style="margin-top:20px; padding-top:15px; border-top:1px solid #eaecf0;"> <div style="display:inline-flex; align-items:flex-start; color:#202122; text-align:left;"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 20 20" style="flex-shrink:0; margin-right:8px; margin-top:2px;"> <path d="M10 0C4.48 0 0 4.48 0 10s4.48 10 10 10 10-4.48 10-10S15.52 0 10 0zm0 15c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1s1 .45 1 1v4c0 .55-.45 1-1 1zm1-8H9V5h2v2z" fill="#36c"/> </svg> <span style="line-height:1.6;"> common.js に手入力で書き込む方法や、詳しい使い方は<br> <a href="${manualUrl}" target="_blank" style="font-weight:bold; text-decoration:none; color:#36c;">こちら(解説ページ)</a> をご覧ください。 </span> </div> </div> </div> `); } scriptList.forEach(function(script) { var s = userSettings[script.id] || { enabled: false, isBlacklistMode: false, onMain: true, onUser: true, onTalk: true, onSpecial: true, onEdit: true, onPreview: true, onDiff: true }; var $card = $('<div class="sm-card">').toggleClass('disabled', !s.enabled); if (s.isBlacklistMode) $card.addClass('mode-bl-active'); var $status = $('<span class="sm-status-badge"></span>').addClass(s.enabled ? 'status-on' : '').text(s.enabled ? 'ON' : 'OFF'); var viewUrl = script.url.replace(/[?&]action=raw/, '').replace(/[?&]ctype=[^&]+/, ''); var $info = $('<div class="sm-info">').append( $('<div class="sm-name">').text(script.name).append($status), $('<div class="sm-id-row">').append( $('<span>').text(script.id), $('<a>').attr({href: viewUrl, target: '_blank', title: script.pageTitle}) .addClass('sm-js-link').text('⇨ ' + script.pageTitle) ) ); var $modeBtn = $('<div class="sm-mode-toggle">').text(s.isBlacklistMode ? '制限ベース' : '許可ベース'); $modeBtn.on('click', function() { var isBl = $(this).text() === '許可ベース'; $(this).text(isBl ? '制限ベース' : '許可ベース'); $card.toggleClass('mode-bl-active', isBl); }); var $mainToggle = $('<div class="sm-main-toggle">').append( $('<label class="sm-checkbox-label">').append($('<input type="checkbox" class="sm-master">').prop('checked', s.enabled).attr('data-id', script.id), '<b>有効</b>') ); function createOption(label, key, val) { var $input = $('<input type="checkbox" class="sm-sub-checkbox">').addClass('sm-' + key).prop('checked', val); return $('<label class="sm-checkbox-label">').append($input, label); } var $subOptions = $('<div class="sm-sub-options">').append( createOption('記事/WP', 'main', s.onMain), createOption('利用者', 'user', s.onUser), createOption('ノート', 'talk', s.onTalk), createOption('特別', 'special', s.onSpecial), createOption('編集', 'edit', s.onEdit), createOption('プレビュー', 'preview', s.onPreview), createOption('差分', 'diff', s.onDiff) ); $mainToggle.find('.sm-master').on('change', function() { var checked = $(this).is(':checked'); $card.toggleClass('disabled', !checked); $card.find('.sm-status-badge').toggleClass('status-on', checked).text(checked ? 'ON' : 'OFF'); }); $container.append($card.append($info, $('<div class="sm-mode-switch">').append($modeBtn), $mainToggle, $subOptions)); }); $body.append($container, $('<div class="sm-footer-actions">').append( $('<a>').attr({id: 'sm-common-js-btn', href: mw.util.getUrl('Special:MyPage/common.js'), target: '_blank'}).addClass('sm-btn').text('common.js を編集'), $('<button id="sm-save-btn">設定を保存して適用</button>').addClass('sm-btn').on('click', function() { var newSettings = {}; $('.sm-card').each(function() { var $c = $(this); var id = $c.find('.sm-master').attr('data-id'); newSettings[id] = { enabled: $c.find('.sm-master').is(':checked'), isBlacklistMode: $c.find('.sm-mode-toggle').text() === '制限ベース', onMain: $c.find('.sm-main').is(':checked'), onUser: $c.find('.sm-user').is(':checked'), onTalk: $c.find('.sm-talk').is(':checked'), onSpecial: $c.find('.sm-special').is(':checked'), onEdit: $c.find('.sm-edit').is(':checked'), onPreview: $c.find('.sm-preview').is(':checked'), onDiff: $c.find('.sm-diff').is(':checked') }; }); localStorage.setItem('wp-script-manager-v4', JSON.stringify(newSettings)); mw.notify('設定を保存しました。'); var returnUrl = document.referrer; setTimeout(function() { location.href = (returnUrl && returnUrl.indexOf(location.hostname) !== -1) ? returnUrl : mw.util.getUrl('Main_Page'); }, 800); }) )); } $(function() { // 1. 基本情報の取得 const pageName = mw.config.get('wgPageName').replace(/_/g, ' '); const action = mw.config.get('wgAction'); const userName = mw.config.get('wgUserName') const userNs = mw.config.get('wgFormattedNamespaces')[2]; const myCommonJs = userNs + ':' + userName + '/common.js'; const isJsPage = pageName.endsWith('.js'); const isManagerScript = pageName.endsWith('ScriptManager.js'); const isDiff = !!mw.config.get('wgDiffNewId'); // 2. 登録済み判定 function checkRegistration() { if (!window.scriptManagerList) return false; return window.scriptManagerList.some(script => { const savedTitle = (script.title || '').replace(/_/g, ' '); return savedTitle === pageName; }); } const isAlreadyRegistered = checkRegistration(); // --- 表示条件 --- // ・JSページである // ・現在のページが「自分のcommon.js」もしくは ScriptManager.jsでは表示しない。 // ・未登録である // ・閲覧モードかつ差分表示ではない // --- ボタンのデザイン変更(青い四角の箱) --- if (isJsPage && pageName !== myCommonJs && !isManagerScript && !isAlreadyRegistered && action === 'view' && !isDiff) { const $smInstallBtn = $('<button>') .text('ScriptManagerに追加') .addClass('mw-ui-button mw-ui-progressive') .css({ 'margin-left': '12px', 'vertical-align': 'middle', 'border-radius': '2px', 'padding': '0 12px', 'height': '32px', 'font-weight': 'bold', 'box-shadow': 'none' }) .on('click', function() { const scriptName = prompt('このスクリプトに名前をつけてください:', mw.config.get('wgTitle')); if (scriptName) { installScript(pageName, scriptName, $(this)); } }); $('#firstHeading').append($smInstallBtn); } // 3. common.js への追加処理 function installScript(targetPage, label, $button) { const api = new mw.Api(); // --- 1. ドメインと言語の判定ロジック(省略) --- const rawDomain = mw.config.get('wgServerName'); let lang = ''; let domain = rawDomain; const parts = rawDomain.split('.'); if (parts.length >= 3 && parts.slice(-2).join('.') === 'wikipedia.org') { lang = parts[0]; domain = 'wikipedia.org'; } if (domain === 'wikipedia.org') domain = ''; if (lang === 'ja') lang = ''; // --- 2. エントリとウィキリンクの作成(省略) --- let entryParts = [`name: '${label}'`]; if (lang !== '') entryParts.push(`lang: '${lang}'`); if (domain !== '') entryParts.push(`domain: '${domain}'`); entryParts.push(`title: '${targetPage}'`); let wikiLink = (domain !== '' && domain !== 'wikipedia.org') ? `[${location.protocol}//${rawDomain}/wiki/${encodeURI(targetPage)} ${targetPage}]` : `[[${(lang !== '' && lang !== 'ja') ? ':' + lang + ':' : ''}${targetPage}]]`; // --- 最終的な書き出し形式の組み立て --- // 1行目にコメント、2行目にオブジェクト(インデント付き) const newEntry = ` // ${wikiLink}\n { ${entryParts.join(', ')} },`; api.get({ action: 'query', prop: 'revisions', titles: myCommonJs, rvprop: 'content', rvslots: 'main' }).done(function(data) { const page = Object.values(data.query.pages)[0]; let content = (page && page.revisions) ? page.revisions[0].slots.main['*'] : ''; // --- 重複コードの検出と削除 (既存) --- const escapedPage = targetPage.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/[ _]/g, '[ _]'); const loadPattern = new RegExp(`(mw\\.loader\\.load|importScript)\\s*\\(\\s*['"\`].*?${escapedPage}.*?['"\`]\\s*\\);?`, 'g'); if (loadPattern.test(content)) { if (!confirm(`注意:common.js 内にこのスクリプトの既存の読み込みコードが見つかりました。\n\n「OK」:既存のコードを削除して移行します。\n「キャンセル」:中止します。`)) return; content = content.replace(loadPattern, '').replace(/\n{3,}/g, '\n\n'); } // --- コンテンツの更新 --- // 配列の開始位置のすぐ後ろに「コメント + オブジェクト」を挿入 if (content.includes('window.scriptManagerList = [')) { content = content.replace('window.scriptManagerList = [', `window.scriptManagerList = [\n${newEntry}`); } else { content = `window.scriptManagerList = [\n${newEntry}\n];\n\n` + content; } api.postWithToken('csrf', { action: 'edit', title: myCommonJs, text: content, summary: `${wikiLink} を ScriptManager に追加 (${label})` }).done(function(saveData) { if (saveData.edit && saveData.edit.result === 'Success') { mw.notify(label + ' を追加しました。'); $button.fadeOut(); if (!window.scriptManagerList) window.scriptManagerList = []; window.scriptManagerList.push({ name: label, lang: lang, domain: domain, title: targetPage }); } }); }); } }); })(jQuery, mediaWiki); osf63bx4mcx7c2sp1ccuyu0w1la8xej 740981 740980 2026-05-08T12:23:58Z OUT is this 73801 740981 javascript text/javascript (function($, mw) { 'use strict'; // --- 1. スクリプト情報の整理 --- var rawList = window.scriptManagerList || []; var usedIds = {}; var scriptList = rawList.map(function(script) { var finalUrl = ''; // --- URL生成ロジック --- if (script.url) { finalUrl = script.url; } else { var langCode = (script.lang === undefined) ? 'ja' : script.lang; var langPrefix = (langCode !== '') ? langCode + '.' : ''; var domain = script.domain || 'wikipedia.org'; var title = script.title || ''; finalUrl = '//' + langPrefix + domain + '/w/index.php?title=' + encodeURIComponent(title) + '&action=raw&ctype=text/javascript'; } var match = finalUrl.match(/[?&]title=([^&]+)/); var pageTitle = match ? decodeURIComponent(match[1]) : 'Unknown'; var idBase = 'unknown'; if (match) { idBase = pageTitle .replace(/^(User|利用者):[^/]+\//i, '') .replace(/\.js$/i, '') .replace(/[ _ %]+/g, '_') .replace(/[^a-zA-Z0-9_]/g, ''); } var finalId = idBase; var counter = 2; while (usedIds[finalId]) { finalId = idBase + '_' + counter; counter++; } usedIds[finalId] = true; return { id: finalId, name: script.name, url: finalUrl, pageTitle: pageTitle }; }); // --- 2. 現在の状態の取得 --- var userSettings = JSON.parse(localStorage.getItem('wp-script-manager-v4') || '{}'); var pageName = mw.config.get('wgPageName').replace(/[ _ ]+/g, '').toLowerCase(); var action = mw.config.get('wgAction'); var ns = mw.config.get('wgNamespaceNumber'); var isDiff = !!mw.config.get('wgDiffNewId'); var isPreview = ['submit', 'preview'].indexOf(action) !== -1 && $('#wikiPreview').length > 0; var isMainNS = (ns === 0 || ns === 4); var isUserNS = (ns === 2 || ns === 3); var isTalkNS = (ns % 2 !== 0 && ns > 0); var isSpecialNS = (ns === -1); var isEditMode = (action === 'edit' || action === 'submit'); // --- 3. メニューへのリンク追加 --- $(function() { var smPageUrl = mw.util.getUrl('Special:SM'); var smLinks = $( ['', '-sticky-header'] .map(function(suffix) { var parentId = $('#p-user-menu-pages' + suffix).length ? 'p-user-menu-pages' : 'p-personal'; return mw.util.addPortletLink( parentId + suffix, smPageUrl, 'スクリプト管理画面', 'pt-scriptmanager' + suffix, 'Script Managerを開く', null, '#pt-logout' + suffix ); }) .filter(function(elOrNull) { return elOrNull !== null; }) ); if (smLinks.length > 0) { const style = ` li[id^="pt-scriptmanager"] a { width: auto !important; padding-left: 25px; white-space: nowrap; height: 20px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><path d="M20 10c0-.7-.1-1.3-.2-1.9l-2.3-.4c-.2-.7-.4-1.4-.8-2l1.4-1.9c-.5-.7-1.1-1.3-1.8-1.8l-1.9 1.4c-.6-.4-1.3-.6-2-.8l-.4-2.3c-.7-.1-1.3-.2-1.9-.2s-1.3.1-1.9.2l-.4 2.3c-.7.2-1.4.4-2 .8L4.1 2c-.7.5-1.3 1.1-1.8 1.8l1.4 1.9c-.4.6-.6 1.3-.8 2l-2.3.4c-.1.6-.2 1.2-.2 1.9s.1 1.3.2 1.9l2.3.4c.2.7.4 1.4.8 2l-1.4 1.9c.5.7 1.1 1.3 1.8 1.8l1.9-1.4c.6.4 1.3.6 2 .8l.4 2.3c.6.1 1.2.2 1.9.2s1.3-.1 1.9-.2l.4-2.3c.7-.2 1.4-.4 2-.8l1.9 1.4c.7-.5 1.3-1.1 1.8-1.8l-1.4-1.9c.4-.6.6-1.3.8-2l2.3-.4c.1-.6.2-1.2.2-1.9z" fill="%23202122"/><text x="10" y="13" font-family="sans-serif" font-weight="bold" font-size="8px" fill="white" text-anchor="middle">JS</text></svg>'); background-repeat: no-repeat; background-size: 20px 20px; background-position: center left; } `; $('<style>').text(style).appendTo('head'); } }); // --- 4. スクリプトのロード判定ロジック --- scriptList.forEach(function(script) { var s = userSettings[script.id]; if (!s || !s.enabled) return; var shouldLoad = false; if (s.isBlacklistMode) { var blocked = false; if (isDiff && !s.onDiff) blocked = true; else if (isPreview && !s.onPreview) blocked = true; else if (isEditMode && !s.onEdit) blocked = true; else if (action === 'view' && !isDiff) { if (isMainNS && !s.onMain) blocked = true; else if (isUserNS && !s.onUser) blocked = true; else if (isTalkNS && !s.onTalk) blocked = true; else if (isSpecialNS && !s.onSpecial) blocked = true; } shouldLoad = !blocked; } else { if (isDiff && s.onDiff) shouldLoad = true; else if (isPreview && s.onPreview) shouldLoad = true; else if (isEditMode && s.onEdit) shouldLoad = true; else if (action === 'view' && !isDiff) { if (isMainNS && s.onMain) shouldLoad = true; else if (isUserNS && s.onUser) shouldLoad = true; else if (isTalkNS && s.onTalk) shouldLoad = true; else if (isSpecialNS && s.onSpecial) shouldLoad = true; } } if (shouldLoad) mw.loader.load(script.url); }); // --- 5. 管理画面(Special:SM)の構築 --- if (/^(special|特別):(scriptmanager|sm)$/i.test(pageName)) { document.title = 'Script Manager'; $('#firstHeading').text('Script Manager'); var $body = $('#mw-content-text').empty(); $('<style>').text(` #sm-container { font-family: sans-serif; color: #202122; max-width: 1000px; margin: 20px 0; } .sm-card { background: #fff; border: 1px solid #c8ccd1; border-left: 5px solid #36c; border-radius: 8px; padding: 14px; margin-bottom: 16px; display: flex; align-items: center; transition: all 0.3s ease; } .sm-info { flex-grow: 1; min-width: 160px; overflow: hidden; margin-right: 10px; } .sm-name { font-weight: bold; font-size: 1.1em; display: flex; align-items: center; color: #202122; } .sm-id-row { font-size: 0.8em; color: #72777d; font-family: monospace; margin-top: 4px; display: flex; align-items: center; gap: 8px; } .sm-js-link { color: #36c; text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 250px; border-bottom: 1px solid transparent; } .sm-js-link:hover { border-bottom-color: #36c; } .sm-status-badge { font-size: 10px; padding: 2px 6px; border-radius: 10px; margin-left: 10px; text-transform: uppercase; border: 1px solid #c8ccd1; background: #f8f9fa; color: #72777d; } .status-on { background: #eaf3ff; color: #36c; border-color: #36c; } .sm-mode-switch { padding: 0 10px; border-right: 1px solid #eaecf0; margin-right: 10px; text-align: center; } .sm-mode-toggle { border: 1px solid #a2a9b1; border-radius: 4px; padding: 4px 8px; cursor: pointer; font-size: 10.5px; background: #fff; color: #202122; white-space: nowrap; } .sm-main-toggle { border-right: 2px solid #eaecf0; padding-right: 10px; margin-right: 10px; flex-shrink: 0; } .sm-sub-options { display: flex; gap: 8px; flex-wrap: wrap; flex-shrink: 0; } .sm-checkbox-label { display: flex; flex-direction: column; align-items: center; font-size: 0.75em; color: #54595d; cursor: pointer; min-width: 46px; text-align: center; } .sm-checkbox-label input { margin-bottom: 4px; cursor: pointer; } .mode-bl-active .sm-sub-checkbox:not(:checked) { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #d33; background: #d33; position: relative; border-radius: 2px; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after, .mode-bl-active .sm-sub-checkbox:not(:checked)::before { content: ''; position: absolute; width: 10px; height: 1.8px; background-color: white; top: 50%; left: 50%; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after { transform: translate(-50%, -50%) rotate(45deg); } .mode-bl-active .sm-sub-checkbox:not(:checked)::before { transform: translate(-50%, -50%) rotate(-45deg); } .mode-bl-active .sm-sub-checkbox:checked { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #a2a9b1; border-radius: 2px; background: #fff; } .mode-bl-active { border-left-color: #d33 !important; } .mode-bl-active .status-on { background: #fee7e6; color: #d33; border-color: #d33; } .sm-card.disabled { background: #f8f9fa !important; opacity: 0.6; filter: grayscale(1); } .sm-footer-actions { position: sticky; bottom: 20px; float: right; display: flex; gap: 10px; z-index: 100; } .sm-btn { border: none; padding: 12px 24px; border-radius: 4px; font-weight: bold; cursor: pointer; transition: background 0.2s; } #sm-save-btn { background: #36c; color: #fff; } #sm-common-js-btn { background: #f8f9fa; color: #202122; border: 1px solid #a2a9b1; text-decoration: none; font-size: 0.95em; display: flex; align-items: center; } /* 管理スクリプトがない時の案内用スタイル */ .sm-guide-box { background: #f8f9fa; border: 1px dashed #a2a9b1; padding: 20px; border-radius: 8px; text-align: center; margin: 20px 0; } .sm-guide-box h3 { margin-top: 0; } .sm-step { display: inline-block; text-align: left; margin: 10px 0; vertical-align: top; width: 250px; padding: 10px; } `).appendTo('head'); var $container = $('<div id="sm-container"></div>'); if (scriptList.length === 0) { var manualUrl = 'https://ja.wikipedia.org/wiki/' + encodeURIComponent('利用者:OUT_is_this/ScriptManager'); $container.append(` <div class="sm-guide-box"> <h3>スクリプトが登録されていません</h3> <p>以下の手順でスクリプトを追加してください:</p> <div class="sm-step"><b>1. 探す</b><br>他の人の <code>.js</code> ページを開きます。</div> <div class="sm-step"><b>2. 追加する</b><br>ページ上部の「ScriptManagerに追加」ボタンを押します。</div> <div class="sm-step"><b>3. 保存</b><br>名前を付けて保存すると自動で common.js に書き込まれます。</div> <div style="margin-top:20px; padding-top:15px; border-top:1px solid #eaecf0; text-align:center;"> <div style="display:inline-flex; align-items:flex-start; color:#202122; text-align:left;"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 20 20" style="flex-shrink:0; margin-right:8px; margin-top:3px;"> <path d="M10 0C4.48 0 0 4.48 0 10s4.48 10 10 10 10-4.48 10-10S15.52 0 10 0zm0 15c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1s1 .45 1 1v4c0 .55-.45 1-1 1zm1-8H9V5h2v2z" fill="#36c"/> </svg> <span style="line-height:1.6;"> common.js に手入力で書き込む方法や、詳しい使い方は<br> <a href="${manualUrl}" target="_blank" style="font-weight:bold; text-decoration:none; color:#36c;">こちら(解説ページ)</a>をご覧ください。 </span> </div> </div> </div> `); } scriptList.forEach(function(script) { var s = userSettings[script.id] || { enabled: false, isBlacklistMode: false, onMain: true, onUser: true, onTalk: true, onSpecial: true, onEdit: true, onPreview: true, onDiff: true }; var $card = $('<div class="sm-card">').toggleClass('disabled', !s.enabled); if (s.isBlacklistMode) $card.addClass('mode-bl-active'); var $status = $('<span class="sm-status-badge"></span>').addClass(s.enabled ? 'status-on' : '').text(s.enabled ? 'ON' : 'OFF'); var viewUrl = script.url.replace(/[?&]action=raw/, '').replace(/[?&]ctype=[^&]+/, ''); var $info = $('<div class="sm-info">').append( $('<div class="sm-name">').text(script.name).append($status), $('<div class="sm-id-row">').append( $('<span>').text(script.id), $('<a>').attr({href: viewUrl, target: '_blank', title: script.pageTitle}) .addClass('sm-js-link').text('⇨ ' + script.pageTitle) ) ); var $modeBtn = $('<div class="sm-mode-toggle">').text(s.isBlacklistMode ? '制限ベース' : '許可ベース'); $modeBtn.on('click', function() { var isBl = $(this).text() === '許可ベース'; $(this).text(isBl ? '制限ベース' : '許可ベース'); $card.toggleClass('mode-bl-active', isBl); }); var $mainToggle = $('<div class="sm-main-toggle">').append( $('<label class="sm-checkbox-label">').append($('<input type="checkbox" class="sm-master">').prop('checked', s.enabled).attr('data-id', script.id), '<b>有効</b>') ); function createOption(label, key, val) { var $input = $('<input type="checkbox" class="sm-sub-checkbox">').addClass('sm-' + key).prop('checked', val); return $('<label class="sm-checkbox-label">').append($input, label); } var $subOptions = $('<div class="sm-sub-options">').append( createOption('記事/WP', 'main', s.onMain), createOption('利用者', 'user', s.onUser), createOption('ノート', 'talk', s.onTalk), createOption('特別', 'special', s.onSpecial), createOption('編集', 'edit', s.onEdit), createOption('プレビュー', 'preview', s.onPreview), createOption('差分', 'diff', s.onDiff) ); $mainToggle.find('.sm-master').on('change', function() { var checked = $(this).is(':checked'); $card.toggleClass('disabled', !checked); $card.find('.sm-status-badge').toggleClass('status-on', checked).text(checked ? 'ON' : 'OFF'); }); $container.append($card.append($info, $('<div class="sm-mode-switch">').append($modeBtn), $mainToggle, $subOptions)); }); $body.append($container, $('<div class="sm-footer-actions">').append( $('<a>').attr({id: 'sm-common-js-btn', href: mw.util.getUrl('Special:MyPage/common.js'), target: '_blank'}).addClass('sm-btn').text('common.js を編集'), $('<button id="sm-save-btn">設定を保存して適用</button>').addClass('sm-btn').on('click', function() { var newSettings = {}; $('.sm-card').each(function() { var $c = $(this); var id = $c.find('.sm-master').attr('data-id'); newSettings[id] = { enabled: $c.find('.sm-master').is(':checked'), isBlacklistMode: $c.find('.sm-mode-toggle').text() === '制限ベース', onMain: $c.find('.sm-main').is(':checked'), onUser: $c.find('.sm-user').is(':checked'), onTalk: $c.find('.sm-talk').is(':checked'), onSpecial: $c.find('.sm-special').is(':checked'), onEdit: $c.find('.sm-edit').is(':checked'), onPreview: $c.find('.sm-preview').is(':checked'), onDiff: $c.find('.sm-diff').is(':checked') }; }); localStorage.setItem('wp-script-manager-v4', JSON.stringify(newSettings)); mw.notify('設定を保存しました。'); var returnUrl = document.referrer; setTimeout(function() { location.href = (returnUrl && returnUrl.indexOf(location.hostname) !== -1) ? returnUrl : mw.util.getUrl('Main_Page'); }, 800); }) )); } $(function() { // 1. 基本情報の取得 const pageName = mw.config.get('wgPageName').replace(/_/g, ' '); const action = mw.config.get('wgAction'); const userName = mw.config.get('wgUserName') const userNs = mw.config.get('wgFormattedNamespaces')[2]; const myCommonJs = userNs + ':' + userName + '/common.js'; const isJsPage = pageName.endsWith('.js'); const isManagerScript = pageName.endsWith('ScriptManager.js'); const isDiff = !!mw.config.get('wgDiffNewId'); // 2. 登録済み判定 function checkRegistration() { if (!window.scriptManagerList) return false; return window.scriptManagerList.some(script => { const savedTitle = (script.title || '').replace(/_/g, ' '); return savedTitle === pageName; }); } const isAlreadyRegistered = checkRegistration(); // --- 表示条件 --- // ・JSページである // ・現在のページが「自分のcommon.js」もしくは ScriptManager.jsでは表示しない。 // ・未登録である // ・閲覧モードかつ差分表示ではない // --- ボタンのデザイン変更(青い四角の箱) --- if (isJsPage && pageName !== myCommonJs && !isManagerScript && !isAlreadyRegistered && action === 'view' && !isDiff) { const $smInstallBtn = $('<button>') .text('ScriptManagerに追加') .addClass('mw-ui-button mw-ui-progressive') .css({ 'margin-left': '12px', 'vertical-align': 'middle', 'border-radius': '2px', 'padding': '0 12px', 'height': '32px', 'font-weight': 'bold', 'box-shadow': 'none' }) .on('click', function() { const scriptName = prompt('このスクリプトに名前をつけてください:', mw.config.get('wgTitle')); if (scriptName) { installScript(pageName, scriptName, $(this)); } }); $('#firstHeading').append($smInstallBtn); } // 3. common.js への追加処理 function installScript(targetPage, label, $button) { const api = new mw.Api(); // --- 1. ドメインと言語の判定ロジック(省略) --- const rawDomain = mw.config.get('wgServerName'); let lang = ''; let domain = rawDomain; const parts = rawDomain.split('.'); if (parts.length >= 3 && parts.slice(-2).join('.') === 'wikipedia.org') { lang = parts[0]; domain = 'wikipedia.org'; } if (domain === 'wikipedia.org') domain = ''; if (lang === 'ja') lang = ''; // --- 2. エントリとウィキリンクの作成(省略) --- let entryParts = [`name: '${label}'`]; if (lang !== '') entryParts.push(`lang: '${lang}'`); if (domain !== '') entryParts.push(`domain: '${domain}'`); entryParts.push(`title: '${targetPage}'`); let wikiLink = (domain !== '' && domain !== 'wikipedia.org') ? `[${location.protocol}//${rawDomain}/wiki/${encodeURI(targetPage)} ${targetPage}]` : `[[${(lang !== '' && lang !== 'ja') ? ':' + lang + ':' : ''}${targetPage}]]`; // --- 最終的な書き出し形式の組み立て --- // 1行目にコメント、2行目にオブジェクト(インデント付き) const newEntry = ` // ${wikiLink}\n { ${entryParts.join(', ')} },`; api.get({ action: 'query', prop: 'revisions', titles: myCommonJs, rvprop: 'content', rvslots: 'main' }).done(function(data) { const page = Object.values(data.query.pages)[0]; let content = (page && page.revisions) ? page.revisions[0].slots.main['*'] : ''; // --- 重複コードの検出と削除 (既存) --- const escapedPage = targetPage.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/[ _]/g, '[ _]'); const loadPattern = new RegExp(`(mw\\.loader\\.load|importScript)\\s*\\(\\s*['"\`].*?${escapedPage}.*?['"\`]\\s*\\);?`, 'g'); if (loadPattern.test(content)) { if (!confirm(`注意:common.js 内にこのスクリプトの既存の読み込みコードが見つかりました。\n\n「OK」:既存のコードを削除して移行します。\n「キャンセル」:中止します。`)) return; content = content.replace(loadPattern, '').replace(/\n{3,}/g, '\n\n'); } // --- コンテンツの更新 --- // 配列の開始位置のすぐ後ろに「コメント + オブジェクト」を挿入 if (content.includes('window.scriptManagerList = [')) { content = content.replace('window.scriptManagerList = [', `window.scriptManagerList = [\n${newEntry}`); } else { content = `window.scriptManagerList = [\n${newEntry}\n];\n\n` + content; } api.postWithToken('csrf', { action: 'edit', title: myCommonJs, text: content, summary: `${wikiLink} を ScriptManager に追加 (${label})` }).done(function(saveData) { if (saveData.edit && saveData.edit.result === 'Success') { mw.notify(label + ' を追加しました。'); $button.fadeOut(); if (!window.scriptManagerList) window.scriptManagerList = []; window.scriptManagerList.push({ name: label, lang: lang, domain: domain, title: targetPage }); } }); }); } }); })(jQuery, mediaWiki); 6piam01tszu461c91kyhkr0u5ettt9v 740982 740981 2026-05-08T12:26:07Z OUT is this 73801 740982 javascript text/javascript (function($, mw) { 'use strict'; // --- 1. スクリプト情報の整理 --- var rawList = window.scriptManagerList || []; var usedIds = {}; var scriptList = rawList.map(function(script) { var finalUrl = ''; // --- URL生成ロジック --- if (script.url) { finalUrl = script.url; } else { var langCode = (script.lang === undefined) ? 'ja' : script.lang; var langPrefix = (langCode !== '') ? langCode + '.' : ''; var domain = script.domain || 'wikipedia.org'; var title = script.title || ''; finalUrl = '//' + langPrefix + domain + '/w/index.php?title=' + encodeURIComponent(title) + '&action=raw&ctype=text/javascript'; } var match = finalUrl.match(/[?&]title=([^&]+)/); var pageTitle = match ? decodeURIComponent(match[1]) : 'Unknown'; var idBase = 'unknown'; if (match) { idBase = pageTitle .replace(/^(User|利用者):[^/]+\//i, '') .replace(/\.js$/i, '') .replace(/[ _ %]+/g, '_') .replace(/[^a-zA-Z0-9_]/g, ''); } var finalId = idBase; var counter = 2; while (usedIds[finalId]) { finalId = idBase + '_' + counter; counter++; } usedIds[finalId] = true; return { id: finalId, name: script.name, url: finalUrl, pageTitle: pageTitle }; }); // --- 2. 現在の状態の取得 --- var userSettings = JSON.parse(localStorage.getItem('wp-script-manager-v4') || '{}'); var pageName = mw.config.get('wgPageName').replace(/[ _ ]+/g, '').toLowerCase(); var action = mw.config.get('wgAction'); var ns = mw.config.get('wgNamespaceNumber'); var isDiff = !!mw.config.get('wgDiffNewId'); var isPreview = ['submit', 'preview'].indexOf(action) !== -1 && $('#wikiPreview').length > 0; var isMainNS = (ns === 0 || ns === 4); var isUserNS = (ns === 2 || ns === 3); var isTalkNS = (ns % 2 !== 0 && ns > 0); var isSpecialNS = (ns === -1); var isEditMode = (action === 'edit' || action === 'submit'); // --- 3. メニューへのリンク追加 --- $(function() { var smPageUrl = mw.util.getUrl('Special:SM'); var smLinks = $( ['', '-sticky-header'] .map(function(suffix) { var parentId = $('#p-user-menu-pages' + suffix).length ? 'p-user-menu-pages' : 'p-personal'; return mw.util.addPortletLink( parentId + suffix, smPageUrl, 'スクリプト管理画面', 'pt-scriptmanager' + suffix, 'Script Managerを開く', null, '#pt-logout' + suffix ); }) .filter(function(elOrNull) { return elOrNull !== null; }) ); if (smLinks.length > 0) { const style = ` li[id^="pt-scriptmanager"] a { width: auto !important; padding-left: 25px; white-space: nowrap; height: 20px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><path d="M20 10c0-.7-.1-1.3-.2-1.9l-2.3-.4c-.2-.7-.4-1.4-.8-2l1.4-1.9c-.5-.7-1.1-1.3-1.8-1.8l-1.9 1.4c-.6-.4-1.3-.6-2-.8l-.4-2.3c-.7-.1-1.3-.2-1.9-.2s-1.3.1-1.9.2l-.4 2.3c-.7.2-1.4.4-2 .8L4.1 2c-.7.5-1.3 1.1-1.8 1.8l1.4 1.9c-.4.6-.6 1.3-.8 2l-2.3.4c-.1.6-.2 1.2-.2 1.9s.1 1.3.2 1.9l2.3.4c.2.7.4 1.4.8 2l-1.4 1.9c.5.7 1.1 1.3 1.8 1.8l1.9-1.4c.6.4 1.3.6 2 .8l.4 2.3c.6.1 1.2.2 1.9.2s1.3-.1 1.9-.2l.4-2.3c.7-.2 1.4-.4 2-.8l1.9 1.4c.7-.5 1.3-1.1 1.8-1.8l-1.4-1.9c.4-.6.6-1.3.8-2l2.3-.4c.1-.6.2-1.2.2-1.9z" fill="%23202122"/><text x="10" y="13" font-family="sans-serif" font-weight="bold" font-size="8px" fill="white" text-anchor="middle">JS</text></svg>'); background-repeat: no-repeat; background-size: 20px 20px; background-position: center left; } `; $('<style>').text(style).appendTo('head'); } }); // --- 4. スクリプトのロード判定ロジック --- scriptList.forEach(function(script) { var s = userSettings[script.id]; if (!s || !s.enabled) return; var shouldLoad = false; if (s.isBlacklistMode) { var blocked = false; if (isDiff && !s.onDiff) blocked = true; else if (isPreview && !s.onPreview) blocked = true; else if (isEditMode && !s.onEdit) blocked = true; else if (action === 'view' && !isDiff) { if (isMainNS && !s.onMain) blocked = true; else if (isUserNS && !s.onUser) blocked = true; else if (isTalkNS && !s.onTalk) blocked = true; else if (isSpecialNS && !s.onSpecial) blocked = true; } shouldLoad = !blocked; } else { if (isDiff && s.onDiff) shouldLoad = true; else if (isPreview && s.onPreview) shouldLoad = true; else if (isEditMode && s.onEdit) shouldLoad = true; else if (action === 'view' && !isDiff) { if (isMainNS && s.onMain) shouldLoad = true; else if (isUserNS && s.onUser) shouldLoad = true; else if (isTalkNS && s.onTalk) shouldLoad = true; else if (isSpecialNS && s.onSpecial) shouldLoad = true; } } if (shouldLoad) mw.loader.load(script.url); }); // --- 5. 管理画面(Special:SM)の構築 --- if (/^(special|特別):(scriptmanager|sm)$/i.test(pageName)) { document.title = 'Script Manager'; $('#firstHeading').text('Script Manager'); var $body = $('#mw-content-text').empty(); $('<style>').text(` #sm-container { font-family: sans-serif; color: #202122; max-width: 1000px; margin: 20px 0; } .sm-card { background: #fff; border: 1px solid #c8ccd1; border-left: 5px solid #36c; border-radius: 8px; padding: 14px; margin-bottom: 16px; display: flex; align-items: center; transition: all 0.3s ease; } .sm-info { flex-grow: 1; min-width: 160px; overflow: hidden; margin-right: 10px; } .sm-name { font-weight: bold; font-size: 1.1em; display: flex; align-items: center; color: #202122; } .sm-id-row { font-size: 0.8em; color: #72777d; font-family: monospace; margin-top: 4px; display: flex; align-items: center; gap: 8px; } .sm-js-link { color: #36c; text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 250px; border-bottom: 1px solid transparent; } .sm-js-link:hover { border-bottom-color: #36c; } .sm-status-badge { font-size: 10px; padding: 2px 6px; border-radius: 10px; margin-left: 10px; text-transform: uppercase; border: 1px solid #c8ccd1; background: #f8f9fa; color: #72777d; } .status-on { background: #eaf3ff; color: #36c; border-color: #36c; } .sm-mode-switch { padding: 0 10px; border-right: 1px solid #eaecf0; margin-right: 10px; text-align: center; } .sm-mode-toggle { border: 1px solid #a2a9b1; border-radius: 4px; padding: 4px 8px; cursor: pointer; font-size: 10.5px; background: #fff; color: #202122; white-space: nowrap; } .sm-main-toggle { border-right: 2px solid #eaecf0; padding-right: 10px; margin-right: 10px; flex-shrink: 0; } .sm-sub-options { display: flex; gap: 8px; flex-wrap: wrap; flex-shrink: 0; } .sm-checkbox-label { display: flex; flex-direction: column; align-items: center; font-size: 0.75em; color: #54595d; cursor: pointer; min-width: 46px; text-align: center; } .sm-checkbox-label input { margin-bottom: 4px; cursor: pointer; } .mode-bl-active .sm-sub-checkbox:not(:checked) { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #d33; background: #d33; position: relative; border-radius: 2px; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after, .mode-bl-active .sm-sub-checkbox:not(:checked)::before { content: ''; position: absolute; width: 10px; height: 1.8px; background-color: white; top: 50%; left: 50%; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after { transform: translate(-50%, -50%) rotate(45deg); } .mode-bl-active .sm-sub-checkbox:not(:checked)::before { transform: translate(-50%, -50%) rotate(-45deg); } .mode-bl-active .sm-sub-checkbox:checked { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #a2a9b1; border-radius: 2px; background: #fff; } .mode-bl-active { border-left-color: #d33 !important; } .mode-bl-active .status-on { background: #fee7e6; color: #d33; border-color: #d33; } .sm-card.disabled { background: #f8f9fa !important; opacity: 0.6; filter: grayscale(1); } .sm-footer-actions { position: sticky; bottom: 20px; float: right; display: flex; gap: 10px; z-index: 100; } .sm-btn { border: none; padding: 12px 24px; border-radius: 4px; font-weight: bold; cursor: pointer; transition: background 0.2s; } #sm-save-btn { background: #36c; color: #fff; } #sm-common-js-btn { background: #f8f9fa; color: #202122; border: 1px solid #a2a9b1; text-decoration: none; font-size: 0.95em; display: flex; align-items: center; } /* 管理スクリプトがない時の案内用スタイル */ .sm-guide-box { background: #f8f9fa; border: 1px dashed #a2a9b1; padding: 20px; border-radius: 8px; text-align: center; margin: 20px 0; } .sm-guide-box h3 { margin-top: 0; } .sm-step { display: inline-block; text-align: left; margin: 10px 0; vertical-align: top; width: 250px; padding: 10px; } `).appendTo('head'); var $container = $('<div id="sm-container"></div>'); if (scriptList.length === 0) { var manualUrl = 'https://ja.wikipedia.org/wiki/' + encodeURIComponent('利用者:OUT_is_this/ScriptManager'); $container.append(` <div class="sm-guide-box"> <h3>スクリプトが登録されていません</h3> <p>以下の手順でスクリプトを追加してください:</p> <div class="sm-step"><b>1. 探す</b><br>他の人の <code>.js</code> ページを開きます。</div> <div class="sm-step"><b>2. 追加する</b><br>ページ上部の「ScriptManagerに追加」ボタンを押します。</div> <div class="sm-step"><b>3. 保存</b><br>名前を付けて保存すると自動で common.js に書き込まれます。</div> <div style="margin-top:20px; padding-top:15px; border-top:1px solid #eaecf0; text-align:center;"> <div style="display:inline-flex; align-items:flex-start; color:#202122;"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 20 20" style="flex-shrink:0; margin-right:8px; margin-top:4px;"> <path d="M10 0C4.48 0 0 4.48 0 10s4.48 10 10 10 10-4.48 10-10S15.52 0 10 0zm0 15c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1s1 .45 1 1v4c0 .55-.45 1-1 1zm1-8H9V5h2v2z" fill="#36c"/> </svg> <span style="line-height:1.8; text-align:center; display:block;"> common.js に手入力で書き込む方法や、詳しい使い方は<br> <a href="${manualUrl}" target="_blank" style="font-weight:bold; text-decoration:none; color:#36c;">こちら(解説ページ)</a>をご覧ください。 </span> </div> </div> </div> `); } scriptList.forEach(function(script) { var s = userSettings[script.id] || { enabled: false, isBlacklistMode: false, onMain: true, onUser: true, onTalk: true, onSpecial: true, onEdit: true, onPreview: true, onDiff: true }; var $card = $('<div class="sm-card">').toggleClass('disabled', !s.enabled); if (s.isBlacklistMode) $card.addClass('mode-bl-active'); var $status = $('<span class="sm-status-badge"></span>').addClass(s.enabled ? 'status-on' : '').text(s.enabled ? 'ON' : 'OFF'); var viewUrl = script.url.replace(/[?&]action=raw/, '').replace(/[?&]ctype=[^&]+/, ''); var $info = $('<div class="sm-info">').append( $('<div class="sm-name">').text(script.name).append($status), $('<div class="sm-id-row">').append( $('<span>').text(script.id), $('<a>').attr({href: viewUrl, target: '_blank', title: script.pageTitle}) .addClass('sm-js-link').text('⇨ ' + script.pageTitle) ) ); var $modeBtn = $('<div class="sm-mode-toggle">').text(s.isBlacklistMode ? '制限ベース' : '許可ベース'); $modeBtn.on('click', function() { var isBl = $(this).text() === '許可ベース'; $(this).text(isBl ? '制限ベース' : '許可ベース'); $card.toggleClass('mode-bl-active', isBl); }); var $mainToggle = $('<div class="sm-main-toggle">').append( $('<label class="sm-checkbox-label">').append($('<input type="checkbox" class="sm-master">').prop('checked', s.enabled).attr('data-id', script.id), '<b>有効</b>') ); function createOption(label, key, val) { var $input = $('<input type="checkbox" class="sm-sub-checkbox">').addClass('sm-' + key).prop('checked', val); return $('<label class="sm-checkbox-label">').append($input, label); } var $subOptions = $('<div class="sm-sub-options">').append( createOption('記事/WP', 'main', s.onMain), createOption('利用者', 'user', s.onUser), createOption('ノート', 'talk', s.onTalk), createOption('特別', 'special', s.onSpecial), createOption('編集', 'edit', s.onEdit), createOption('プレビュー', 'preview', s.onPreview), createOption('差分', 'diff', s.onDiff) ); $mainToggle.find('.sm-master').on('change', function() { var checked = $(this).is(':checked'); $card.toggleClass('disabled', !checked); $card.find('.sm-status-badge').toggleClass('status-on', checked).text(checked ? 'ON' : 'OFF'); }); $container.append($card.append($info, $('<div class="sm-mode-switch">').append($modeBtn), $mainToggle, $subOptions)); }); $body.append($container, $('<div class="sm-footer-actions">').append( $('<a>').attr({id: 'sm-common-js-btn', href: mw.util.getUrl('Special:MyPage/common.js'), target: '_blank'}).addClass('sm-btn').text('common.js を編集'), $('<button id="sm-save-btn">設定を保存して適用</button>').addClass('sm-btn').on('click', function() { var newSettings = {}; $('.sm-card').each(function() { var $c = $(this); var id = $c.find('.sm-master').attr('data-id'); newSettings[id] = { enabled: $c.find('.sm-master').is(':checked'), isBlacklistMode: $c.find('.sm-mode-toggle').text() === '制限ベース', onMain: $c.find('.sm-main').is(':checked'), onUser: $c.find('.sm-user').is(':checked'), onTalk: $c.find('.sm-talk').is(':checked'), onSpecial: $c.find('.sm-special').is(':checked'), onEdit: $c.find('.sm-edit').is(':checked'), onPreview: $c.find('.sm-preview').is(':checked'), onDiff: $c.find('.sm-diff').is(':checked') }; }); localStorage.setItem('wp-script-manager-v4', JSON.stringify(newSettings)); mw.notify('設定を保存しました。'); var returnUrl = document.referrer; setTimeout(function() { location.href = (returnUrl && returnUrl.indexOf(location.hostname) !== -1) ? returnUrl : mw.util.getUrl('Main_Page'); }, 800); }) )); } $(function() { // 1. 基本情報の取得 const pageName = mw.config.get('wgPageName').replace(/_/g, ' '); const action = mw.config.get('wgAction'); const userName = mw.config.get('wgUserName') const userNs = mw.config.get('wgFormattedNamespaces')[2]; const myCommonJs = userNs + ':' + userName + '/common.js'; const isJsPage = pageName.endsWith('.js'); const isManagerScript = pageName.endsWith('ScriptManager.js'); const isDiff = !!mw.config.get('wgDiffNewId'); // 2. 登録済み判定 function checkRegistration() { if (!window.scriptManagerList) return false; return window.scriptManagerList.some(script => { const savedTitle = (script.title || '').replace(/_/g, ' '); return savedTitle === pageName; }); } const isAlreadyRegistered = checkRegistration(); // --- 表示条件 --- // ・JSページである // ・現在のページが「自分のcommon.js」もしくは ScriptManager.jsでは表示しない。 // ・未登録である // ・閲覧モードかつ差分表示ではない // --- ボタンのデザイン変更(青い四角の箱) --- if (isJsPage && pageName !== myCommonJs && !isManagerScript && !isAlreadyRegistered && action === 'view' && !isDiff) { const $smInstallBtn = $('<button>') .text('ScriptManagerに追加') .addClass('mw-ui-button mw-ui-progressive') .css({ 'margin-left': '12px', 'vertical-align': 'middle', 'border-radius': '2px', 'padding': '0 12px', 'height': '32px', 'font-weight': 'bold', 'box-shadow': 'none' }) .on('click', function() { const scriptName = prompt('このスクリプトに名前をつけてください:', mw.config.get('wgTitle')); if (scriptName) { installScript(pageName, scriptName, $(this)); } }); $('#firstHeading').append($smInstallBtn); } // 3. common.js への追加処理 function installScript(targetPage, label, $button) { const api = new mw.Api(); // --- 1. ドメインと言語の判定ロジック(省略) --- const rawDomain = mw.config.get('wgServerName'); let lang = ''; let domain = rawDomain; const parts = rawDomain.split('.'); if (parts.length >= 3 && parts.slice(-2).join('.') === 'wikipedia.org') { lang = parts[0]; domain = 'wikipedia.org'; } if (domain === 'wikipedia.org') domain = ''; if (lang === 'ja') lang = ''; // --- 2. エントリとウィキリンクの作成(省略) --- let entryParts = [`name: '${label}'`]; if (lang !== '') entryParts.push(`lang: '${lang}'`); if (domain !== '') entryParts.push(`domain: '${domain}'`); entryParts.push(`title: '${targetPage}'`); let wikiLink = (domain !== '' && domain !== 'wikipedia.org') ? `[${location.protocol}//${rawDomain}/wiki/${encodeURI(targetPage)} ${targetPage}]` : `[[${(lang !== '' && lang !== 'ja') ? ':' + lang + ':' : ''}${targetPage}]]`; // --- 最終的な書き出し形式の組み立て --- // 1行目にコメント、2行目にオブジェクト(インデント付き) const newEntry = ` // ${wikiLink}\n { ${entryParts.join(', ')} },`; api.get({ action: 'query', prop: 'revisions', titles: myCommonJs, rvprop: 'content', rvslots: 'main' }).done(function(data) { const page = Object.values(data.query.pages)[0]; let content = (page && page.revisions) ? page.revisions[0].slots.main['*'] : ''; // --- 重複コードの検出と削除 (既存) --- const escapedPage = targetPage.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/[ _]/g, '[ _]'); const loadPattern = new RegExp(`(mw\\.loader\\.load|importScript)\\s*\\(\\s*['"\`].*?${escapedPage}.*?['"\`]\\s*\\);?`, 'g'); if (loadPattern.test(content)) { if (!confirm(`注意:common.js 内にこのスクリプトの既存の読み込みコードが見つかりました。\n\n「OK」:既存のコードを削除して移行します。\n「キャンセル」:中止します。`)) return; content = content.replace(loadPattern, '').replace(/\n{3,}/g, '\n\n'); } // --- コンテンツの更新 --- // 配列の開始位置のすぐ後ろに「コメント + オブジェクト」を挿入 if (content.includes('window.scriptManagerList = [')) { content = content.replace('window.scriptManagerList = [', `window.scriptManagerList = [\n${newEntry}`); } else { content = `window.scriptManagerList = [\n${newEntry}\n];\n\n` + content; } api.postWithToken('csrf', { action: 'edit', title: myCommonJs, text: content, summary: `${wikiLink} を ScriptManager に追加 (${label})` }).done(function(saveData) { if (saveData.edit && saveData.edit.result === 'Success') { mw.notify(label + ' を追加しました。'); $button.fadeOut(); if (!window.scriptManagerList) window.scriptManagerList = []; window.scriptManagerList.push({ name: label, lang: lang, domain: domain, title: targetPage }); } }); }); } }); })(jQuery, mediaWiki); hnt86n1z1ek8lfegayqr4bpavr9pb75 740983 740982 2026-05-08T12:33:01Z OUT is this 73801 案内文修正 740983 javascript text/javascript (function($, mw) { 'use strict'; // --- 1. スクリプト情報の整理 --- var rawList = window.scriptManagerList || []; var usedIds = {}; var scriptList = rawList.map(function(script) { var finalUrl = ''; // --- URL生成ロジック --- if (script.url) { finalUrl = script.url; } else { var langCode = (script.lang === undefined) ? 'ja' : script.lang; var langPrefix = (langCode !== '') ? langCode + '.' : ''; var domain = script.domain || 'wikipedia.org'; var title = script.title || ''; finalUrl = '//' + langPrefix + domain + '/w/index.php?title=' + encodeURIComponent(title) + '&action=raw&ctype=text/javascript'; } var match = finalUrl.match(/[?&]title=([^&]+)/); var pageTitle = match ? decodeURIComponent(match[1]) : 'Unknown'; var idBase = 'unknown'; if (match) { idBase = pageTitle .replace(/^(User|利用者):[^/]+\//i, '') .replace(/\.js$/i, '') .replace(/[ _ %]+/g, '_') .replace(/[^a-zA-Z0-9_]/g, ''); } var finalId = idBase; var counter = 2; while (usedIds[finalId]) { finalId = idBase + '_' + counter; counter++; } usedIds[finalId] = true; return { id: finalId, name: script.name, url: finalUrl, pageTitle: pageTitle }; }); // --- 2. 現在の状態の取得 --- var userSettings = JSON.parse(localStorage.getItem('wp-script-manager-v4') || '{}'); var pageName = mw.config.get('wgPageName').replace(/[ _ ]+/g, '').toLowerCase(); var action = mw.config.get('wgAction'); var ns = mw.config.get('wgNamespaceNumber'); var isDiff = !!mw.config.get('wgDiffNewId'); var isPreview = ['submit', 'preview'].indexOf(action) !== -1 && $('#wikiPreview').length > 0; var isMainNS = (ns === 0 || ns === 4); var isUserNS = (ns === 2 || ns === 3); var isTalkNS = (ns % 2 !== 0 && ns > 0); var isSpecialNS = (ns === -1); var isEditMode = (action === 'edit' || action === 'submit'); // --- 3. メニューへのリンク追加 --- $(function() { var smPageUrl = mw.util.getUrl('Special:SM'); var smLinks = $( ['', '-sticky-header'] .map(function(suffix) { var parentId = $('#p-user-menu-pages' + suffix).length ? 'p-user-menu-pages' : 'p-personal'; return mw.util.addPortletLink( parentId + suffix, smPageUrl, 'スクリプト管理画面', 'pt-scriptmanager' + suffix, 'Script Managerを開く', null, '#pt-logout' + suffix ); }) .filter(function(elOrNull) { return elOrNull !== null; }) ); if (smLinks.length > 0) { const style = ` li[id^="pt-scriptmanager"] a { width: auto !important; padding-left: 25px; white-space: nowrap; height: 20px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><path d="M20 10c0-.7-.1-1.3-.2-1.9l-2.3-.4c-.2-.7-.4-1.4-.8-2l1.4-1.9c-.5-.7-1.1-1.3-1.8-1.8l-1.9 1.4c-.6-.4-1.3-.6-2-.8l-.4-2.3c-.7-.1-1.3-.2-1.9-.2s-1.3.1-1.9.2l-.4 2.3c-.7.2-1.4.4-2 .8L4.1 2c-.7.5-1.3 1.1-1.8 1.8l1.4 1.9c-.4.6-.6 1.3-.8 2l-2.3.4c-.1.6-.2 1.2-.2 1.9s.1 1.3.2 1.9l2.3.4c.2.7.4 1.4.8 2l-1.4 1.9c.5.7 1.1 1.3 1.8 1.8l1.9-1.4c.6.4 1.3.6 2 .8l.4 2.3c.6.1 1.2.2 1.9.2s1.3-.1 1.9-.2l.4-2.3c.7-.2 1.4-.4 2-.8l1.9 1.4c.7-.5 1.3-1.1 1.8-1.8l-1.4-1.9c.4-.6.6-1.3.8-2l2.3-.4c.1-.6.2-1.2.2-1.9z" fill="%23202122"/><text x="10" y="13" font-family="sans-serif" font-weight="bold" font-size="8px" fill="white" text-anchor="middle">JS</text></svg>'); background-repeat: no-repeat; background-size: 20px 20px; background-position: center left; } `; $('<style>').text(style).appendTo('head'); } }); // --- 4. スクリプトのロード判定ロジック --- scriptList.forEach(function(script) { var s = userSettings[script.id]; if (!s || !s.enabled) return; var shouldLoad = false; if (s.isBlacklistMode) { var blocked = false; if (isDiff && !s.onDiff) blocked = true; else if (isPreview && !s.onPreview) blocked = true; else if (isEditMode && !s.onEdit) blocked = true; else if (action === 'view' && !isDiff) { if (isMainNS && !s.onMain) blocked = true; else if (isUserNS && !s.onUser) blocked = true; else if (isTalkNS && !s.onTalk) blocked = true; else if (isSpecialNS && !s.onSpecial) blocked = true; } shouldLoad = !blocked; } else { if (isDiff && s.onDiff) shouldLoad = true; else if (isPreview && s.onPreview) shouldLoad = true; else if (isEditMode && s.onEdit) shouldLoad = true; else if (action === 'view' && !isDiff) { if (isMainNS && s.onMain) shouldLoad = true; else if (isUserNS && s.onUser) shouldLoad = true; else if (isTalkNS && s.onTalk) shouldLoad = true; else if (isSpecialNS && s.onSpecial) shouldLoad = true; } } if (shouldLoad) mw.loader.load(script.url); }); // --- 5. 管理画面(Special:SM)の構築 --- if (/^(special|特別):(scriptmanager|sm)$/i.test(pageName)) { document.title = 'Script Manager'; $('#firstHeading').text('Script Manager'); var $body = $('#mw-content-text').empty(); $('<style>').text(` #sm-container { font-family: sans-serif; color: #202122; max-width: 1000px; margin: 20px 0; } .sm-card { background: #fff; border: 1px solid #c8ccd1; border-left: 5px solid #36c; border-radius: 8px; padding: 14px; margin-bottom: 16px; display: flex; align-items: center; transition: all 0.3s ease; } .sm-info { flex-grow: 1; min-width: 160px; overflow: hidden; margin-right: 10px; } .sm-name { font-weight: bold; font-size: 1.1em; display: flex; align-items: center; color: #202122; } .sm-id-row { font-size: 0.8em; color: #72777d; font-family: monospace; margin-top: 4px; display: flex; align-items: center; gap: 8px; } .sm-js-link { color: #36c; text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 250px; border-bottom: 1px solid transparent; } .sm-js-link:hover { border-bottom-color: #36c; } .sm-status-badge { font-size: 10px; padding: 2px 6px; border-radius: 10px; margin-left: 10px; text-transform: uppercase; border: 1px solid #c8ccd1; background: #f8f9fa; color: #72777d; } .status-on { background: #eaf3ff; color: #36c; border-color: #36c; } .sm-mode-switch { padding: 0 10px; border-right: 1px solid #eaecf0; margin-right: 10px; text-align: center; } .sm-mode-toggle { border: 1px solid #a2a9b1; border-radius: 4px; padding: 4px 8px; cursor: pointer; font-size: 10.5px; background: #fff; color: #202122; white-space: nowrap; } .sm-main-toggle { border-right: 2px solid #eaecf0; padding-right: 10px; margin-right: 10px; flex-shrink: 0; } .sm-sub-options { display: flex; gap: 8px; flex-wrap: wrap; flex-shrink: 0; } .sm-checkbox-label { display: flex; flex-direction: column; align-items: center; font-size: 0.75em; color: #54595d; cursor: pointer; min-width: 46px; text-align: center; } .sm-checkbox-label input { margin-bottom: 4px; cursor: pointer; } .mode-bl-active .sm-sub-checkbox:not(:checked) { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #d33; background: #d33; position: relative; border-radius: 2px; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after, .mode-bl-active .sm-sub-checkbox:not(:checked)::before { content: ''; position: absolute; width: 10px; height: 1.8px; background-color: white; top: 50%; left: 50%; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after { transform: translate(-50%, -50%) rotate(45deg); } .mode-bl-active .sm-sub-checkbox:not(:checked)::before { transform: translate(-50%, -50%) rotate(-45deg); } .mode-bl-active .sm-sub-checkbox:checked { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #a2a9b1; border-radius: 2px; background: #fff; } .mode-bl-active { border-left-color: #d33 !important; } .mode-bl-active .status-on { background: #fee7e6; color: #d33; border-color: #d33; } .sm-card.disabled { background: #f8f9fa !important; opacity: 0.6; filter: grayscale(1); } .sm-footer-actions { position: sticky; bottom: 20px; float: right; display: flex; gap: 10px; z-index: 100; } .sm-btn { border: none; padding: 12px 24px; border-radius: 4px; font-weight: bold; cursor: pointer; transition: background 0.2s; } #sm-save-btn { background: #36c; color: #fff; } #sm-common-js-btn { background: #f8f9fa; color: #202122; border: 1px solid #a2a9b1; text-decoration: none; font-size: 0.95em; display: flex; align-items: center; } /* 管理スクリプトがない時の案内用スタイル */ .sm-guide-box { background: #f8f9fa; border: 1px dashed #a2a9b1; padding: 20px; border-radius: 8px; text-align: center; margin: 20px 0; } .sm-guide-box h3 { margin-top: 0; } .sm-step { display: inline-block; text-align: left; margin: 10px 0; vertical-align: top; width: 250px; padding: 10px; } `).appendTo('head'); var $container = $('<div id="sm-container"></div>'); if (scriptList.length === 0) { var manualUrl = 'https://ja.wikipedia.org/wiki/' + encodeURIComponent('利用者:OUT_is_this/ScriptManager'); $container.append(` <div class="sm-guide-box"> <h3>スクリプトが登録されていません</h3> <p>以下の手順でスクリプトを追加してください:</p> <div class="sm-step"><b>1. 探す</b><br>ScriptManagerに登録したいスクリプトが置いてある <code>.js</code> ページを開きます。</div> <div class="sm-step"><b>2. 追加する</b><br>ページ上部の「ScriptManagerに追加」ボタンを押します。</div> <div class="sm-step"><b>3. 保存</b><br>名前を付けて保存すると自動で common.js に書き込まれます。</div> <div style="margin-top:20px; padding-top:15px; border-top:1px solid #eaecf0; text-align:center;"> <div style="display:inline-flex; align-items:flex-start; color:#202122;"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 20 20" style="flex-shrink:0; margin-right:8px; margin-top:4px;"> <path d="M10 0C4.48 0 0 4.48 0 10s4.48 10 10 10 10-4.48 10-10S15.52 0 10 0zm0 15c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1s1 .45 1 1v4c0 .55-.45 1-1 1zm1-8H9V5h2v2z" fill="#36c"/> </svg> <span style="line-height:1.8; text-align:center; display:block;"> common.js に手入力で直接書き込む方法や、他ドメインにある js の登録方法、その他詳しい使い方などは<br> <a href="${manualUrl}" target="_blank" style="font-weight:bold; text-decoration:none; color:#36c;">こちら(解説ページ)</a>をご覧ください。 </span> </div> </div> </div> `); } scriptList.forEach(function(script) { var s = userSettings[script.id] || { enabled: false, isBlacklistMode: false, onMain: true, onUser: true, onTalk: true, onSpecial: true, onEdit: true, onPreview: true, onDiff: true }; var $card = $('<div class="sm-card">').toggleClass('disabled', !s.enabled); if (s.isBlacklistMode) $card.addClass('mode-bl-active'); var $status = $('<span class="sm-status-badge"></span>').addClass(s.enabled ? 'status-on' : '').text(s.enabled ? 'ON' : 'OFF'); var viewUrl = script.url.replace(/[?&]action=raw/, '').replace(/[?&]ctype=[^&]+/, ''); var $info = $('<div class="sm-info">').append( $('<div class="sm-name">').text(script.name).append($status), $('<div class="sm-id-row">').append( $('<span>').text(script.id), $('<a>').attr({href: viewUrl, target: '_blank', title: script.pageTitle}) .addClass('sm-js-link').text('⇨ ' + script.pageTitle) ) ); var $modeBtn = $('<div class="sm-mode-toggle">').text(s.isBlacklistMode ? '制限ベース' : '許可ベース'); $modeBtn.on('click', function() { var isBl = $(this).text() === '許可ベース'; $(this).text(isBl ? '制限ベース' : '許可ベース'); $card.toggleClass('mode-bl-active', isBl); }); var $mainToggle = $('<div class="sm-main-toggle">').append( $('<label class="sm-checkbox-label">').append($('<input type="checkbox" class="sm-master">').prop('checked', s.enabled).attr('data-id', script.id), '<b>有効</b>') ); function createOption(label, key, val) { var $input = $('<input type="checkbox" class="sm-sub-checkbox">').addClass('sm-' + key).prop('checked', val); return $('<label class="sm-checkbox-label">').append($input, label); } var $subOptions = $('<div class="sm-sub-options">').append( createOption('記事/WP', 'main', s.onMain), createOption('利用者', 'user', s.onUser), createOption('ノート', 'talk', s.onTalk), createOption('特別', 'special', s.onSpecial), createOption('編集', 'edit', s.onEdit), createOption('プレビュー', 'preview', s.onPreview), createOption('差分', 'diff', s.onDiff) ); $mainToggle.find('.sm-master').on('change', function() { var checked = $(this).is(':checked'); $card.toggleClass('disabled', !checked); $card.find('.sm-status-badge').toggleClass('status-on', checked).text(checked ? 'ON' : 'OFF'); }); $container.append($card.append($info, $('<div class="sm-mode-switch">').append($modeBtn), $mainToggle, $subOptions)); }); $body.append($container, $('<div class="sm-footer-actions">').append( $('<a>').attr({id: 'sm-common-js-btn', href: mw.util.getUrl('Special:MyPage/common.js'), target: '_blank'}).addClass('sm-btn').text('common.js を編集'), $('<button id="sm-save-btn">設定を保存して適用</button>').addClass('sm-btn').on('click', function() { var newSettings = {}; $('.sm-card').each(function() { var $c = $(this); var id = $c.find('.sm-master').attr('data-id'); newSettings[id] = { enabled: $c.find('.sm-master').is(':checked'), isBlacklistMode: $c.find('.sm-mode-toggle').text() === '制限ベース', onMain: $c.find('.sm-main').is(':checked'), onUser: $c.find('.sm-user').is(':checked'), onTalk: $c.find('.sm-talk').is(':checked'), onSpecial: $c.find('.sm-special').is(':checked'), onEdit: $c.find('.sm-edit').is(':checked'), onPreview: $c.find('.sm-preview').is(':checked'), onDiff: $c.find('.sm-diff').is(':checked') }; }); localStorage.setItem('wp-script-manager-v4', JSON.stringify(newSettings)); mw.notify('設定を保存しました。'); var returnUrl = document.referrer; setTimeout(function() { location.href = (returnUrl && returnUrl.indexOf(location.hostname) !== -1) ? returnUrl : mw.util.getUrl('Main_Page'); }, 800); }) )); } $(function() { // 1. 基本情報の取得 const pageName = mw.config.get('wgPageName').replace(/_/g, ' '); const action = mw.config.get('wgAction'); const userName = mw.config.get('wgUserName') const userNs = mw.config.get('wgFormattedNamespaces')[2]; const myCommonJs = userNs + ':' + userName + '/common.js'; const isJsPage = pageName.endsWith('.js'); const isManagerScript = pageName.endsWith('ScriptManager.js'); const isDiff = !!mw.config.get('wgDiffNewId'); // 2. 登録済み判定 function checkRegistration() { if (!window.scriptManagerList) return false; return window.scriptManagerList.some(script => { const savedTitle = (script.title || '').replace(/_/g, ' '); return savedTitle === pageName; }); } const isAlreadyRegistered = checkRegistration(); // --- 表示条件 --- // ・JSページである // ・現在のページが「自分のcommon.js」もしくは ScriptManager.jsでは表示しない。 // ・未登録である // ・閲覧モードかつ差分表示ではない // --- ボタンのデザイン変更(青い四角の箱) --- if (isJsPage && pageName !== myCommonJs && !isManagerScript && !isAlreadyRegistered && action === 'view' && !isDiff) { const $smInstallBtn = $('<button>') .text('ScriptManagerに追加') .addClass('mw-ui-button mw-ui-progressive') .css({ 'margin-left': '12px', 'vertical-align': 'middle', 'border-radius': '2px', 'padding': '0 12px', 'height': '32px', 'font-weight': 'bold', 'box-shadow': 'none' }) .on('click', function() { const scriptName = prompt('このスクリプトに名前をつけてください:', mw.config.get('wgTitle')); if (scriptName) { installScript(pageName, scriptName, $(this)); } }); $('#firstHeading').append($smInstallBtn); } // 3. common.js への追加処理 function installScript(targetPage, label, $button) { const api = new mw.Api(); // --- 1. ドメインと言語の判定ロジック(省略) --- const rawDomain = mw.config.get('wgServerName'); let lang = ''; let domain = rawDomain; const parts = rawDomain.split('.'); if (parts.length >= 3 && parts.slice(-2).join('.') === 'wikipedia.org') { lang = parts[0]; domain = 'wikipedia.org'; } if (domain === 'wikipedia.org') domain = ''; if (lang === 'ja') lang = ''; // --- 2. エントリとウィキリンクの作成(省略) --- let entryParts = [`name: '${label}'`]; if (lang !== '') entryParts.push(`lang: '${lang}'`); if (domain !== '') entryParts.push(`domain: '${domain}'`); entryParts.push(`title: '${targetPage}'`); let wikiLink = (domain !== '' && domain !== 'wikipedia.org') ? `[${location.protocol}//${rawDomain}/wiki/${encodeURI(targetPage)} ${targetPage}]` : `[[${(lang !== '' && lang !== 'ja') ? ':' + lang + ':' : ''}${targetPage}]]`; // --- 最終的な書き出し形式の組み立て --- // 1行目にコメント、2行目にオブジェクト(インデント付き) const newEntry = ` // ${wikiLink}\n { ${entryParts.join(', ')} },`; api.get({ action: 'query', prop: 'revisions', titles: myCommonJs, rvprop: 'content', rvslots: 'main' }).done(function(data) { const page = Object.values(data.query.pages)[0]; let content = (page && page.revisions) ? page.revisions[0].slots.main['*'] : ''; // --- 重複コードの検出と削除 (既存) --- const escapedPage = targetPage.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/[ _]/g, '[ _]'); const loadPattern = new RegExp(`(mw\\.loader\\.load|importScript)\\s*\\(\\s*['"\`].*?${escapedPage}.*?['"\`]\\s*\\);?`, 'g'); if (loadPattern.test(content)) { if (!confirm(`注意:common.js 内にこのスクリプトの既存の読み込みコードが見つかりました。\n\n「OK」:既存のコードを削除して移行します。\n「キャンセル」:中止します。`)) return; content = content.replace(loadPattern, '').replace(/\n{3,}/g, '\n\n'); } // --- コンテンツの更新 --- // 配列の開始位置のすぐ後ろに「コメント + オブジェクト」を挿入 if (content.includes('window.scriptManagerList = [')) { content = content.replace('window.scriptManagerList = [', `window.scriptManagerList = [\n${newEntry}`); } else { content = `window.scriptManagerList = [\n${newEntry}\n];\n\n` + content; } api.postWithToken('csrf', { action: 'edit', title: myCommonJs, text: content, summary: `${wikiLink} を ScriptManager に追加 (${label})` }).done(function(saveData) { if (saveData.edit && saveData.edit.result === 'Success') { mw.notify(label + ' を追加しました。'); $button.fadeOut(); if (!window.scriptManagerList) window.scriptManagerList = []; window.scriptManagerList.push({ name: label, lang: lang, domain: domain, title: targetPage }); } }); }); } }); })(jQuery, mediaWiki); nxtghmrssih0ib5j5bu0zoozv67kjn8 740986 740983 2026-05-08T12:58:37Z OUT is this 73801 740986 javascript text/javascript (function($, mw) { 'use strict'; // --- 1. スクリプト情報の整理 --- var rawList = window.scriptManagerList || []; var usedIds = {}; var scriptList = rawList.map(function(script) { var finalUrl = ''; // --- URL生成ロジック --- if (script.url) { finalUrl = script.url; } else { var langCode = (script.lang === undefined) ? 'ja' : script.lang; var langPrefix = (langCode !== '') ? langCode + '.' : ''; var domain = script.domain || 'wikipedia.org'; var title = script.title || ''; finalUrl = '//' + langPrefix + domain + '/w/index.php?title=' + encodeURIComponent(title) + '&action=raw&ctype=text/javascript'; } var match = finalUrl.match(/[?&]title=([^&]+)/); var pageTitle = match ? decodeURIComponent(match[1]) : 'Unknown'; var idBase = 'unknown'; if (match) { idBase = pageTitle .replace(/^(User|利用者):[^/]+\//i, '') .replace(/\.js$/i, '') .replace(/[ _ %]+/g, '_') .replace(/[^a-zA-Z0-9_]/g, ''); } var finalId = idBase; var counter = 2; while (usedIds[finalId]) { finalId = idBase + '_' + counter; counter++; } usedIds[finalId] = true; return { id: finalId, name: script.name, url: finalUrl, pageTitle: pageTitle }; }); // --- 2. 現在の状態の取得 --- var userSettings = JSON.parse(localStorage.getItem('wp-script-manager-v4') || '{}'); var pageName = mw.config.get('wgPageName').replace(/[ _ ]+/g, '').toLowerCase(); var action = mw.config.get('wgAction'); var ns = mw.config.get('wgNamespaceNumber'); var isDiff = !!mw.config.get('wgDiffNewId'); var isPreview = ['submit', 'preview'].indexOf(action) !== -1 && $('#wikiPreview').length > 0; var isMainNS = (ns === 0 || ns === 4); var isUserNS = (ns === 2 || ns === 3); var isTalkNS = (ns % 2 !== 0 && ns > 0); var isSpecialNS = (ns === -1); var isEditMode = (action === 'edit' || action === 'submit'); // --- 3. メニューへのリンク追加 --- $(function() { var smPageUrl = mw.util.getUrl('Special:SM'); var smLinks = $( ['', '-sticky-header'] .map(function(suffix) { var parentId = $('#p-user-menu-pages' + suffix).length ? 'p-user-menu-pages' : 'p-personal'; return mw.util.addPortletLink( parentId + suffix, smPageUrl, 'スクリプト管理画面', 'pt-scriptmanager' + suffix, 'Script Managerを開く', null, '#pt-logout' + suffix ); }) .filter(function(elOrNull) { return elOrNull !== null; }) ); if (smLinks.length > 0) { const style = ` li[id^="pt-scriptmanager"] a { width: auto !important; padding-left: 25px; white-space: nowrap; height: 20px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><path d="M20 10c0-.7-.1-1.3-.2-1.9l-2.3-.4c-.2-.7-.4-1.4-.8-2l1.4-1.9c-.5-.7-1.1-1.3-1.8-1.8l-1.9 1.4c-.6-.4-1.3-.6-2-.8l-.4-2.3c-.7-.1-1.3-.2-1.9-.2s-1.3.1-1.9.2l-.4 2.3c-.7.2-1.4.4-2 .8L4.1 2c-.7.5-1.3 1.1-1.8 1.8l1.4 1.9c-.4.6-.6 1.3-.8 2l-2.3.4c-.1.6-.2 1.2-.2 1.9s.1 1.3.2 1.9l2.3.4c.2.7.4 1.4.8 2l-1.4 1.9c.5.7 1.1 1.3 1.8 1.8l1.9-1.4c.6.4 1.3.6 2 .8l.4 2.3c.6.1 1.2.2 1.9.2s1.3-.1 1.9-.2l.4-2.3c.7-.2 1.4-.4 2-.8l1.9 1.4c.7-.5 1.3-1.1 1.8-1.8l-1.4-1.9c.4-.6.6-1.3.8-2l2.3-.4c.1-.6.2-1.2.2-1.9z" fill="%23202122"/><text x="10" y="13" font-family="sans-serif" font-weight="bold" font-size="8px" fill="white" text-anchor="middle">JS</text></svg>'); background-repeat: no-repeat; background-size: 20px 20px; background-position: center left; } `; $('<style>').text(style).appendTo('head'); } }); // --- 4. スクリプトのロード判定ロジック --- scriptList.forEach(function(script) { var s = userSettings[script.id]; if (!s || !s.enabled) return; var shouldLoad = false; if (s.isBlacklistMode) { var blocked = false; if (isDiff && !s.onDiff) blocked = true; else if (isPreview && !s.onPreview) blocked = true; else if (isEditMode && !s.onEdit) blocked = true; else if (action === 'view' && !isDiff) { if (isMainNS && !s.onMain) blocked = true; else if (isUserNS && !s.onUser) blocked = true; else if (isTalkNS && !s.onTalk) blocked = true; else if (isSpecialNS && !s.onSpecial) blocked = true; } shouldLoad = !blocked; } else { if (isDiff && s.onDiff) shouldLoad = true; else if (isPreview && s.onPreview) shouldLoad = true; else if (isEditMode && s.onEdit) shouldLoad = true; else if (action === 'view' && !isDiff) { if (isMainNS && s.onMain) shouldLoad = true; else if (isUserNS && s.onUser) shouldLoad = true; else if (isTalkNS && s.onTalk) shouldLoad = true; else if (isSpecialNS && s.onSpecial) shouldLoad = true; } } if (shouldLoad) mw.loader.load(script.url); }); // --- 5. 管理画面(Special:SM)の構築 --- if (/^(special|特別):(scriptmanager|sm)$/i.test(pageName)) { document.title = 'Script Manager'; $('#firstHeading').text('Script Manager'); var $body = $('#mw-content-text').empty(); $('<style>').text(` #sm-container { font-family: sans-serif; color: #202122; max-width: 1000px; margin: 20px 0; } .sm-card { background: #fff; border: 1px solid #c8ccd1; border-left: 5px solid #36c; border-radius: 8px; padding: 14px; margin-bottom: 16px; display: flex; align-items: center; transition: all 0.3s ease; } .sm-info { flex-grow: 1; min-width: 160px; overflow: hidden; margin-right: 10px; } .sm-name { font-weight: bold; font-size: 1.1em; display: flex; align-items: center; color: #202122; } .sm-id-row { font-size: 0.8em; color: #72777d; font-family: monospace; margin-top: 4px; display: flex; align-items: center; gap: 8px; } .sm-js-link { color: #36c; text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 250px; border-bottom: 1px solid transparent; } .sm-js-link:hover { border-bottom-color: #36c; } .sm-status-badge { font-size: 10px; padding: 2px 6px; border-radius: 10px; margin-left: 10px; text-transform: uppercase; border: 1px solid #c8ccd1; background: #f8f9fa; color: #72777d; } .status-on { background: #eaf3ff; color: #36c; border-color: #36c; } .sm-mode-switch { padding: 0 10px; border-right: 1px solid #eaecf0; margin-right: 10px; text-align: center; } .sm-mode-toggle { border: 1px solid #a2a9b1; border-radius: 4px; padding: 4px 8px; cursor: pointer; font-size: 10.5px; background: #fff; color: #202122; white-space: nowrap; } .sm-main-toggle { border-right: 2px solid #eaecf0; padding-right: 10px; margin-right: 10px; flex-shrink: 0; } .sm-sub-options { display: flex; gap: 8px; flex-wrap: wrap; flex-shrink: 0; } .sm-checkbox-label { display: flex; flex-direction: column; align-items: center; font-size: 0.75em; color: #54595d; cursor: pointer; min-width: 46px; text-align: center; } .sm-checkbox-label input { margin-bottom: 4px; cursor: pointer; } .mode-bl-active .sm-sub-checkbox:not(:checked) { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #d33; background: #d33; position: relative; border-radius: 2px; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after, .mode-bl-active .sm-sub-checkbox:not(:checked)::before { content: ''; position: absolute; width: 10px; height: 1.8px; background-color: white; top: 50%; left: 50%; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after { transform: translate(-50%, -50%) rotate(45deg); } .mode-bl-active .sm-sub-checkbox:not(:checked)::before { transform: translate(-50%, -50%) rotate(-45deg); } .mode-bl-active .sm-sub-checkbox:checked { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #a2a9b1; border-radius: 2px; background: #fff; } .mode-bl-active { border-left-color: #d33 !important; } .mode-bl-active .status-on { background: #fee7e6; color: #d33; border-color: #d33; } .sm-card.disabled { background: #f8f9fa !important; } .sm-footer-actions { position: sticky; bottom: 20px; float: right; display: flex; gap: 10px; z-index: 100; } .sm-btn { border: none; padding: 12px 24px; border-radius: 4px; font-weight: bold; cursor: pointer; transition: background 0.2s; } #sm-save-btn { background: #36c; color: #fff; } #sm-common-js-btn { background: #f8f9fa; color: #202122; border: 1px solid #a2a9b1; text-decoration: none; font-size: 0.95em; display: flex; align-items: center; } /* 管理スクリプトがない時の案内用スタイル */ .sm-guide-box { background: #f8f9fa; border: 1px dashed #a2a9b1; padding: 20px; border-radius: 8px; text-align: center; margin: 20px 0; } .sm-guide-box h3 { margin-top: 0; } .sm-step { display: inline-block; text-align: left; margin: 10px 0; vertical-align: top; width: 250px; padding: 10px; } `).appendTo('head'); var $container = $('<div id="sm-container"></div>'); if (scriptList.length === 0) { var manualUrl = 'https://ja.wikipedia.org/wiki/' + encodeURIComponent('利用者:OUT_is_this/ScriptManager'); $container.append(` <div class="sm-guide-box"> <h3>スクリプトが登録されていません</h3> <p>以下の手順でスクリプトを追加してください:</p> <div class="sm-step"><b>1. 探す</b><br>ScriptManagerに登録したいスクリプトが置いてある <code>.js</code> ページを開きます。</div> <div class="sm-step"><b>2. 追加する</b><br>ページ上部の「ScriptManagerに追加」ボタンを押します。</div> <div class="sm-step"><b>3. 保存</b><br>名前を付けて保存すると自動で common.js に書き込まれます。</div> <div style="margin-top:20px; padding-top:15px; border-top:1px solid #eaecf0; text-align:center;"> <div style="display:inline-flex; align-items:flex-start; color:#202122;"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 20 20" style="flex-shrink:0; margin-right:8px; margin-top:4px;"> <path d="M10 0C4.48 0 0 4.48 0 10s4.48 10 10 10 10-4.48 10-10S15.52 0 10 0zm0 15c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1s1 .45 1 1v4c0 .55-.45 1-1 1zm1-8H9V5h2v2z" fill="#36c"/> </svg> <span style="line-height:1.8; text-align:center; display:block;"> common.js に手入力で直接書き込む方法や、他ドメインにある js の登録方法、その他詳しい使い方などは<br> <a href="${manualUrl}" target="_blank" style="font-weight:bold; text-decoration:none; color:#36c;">こちら(解説ページ)</a>をご覧ください。 </span> </div> </div> </div> `); } scriptList.forEach(function(script) { var s = userSettings[script.id] || { enabled: false, isBlacklistMode: false, onMain: true, onUser: true, onTalk: true, onSpecial: true, onEdit: true, onPreview: true, onDiff: true }; var $card = $('<div class="sm-card">'); if (!s.enabled) $card.css({'background': '#f8f9fa'}); if (s.isBlacklistMode) $card.addClass('mode-bl-active'); var $status = $('<span class="sm-status-badge"></span>').addClass(s.enabled ? 'status-on' : '').text(s.enabled ? 'ON' : 'OFF'); var viewUrl = script.url.replace(/[?&]action=raw/, '').replace(/[?&]ctype=[^&]+/, ''); var $info = $('<div class="sm-info">').append( $('<div class="sm-name">').text(script.name).append($status), $('<div class="sm-id-row">').append( $('<span>').text(script.id), $('<a>').attr({href: viewUrl, target: '_blank', title: script.pageTitle}) .addClass('sm-js-link').text('⇨ ' + script.pageTitle) ) ); var $modeBtn = $('<div class="sm-mode-toggle">').text(s.isBlacklistMode ? '制限ベース' : '許可ベース'); $modeBtn.on('click', function() { var isBl = $(this).text() === '許可ベース'; $(this).text(isBl ? '制限ベース' : '許可ベース'); $card.toggleClass('mode-bl-active', isBl); }); var $masterCheck = $('<input type="checkbox" class="sm-master">') .prop('checked', s.enabled) .attr('data-id', script.id) .css({ 'cursor': 'pointer', 'width': '18px', 'height': '18px', 'appearance': 'none', '-webkit-appearance': 'none', 'border': '2px solid #000', // ★無効でも縁を黒く 'border-radius': '3px', 'background-color': '#fff', 'position': 'relative', 'margin-bottom': '4px' }); // チェック時のレ点スタイルを動的に追加(ループの外で一度だけ実行が理想ですが、ここでIDごとに定義も可) if (!$('#sm-custom-checkbox-style').length) { $('<style id="sm-custom-checkbox-style">').text(` .sm-master:checked { background-color: #36c !important; border-color: #36c !important; } .sm-master:checked::after { content: ""; position: absolute; left: 5px; top: 1px; width: 5px; height: 10px; border: solid white; border-width: 0 2px 2px 0; transform: rotate(45deg); } `).appendTo('head'); } var $mainToggle = $('<div class="sm-main-toggle">').append( $('<label class="sm-checkbox-label">').append( $masterCheck, $('<b style="color:#202122; opacity:1;">').text('有効') // ★文字を薄くせず黒く ) ); // --- 以下、イベントハンドラやオプションの追加 --- $masterCheck.on('change', function() { var checked = $(this).is(':checked'); // カード全体の不透明度を下げないように変更 $card.css('background', checked ? '#fff' : '#f8f9fa'); $card.find('.sm-status-badge').toggleClass('status-on', checked).text(checked ? 'ON' : 'OFF'); }); function createOption(label, key, val) { var $input = $('<input type="checkbox" class="sm-sub-checkbox">').addClass('sm-' + key).prop('checked', val); return $('<label class="sm-checkbox-label">').append($input, label); } var $subOptions = $('<div class="sm-sub-options">').append( createOption('記事/WP', 'main', s.onMain), createOption('利用者', 'user', s.onUser), createOption('ノート', 'talk', s.onTalk), createOption('特別', 'special', s.onSpecial), createOption('編集', 'edit', s.onEdit), createOption('プレビュー', 'preview', s.onPreview), createOption('差分', 'diff', s.onDiff) ); $mainToggle.find('.sm-master').on('change', function() { var checked = $(this).is(':checked'); $card.toggleClass('disabled', !checked); $card.find('.sm-status-badge').toggleClass('status-on', checked).text(checked ? 'ON' : 'OFF'); }); $container.append($card.append($info, $('<div class="sm-mode-switch">').append($modeBtn), $mainToggle, $subOptions)); }); $body.append($container, $('<div class="sm-footer-actions">').append( $('<a>').attr({id: 'sm-common-js-btn', href: mw.util.getUrl('Special:MyPage/common.js'), target: '_blank'}).addClass('sm-btn').text('common.js を編集'), $('<button id="sm-save-btn">設定を保存して適用</button>').addClass('sm-btn').on('click', function() { var newSettings = {}; $('.sm-card').each(function() { var $c = $(this); var id = $c.find('.sm-master').attr('data-id'); newSettings[id] = { enabled: $c.find('.sm-master').is(':checked'), isBlacklistMode: $c.find('.sm-mode-toggle').text() === '制限ベース', onMain: $c.find('.sm-main').is(':checked'), onUser: $c.find('.sm-user').is(':checked'), onTalk: $c.find('.sm-talk').is(':checked'), onSpecial: $c.find('.sm-special').is(':checked'), onEdit: $c.find('.sm-edit').is(':checked'), onPreview: $c.find('.sm-preview').is(':checked'), onDiff: $c.find('.sm-diff').is(':checked') }; }); localStorage.setItem('wp-script-manager-v4', JSON.stringify(newSettings)); mw.notify('設定を保存しました。'); var returnUrl = document.referrer; setTimeout(function() { location.href = (returnUrl && returnUrl.indexOf(location.hostname) !== -1) ? returnUrl : mw.util.getUrl('Main_Page'); }, 800); }) )); } $(function() { // 1. 基本情報の取得 const pageName = mw.config.get('wgPageName').replace(/_/g, ' '); const action = mw.config.get('wgAction'); const userName = mw.config.get('wgUserName') const userNs = mw.config.get('wgFormattedNamespaces')[2]; const myCommonJs = userNs + ':' + userName + '/common.js'; const isJsPage = pageName.endsWith('.js'); const isManagerScript = pageName.endsWith('ScriptManager.js'); const isDiff = !!mw.config.get('wgDiffNewId'); // 2. 登録済み判定 function checkRegistration() { if (!window.scriptManagerList) return false; return window.scriptManagerList.some(script => { const savedTitle = (script.title || '').replace(/_/g, ' '); return savedTitle === pageName; }); } const isAlreadyRegistered = checkRegistration(); // --- 表示条件 --- // ・JSページである // ・現在のページが「自分のcommon.js」もしくは ScriptManager.jsでは表示しない。 // ・未登録である // ・閲覧モードかつ差分表示ではない // --- ボタンのデザイン変更(青い四角の箱) --- if (isJsPage && pageName !== myCommonJs && !isManagerScript && !isAlreadyRegistered && action === 'view' && !isDiff) { const $smInstallBtn = $('<button>') .text('ScriptManagerに追加') .addClass('mw-ui-button mw-ui-progressive') .css({ 'margin-left': '12px', 'vertical-align': 'middle', 'border-radius': '2px', 'padding': '0 12px', 'height': '32px', 'font-weight': 'bold', 'box-shadow': 'none' }) .on('click', function() { const scriptName = prompt('このスクリプトに名前をつけてください:', mw.config.get('wgTitle')); if (scriptName) { installScript(pageName, scriptName, $(this)); } }); $('#firstHeading').append($smInstallBtn); } // 3. common.js への追加処理 function installScript(targetPage, label, $button) { const api = new mw.Api(); // --- 1. ドメインと言語の判定ロジック(省略) --- const rawDomain = mw.config.get('wgServerName'); let lang = ''; let domain = rawDomain; const parts = rawDomain.split('.'); if (parts.length >= 3 && parts.slice(-2).join('.') === 'wikipedia.org') { lang = parts[0]; domain = 'wikipedia.org'; } if (domain === 'wikipedia.org') domain = ''; if (lang === 'ja') lang = ''; // --- 2. エントリとウィキリンクの作成(省略) --- let entryParts = [`name: '${label}'`]; if (lang !== '') entryParts.push(`lang: '${lang}'`); if (domain !== '') entryParts.push(`domain: '${domain}'`); entryParts.push(`title: '${targetPage}'`); let wikiLink = (domain !== '' && domain !== 'wikipedia.org') ? `[${location.protocol}//${rawDomain}/wiki/${encodeURI(targetPage)} ${targetPage}]` : `[[${(lang !== '' && lang !== 'ja') ? ':' + lang + ':' : ''}${targetPage}]]`; // --- 最終的な書き出し形式の組み立て --- // 1行目にコメント、2行目にオブジェクト(インデント付き) const newEntry = ` // ${wikiLink}\n { ${entryParts.join(', ')} },`; api.get({ action: 'query', prop: 'revisions', titles: myCommonJs, rvprop: 'content', rvslots: 'main' }).done(function(data) { const page = Object.values(data.query.pages)[0]; let content = (page && page.revisions) ? page.revisions[0].slots.main['*'] : ''; // --- 重複コードの検出と削除 (既存) --- const escapedPage = targetPage.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/[ _]/g, '[ _]'); const loadPattern = new RegExp(`(mw\\.loader\\.load|importScript)\\s*\\(\\s*['"\`].*?${escapedPage}.*?['"\`]\\s*\\);?`, 'g'); if (loadPattern.test(content)) { if (!confirm(`注意:common.js 内にこのスクリプトの既存の読み込みコードが見つかりました。\n\n「OK」:既存のコードを削除して移行します。\n「キャンセル」:中止します。`)) return; content = content.replace(loadPattern, '').replace(/\n{3,}/g, '\n\n'); } // --- コンテンツの更新 --- // 配列の開始位置のすぐ後ろに「コメント + オブジェクト」を挿入 if (content.includes('window.scriptManagerList = [')) { content = content.replace('window.scriptManagerList = [', `window.scriptManagerList = [\n${newEntry}`); } else { content = `window.scriptManagerList = [\n${newEntry}\n];\n\n` + content; } api.postWithToken('csrf', { action: 'edit', title: myCommonJs, text: content, summary: `${wikiLink} を ScriptManager に追加 (${label})` }).done(function(saveData) { if (saveData.edit && saveData.edit.result === 'Success') { mw.notify(label + ' を追加しました。'); $button.fadeOut(); if (!window.scriptManagerList) window.scriptManagerList = []; window.scriptManagerList.push({ name: label, lang: lang, domain: domain, title: targetPage }); } }); }); } }); })(jQuery, mediaWiki); 39uh3etpfy4i4cvualsoqziyjae22tx 740987 740986 2026-05-08T12:59:27Z OUT is this 73801 Undid revision [[Special:Diff/740986|740986]] by [[Special:Contributions/OUT is this|OUT is this]] ([[User talk:OUT is this|talk]]) 740987 javascript text/javascript (function($, mw) { 'use strict'; // --- 1. スクリプト情報の整理 --- var rawList = window.scriptManagerList || []; var usedIds = {}; var scriptList = rawList.map(function(script) { var finalUrl = ''; // --- URL生成ロジック --- if (script.url) { finalUrl = script.url; } else { var langCode = (script.lang === undefined) ? 'ja' : script.lang; var langPrefix = (langCode !== '') ? langCode + '.' : ''; var domain = script.domain || 'wikipedia.org'; var title = script.title || ''; finalUrl = '//' + langPrefix + domain + '/w/index.php?title=' + encodeURIComponent(title) + '&action=raw&ctype=text/javascript'; } var match = finalUrl.match(/[?&]title=([^&]+)/); var pageTitle = match ? decodeURIComponent(match[1]) : 'Unknown'; var idBase = 'unknown'; if (match) { idBase = pageTitle .replace(/^(User|利用者):[^/]+\//i, '') .replace(/\.js$/i, '') .replace(/[ _ %]+/g, '_') .replace(/[^a-zA-Z0-9_]/g, ''); } var finalId = idBase; var counter = 2; while (usedIds[finalId]) { finalId = idBase + '_' + counter; counter++; } usedIds[finalId] = true; return { id: finalId, name: script.name, url: finalUrl, pageTitle: pageTitle }; }); // --- 2. 現在の状態の取得 --- var userSettings = JSON.parse(localStorage.getItem('wp-script-manager-v4') || '{}'); var pageName = mw.config.get('wgPageName').replace(/[ _ ]+/g, '').toLowerCase(); var action = mw.config.get('wgAction'); var ns = mw.config.get('wgNamespaceNumber'); var isDiff = !!mw.config.get('wgDiffNewId'); var isPreview = ['submit', 'preview'].indexOf(action) !== -1 && $('#wikiPreview').length > 0; var isMainNS = (ns === 0 || ns === 4); var isUserNS = (ns === 2 || ns === 3); var isTalkNS = (ns % 2 !== 0 && ns > 0); var isSpecialNS = (ns === -1); var isEditMode = (action === 'edit' || action === 'submit'); // --- 3. メニューへのリンク追加 --- $(function() { var smPageUrl = mw.util.getUrl('Special:SM'); var smLinks = $( ['', '-sticky-header'] .map(function(suffix) { var parentId = $('#p-user-menu-pages' + suffix).length ? 'p-user-menu-pages' : 'p-personal'; return mw.util.addPortletLink( parentId + suffix, smPageUrl, 'スクリプト管理画面', 'pt-scriptmanager' + suffix, 'Script Managerを開く', null, '#pt-logout' + suffix ); }) .filter(function(elOrNull) { return elOrNull !== null; }) ); if (smLinks.length > 0) { const style = ` li[id^="pt-scriptmanager"] a { width: auto !important; padding-left: 25px; white-space: nowrap; height: 20px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><path d="M20 10c0-.7-.1-1.3-.2-1.9l-2.3-.4c-.2-.7-.4-1.4-.8-2l1.4-1.9c-.5-.7-1.1-1.3-1.8-1.8l-1.9 1.4c-.6-.4-1.3-.6-2-.8l-.4-2.3c-.7-.1-1.3-.2-1.9-.2s-1.3.1-1.9.2l-.4 2.3c-.7.2-1.4.4-2 .8L4.1 2c-.7.5-1.3 1.1-1.8 1.8l1.4 1.9c-.4.6-.6 1.3-.8 2l-2.3.4c-.1.6-.2 1.2-.2 1.9s.1 1.3.2 1.9l2.3.4c.2.7.4 1.4.8 2l-1.4 1.9c.5.7 1.1 1.3 1.8 1.8l1.9-1.4c.6.4 1.3.6 2 .8l.4 2.3c.6.1 1.2.2 1.9.2s1.3-.1 1.9-.2l.4-2.3c.7-.2 1.4-.4 2-.8l1.9 1.4c.7-.5 1.3-1.1 1.8-1.8l-1.4-1.9c.4-.6.6-1.3.8-2l2.3-.4c.1-.6.2-1.2.2-1.9z" fill="%23202122"/><text x="10" y="13" font-family="sans-serif" font-weight="bold" font-size="8px" fill="white" text-anchor="middle">JS</text></svg>'); background-repeat: no-repeat; background-size: 20px 20px; background-position: center left; } `; $('<style>').text(style).appendTo('head'); } }); // --- 4. スクリプトのロード判定ロジック --- scriptList.forEach(function(script) { var s = userSettings[script.id]; if (!s || !s.enabled) return; var shouldLoad = false; if (s.isBlacklistMode) { var blocked = false; if (isDiff && !s.onDiff) blocked = true; else if (isPreview && !s.onPreview) blocked = true; else if (isEditMode && !s.onEdit) blocked = true; else if (action === 'view' && !isDiff) { if (isMainNS && !s.onMain) blocked = true; else if (isUserNS && !s.onUser) blocked = true; else if (isTalkNS && !s.onTalk) blocked = true; else if (isSpecialNS && !s.onSpecial) blocked = true; } shouldLoad = !blocked; } else { if (isDiff && s.onDiff) shouldLoad = true; else if (isPreview && s.onPreview) shouldLoad = true; else if (isEditMode && s.onEdit) shouldLoad = true; else if (action === 'view' && !isDiff) { if (isMainNS && s.onMain) shouldLoad = true; else if (isUserNS && s.onUser) shouldLoad = true; else if (isTalkNS && s.onTalk) shouldLoad = true; else if (isSpecialNS && s.onSpecial) shouldLoad = true; } } if (shouldLoad) mw.loader.load(script.url); }); // --- 5. 管理画面(Special:SM)の構築 --- if (/^(special|特別):(scriptmanager|sm)$/i.test(pageName)) { document.title = 'Script Manager'; $('#firstHeading').text('Script Manager'); var $body = $('#mw-content-text').empty(); $('<style>').text(` #sm-container { font-family: sans-serif; color: #202122; max-width: 1000px; margin: 20px 0; } .sm-card { background: #fff; border: 1px solid #c8ccd1; border-left: 5px solid #36c; border-radius: 8px; padding: 14px; margin-bottom: 16px; display: flex; align-items: center; transition: all 0.3s ease; } .sm-info { flex-grow: 1; min-width: 160px; overflow: hidden; margin-right: 10px; } .sm-name { font-weight: bold; font-size: 1.1em; display: flex; align-items: center; color: #202122; } .sm-id-row { font-size: 0.8em; color: #72777d; font-family: monospace; margin-top: 4px; display: flex; align-items: center; gap: 8px; } .sm-js-link { color: #36c; text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 250px; border-bottom: 1px solid transparent; } .sm-js-link:hover { border-bottom-color: #36c; } .sm-status-badge { font-size: 10px; padding: 2px 6px; border-radius: 10px; margin-left: 10px; text-transform: uppercase; border: 1px solid #c8ccd1; background: #f8f9fa; color: #72777d; } .status-on { background: #eaf3ff; color: #36c; border-color: #36c; } .sm-mode-switch { padding: 0 10px; border-right: 1px solid #eaecf0; margin-right: 10px; text-align: center; } .sm-mode-toggle { border: 1px solid #a2a9b1; border-radius: 4px; padding: 4px 8px; cursor: pointer; font-size: 10.5px; background: #fff; color: #202122; white-space: nowrap; } .sm-main-toggle { border-right: 2px solid #eaecf0; padding-right: 10px; margin-right: 10px; flex-shrink: 0; } .sm-sub-options { display: flex; gap: 8px; flex-wrap: wrap; flex-shrink: 0; } .sm-checkbox-label { display: flex; flex-direction: column; align-items: center; font-size: 0.75em; color: #54595d; cursor: pointer; min-width: 46px; text-align: center; } .sm-checkbox-label input { margin-bottom: 4px; cursor: pointer; } .mode-bl-active .sm-sub-checkbox:not(:checked) { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #d33; background: #d33; position: relative; border-radius: 2px; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after, .mode-bl-active .sm-sub-checkbox:not(:checked)::before { content: ''; position: absolute; width: 10px; height: 1.8px; background-color: white; top: 50%; left: 50%; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after { transform: translate(-50%, -50%) rotate(45deg); } .mode-bl-active .sm-sub-checkbox:not(:checked)::before { transform: translate(-50%, -50%) rotate(-45deg); } .mode-bl-active .sm-sub-checkbox:checked { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #a2a9b1; border-radius: 2px; background: #fff; } .mode-bl-active { border-left-color: #d33 !important; } .mode-bl-active .status-on { background: #fee7e6; color: #d33; border-color: #d33; } .sm-card.disabled { background: #f8f9fa !important; opacity: 0.6; filter: grayscale(1); } .sm-footer-actions { position: sticky; bottom: 20px; float: right; display: flex; gap: 10px; z-index: 100; } .sm-btn { border: none; padding: 12px 24px; border-radius: 4px; font-weight: bold; cursor: pointer; transition: background 0.2s; } #sm-save-btn { background: #36c; color: #fff; } #sm-common-js-btn { background: #f8f9fa; color: #202122; border: 1px solid #a2a9b1; text-decoration: none; font-size: 0.95em; display: flex; align-items: center; } /* 管理スクリプトがない時の案内用スタイル */ .sm-guide-box { background: #f8f9fa; border: 1px dashed #a2a9b1; padding: 20px; border-radius: 8px; text-align: center; margin: 20px 0; } .sm-guide-box h3 { margin-top: 0; } .sm-step { display: inline-block; text-align: left; margin: 10px 0; vertical-align: top; width: 250px; padding: 10px; } `).appendTo('head'); var $container = $('<div id="sm-container"></div>'); if (scriptList.length === 0) { var manualUrl = 'https://ja.wikipedia.org/wiki/' + encodeURIComponent('利用者:OUT_is_this/ScriptManager'); $container.append(` <div class="sm-guide-box"> <h3>スクリプトが登録されていません</h3> <p>以下の手順でスクリプトを追加してください:</p> <div class="sm-step"><b>1. 探す</b><br>ScriptManagerに登録したいスクリプトが置いてある <code>.js</code> ページを開きます。</div> <div class="sm-step"><b>2. 追加する</b><br>ページ上部の「ScriptManagerに追加」ボタンを押します。</div> <div class="sm-step"><b>3. 保存</b><br>名前を付けて保存すると自動で common.js に書き込まれます。</div> <div style="margin-top:20px; padding-top:15px; border-top:1px solid #eaecf0; text-align:center;"> <div style="display:inline-flex; align-items:flex-start; color:#202122;"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 20 20" style="flex-shrink:0; margin-right:8px; margin-top:4px;"> <path d="M10 0C4.48 0 0 4.48 0 10s4.48 10 10 10 10-4.48 10-10S15.52 0 10 0zm0 15c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1s1 .45 1 1v4c0 .55-.45 1-1 1zm1-8H9V5h2v2z" fill="#36c"/> </svg> <span style="line-height:1.8; text-align:center; display:block;"> common.js に手入力で直接書き込む方法や、他ドメインにある js の登録方法、その他詳しい使い方などは<br> <a href="${manualUrl}" target="_blank" style="font-weight:bold; text-decoration:none; color:#36c;">こちら(解説ページ)</a>をご覧ください。 </span> </div> </div> </div> `); } scriptList.forEach(function(script) { var s = userSettings[script.id] || { enabled: false, isBlacklistMode: false, onMain: true, onUser: true, onTalk: true, onSpecial: true, onEdit: true, onPreview: true, onDiff: true }; var $card = $('<div class="sm-card">').toggleClass('disabled', !s.enabled); if (s.isBlacklistMode) $card.addClass('mode-bl-active'); var $status = $('<span class="sm-status-badge"></span>').addClass(s.enabled ? 'status-on' : '').text(s.enabled ? 'ON' : 'OFF'); var viewUrl = script.url.replace(/[?&]action=raw/, '').replace(/[?&]ctype=[^&]+/, ''); var $info = $('<div class="sm-info">').append( $('<div class="sm-name">').text(script.name).append($status), $('<div class="sm-id-row">').append( $('<span>').text(script.id), $('<a>').attr({href: viewUrl, target: '_blank', title: script.pageTitle}) .addClass('sm-js-link').text('⇨ ' + script.pageTitle) ) ); var $modeBtn = $('<div class="sm-mode-toggle">').text(s.isBlacklistMode ? '制限ベース' : '許可ベース'); $modeBtn.on('click', function() { var isBl = $(this).text() === '許可ベース'; $(this).text(isBl ? '制限ベース' : '許可ベース'); $card.toggleClass('mode-bl-active', isBl); }); var $mainToggle = $('<div class="sm-main-toggle">').append( $('<label class="sm-checkbox-label">').append($('<input type="checkbox" class="sm-master">').prop('checked', s.enabled).attr('data-id', script.id), '<b>有効</b>') ); function createOption(label, key, val) { var $input = $('<input type="checkbox" class="sm-sub-checkbox">').addClass('sm-' + key).prop('checked', val); return $('<label class="sm-checkbox-label">').append($input, label); } var $subOptions = $('<div class="sm-sub-options">').append( createOption('記事/WP', 'main', s.onMain), createOption('利用者', 'user', s.onUser), createOption('ノート', 'talk', s.onTalk), createOption('特別', 'special', s.onSpecial), createOption('編集', 'edit', s.onEdit), createOption('プレビュー', 'preview', s.onPreview), createOption('差分', 'diff', s.onDiff) ); $mainToggle.find('.sm-master').on('change', function() { var checked = $(this).is(':checked'); $card.toggleClass('disabled', !checked); $card.find('.sm-status-badge').toggleClass('status-on', checked).text(checked ? 'ON' : 'OFF'); }); $container.append($card.append($info, $('<div class="sm-mode-switch">').append($modeBtn), $mainToggle, $subOptions)); }); $body.append($container, $('<div class="sm-footer-actions">').append( $('<a>').attr({id: 'sm-common-js-btn', href: mw.util.getUrl('Special:MyPage/common.js'), target: '_blank'}).addClass('sm-btn').text('common.js を編集'), $('<button id="sm-save-btn">設定を保存して適用</button>').addClass('sm-btn').on('click', function() { var newSettings = {}; $('.sm-card').each(function() { var $c = $(this); var id = $c.find('.sm-master').attr('data-id'); newSettings[id] = { enabled: $c.find('.sm-master').is(':checked'), isBlacklistMode: $c.find('.sm-mode-toggle').text() === '制限ベース', onMain: $c.find('.sm-main').is(':checked'), onUser: $c.find('.sm-user').is(':checked'), onTalk: $c.find('.sm-talk').is(':checked'), onSpecial: $c.find('.sm-special').is(':checked'), onEdit: $c.find('.sm-edit').is(':checked'), onPreview: $c.find('.sm-preview').is(':checked'), onDiff: $c.find('.sm-diff').is(':checked') }; }); localStorage.setItem('wp-script-manager-v4', JSON.stringify(newSettings)); mw.notify('設定を保存しました。'); var returnUrl = document.referrer; setTimeout(function() { location.href = (returnUrl && returnUrl.indexOf(location.hostname) !== -1) ? returnUrl : mw.util.getUrl('Main_Page'); }, 800); }) )); } $(function() { // 1. 基本情報の取得 const pageName = mw.config.get('wgPageName').replace(/_/g, ' '); const action = mw.config.get('wgAction'); const userName = mw.config.get('wgUserName') const userNs = mw.config.get('wgFormattedNamespaces')[2]; const myCommonJs = userNs + ':' + userName + '/common.js'; const isJsPage = pageName.endsWith('.js'); const isManagerScript = pageName.endsWith('ScriptManager.js'); const isDiff = !!mw.config.get('wgDiffNewId'); // 2. 登録済み判定 function checkRegistration() { if (!window.scriptManagerList) return false; return window.scriptManagerList.some(script => { const savedTitle = (script.title || '').replace(/_/g, ' '); return savedTitle === pageName; }); } const isAlreadyRegistered = checkRegistration(); // --- 表示条件 --- // ・JSページである // ・現在のページが「自分のcommon.js」もしくは ScriptManager.jsでは表示しない。 // ・未登録である // ・閲覧モードかつ差分表示ではない // --- ボタンのデザイン変更(青い四角の箱) --- if (isJsPage && pageName !== myCommonJs && !isManagerScript && !isAlreadyRegistered && action === 'view' && !isDiff) { const $smInstallBtn = $('<button>') .text('ScriptManagerに追加') .addClass('mw-ui-button mw-ui-progressive') .css({ 'margin-left': '12px', 'vertical-align': 'middle', 'border-radius': '2px', 'padding': '0 12px', 'height': '32px', 'font-weight': 'bold', 'box-shadow': 'none' }) .on('click', function() { const scriptName = prompt('このスクリプトに名前をつけてください:', mw.config.get('wgTitle')); if (scriptName) { installScript(pageName, scriptName, $(this)); } }); $('#firstHeading').append($smInstallBtn); } // 3. common.js への追加処理 function installScript(targetPage, label, $button) { const api = new mw.Api(); // --- 1. ドメインと言語の判定ロジック(省略) --- const rawDomain = mw.config.get('wgServerName'); let lang = ''; let domain = rawDomain; const parts = rawDomain.split('.'); if (parts.length >= 3 && parts.slice(-2).join('.') === 'wikipedia.org') { lang = parts[0]; domain = 'wikipedia.org'; } if (domain === 'wikipedia.org') domain = ''; if (lang === 'ja') lang = ''; // --- 2. エントリとウィキリンクの作成(省略) --- let entryParts = [`name: '${label}'`]; if (lang !== '') entryParts.push(`lang: '${lang}'`); if (domain !== '') entryParts.push(`domain: '${domain}'`); entryParts.push(`title: '${targetPage}'`); let wikiLink = (domain !== '' && domain !== 'wikipedia.org') ? `[${location.protocol}//${rawDomain}/wiki/${encodeURI(targetPage)} ${targetPage}]` : `[[${(lang !== '' && lang !== 'ja') ? ':' + lang + ':' : ''}${targetPage}]]`; // --- 最終的な書き出し形式の組み立て --- // 1行目にコメント、2行目にオブジェクト(インデント付き) const newEntry = ` // ${wikiLink}\n { ${entryParts.join(', ')} },`; api.get({ action: 'query', prop: 'revisions', titles: myCommonJs, rvprop: 'content', rvslots: 'main' }).done(function(data) { const page = Object.values(data.query.pages)[0]; let content = (page && page.revisions) ? page.revisions[0].slots.main['*'] : ''; // --- 重複コードの検出と削除 (既存) --- const escapedPage = targetPage.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/[ _]/g, '[ _]'); const loadPattern = new RegExp(`(mw\\.loader\\.load|importScript)\\s*\\(\\s*['"\`].*?${escapedPage}.*?['"\`]\\s*\\);?`, 'g'); if (loadPattern.test(content)) { if (!confirm(`注意:common.js 内にこのスクリプトの既存の読み込みコードが見つかりました。\n\n「OK」:既存のコードを削除して移行します。\n「キャンセル」:中止します。`)) return; content = content.replace(loadPattern, '').replace(/\n{3,}/g, '\n\n'); } // --- コンテンツの更新 --- // 配列の開始位置のすぐ後ろに「コメント + オブジェクト」を挿入 if (content.includes('window.scriptManagerList = [')) { content = content.replace('window.scriptManagerList = [', `window.scriptManagerList = [\n${newEntry}`); } else { content = `window.scriptManagerList = [\n${newEntry}\n];\n\n` + content; } api.postWithToken('csrf', { action: 'edit', title: myCommonJs, text: content, summary: `${wikiLink} を ScriptManager に追加 (${label})` }).done(function(saveData) { if (saveData.edit && saveData.edit.result === 'Success') { mw.notify(label + ' を追加しました。'); $button.fadeOut(); if (!window.scriptManagerList) window.scriptManagerList = []; window.scriptManagerList.push({ name: label, lang: lang, domain: domain, title: targetPage }); } }); }); } }); })(jQuery, mediaWiki); nxtghmrssih0ib5j5bu0zoozv67kjn8 740995 740987 2026-05-08T13:28:27Z OUT is this 73801 740995 javascript text/javascript (function($, mw) { 'use strict'; // --- 1. スクリプト情報の整理 --- var rawList = window.scriptManagerList || []; var usedIds = {}; var scriptList = rawList.map(function(script) { var finalUrl = ''; // --- URL生成ロジック --- if (script.url) { finalUrl = script.url; } else { var langCode = (script.lang === undefined) ? 'ja' : script.lang; var langPrefix = (langCode !== '') ? langCode + '.' : ''; var domain = script.domain || 'wikipedia.org'; var title = script.title || ''; finalUrl = '//' + langPrefix + domain + '/w/index.php?title=' + encodeURIComponent(title) + '&action=raw&ctype=text/javascript'; } var match = finalUrl.match(/[?&]title=([^&]+)/); var pageTitle = match ? decodeURIComponent(match[1]) : 'Unknown'; var idBase = 'unknown'; if (match) { idBase = pageTitle .replace(/^(User|利用者):[^/]+\//i, '') .replace(/\.js$/i, '') .replace(/[ _ %]+/g, '_') .replace(/[^a-zA-Z0-9_]/g, ''); } var finalId = idBase; var counter = 2; while (usedIds[finalId]) { finalId = idBase + '_' + counter; counter++; } usedIds[finalId] = true; return { id: finalId, name: script.name, url: finalUrl, pageTitle: pageTitle }; }); // --- 2. 現在の状態の取得 --- var userSettings = JSON.parse(localStorage.getItem('wp-script-manager-v4') || '{}'); var pageName = mw.config.get('wgPageName').replace(/[ _ ]+/g, '').toLowerCase(); var action = mw.config.get('wgAction'); var ns = mw.config.get('wgNamespaceNumber'); var isDiff = !!mw.config.get('wgDiffNewId'); var isPreview = ['submit', 'preview'].indexOf(action) !== -1 && $('#wikiPreview').length > 0; var isMainNS = (ns === 0 || ns === 4); var isUserNS = (ns === 2 || ns === 3); var isTalkNS = (ns % 2 !== 0 && ns > 0); var isSpecialNS = (ns === -1); var isEditMode = (action === 'edit' || action === 'submit'); // --- 3. メニューへのリンク追加 --- $(function() { var smPageUrl = mw.util.getUrl('Special:SM'); var smLinks = $( ['', '-sticky-header'] .map(function(suffix) { var parentId = $('#p-user-menu-pages' + suffix).length ? 'p-user-menu-pages' : 'p-personal'; return mw.util.addPortletLink( parentId + suffix, smPageUrl, 'スクリプト管理画面', 'pt-scriptmanager' + suffix, 'Script Managerを開く', null, '#pt-logout' + suffix ); }) .filter(function(elOrNull) { return elOrNull !== null; }) ); if (smLinks.length > 0) { const style = ` li[id^="pt-scriptmanager"] a { width: auto !important; padding-left: 25px; white-space: nowrap; height: 20px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><path d="M20 10c0-.7-.1-1.3-.2-1.9l-2.3-.4c-.2-.7-.4-1.4-.8-2l1.4-1.9c-.5-.7-1.1-1.3-1.8-1.8l-1.9 1.4c-.6-.4-1.3-.6-2-.8l-.4-2.3c-.7-.1-1.3-.2-1.9-.2s-1.3.1-1.9.2l-.4 2.3c-.7.2-1.4.4-2 .8L4.1 2c-.7.5-1.3 1.1-1.8 1.8l1.4 1.9c-.4.6-.6 1.3-.8 2l-2.3.4c-.1.6-.2 1.2-.2 1.9s.1 1.3.2 1.9l2.3.4c.2.7.4 1.4.8 2l-1.4 1.9c.5.7 1.1 1.3 1.8 1.8l1.9-1.4c.6.4 1.3.6 2 .8l.4 2.3c.6.1 1.2.2 1.9.2s1.3-.1 1.9-.2l.4-2.3c.7-.2 1.4-.4 2-.8l1.9 1.4c.7-.5 1.3-1.1 1.8-1.8l-1.4-1.9c.4-.6.6-1.3.8-2l2.3-.4c.1-.6.2-1.2.2-1.9z" fill="%23202122"/><text x="10" y="13" font-family="sans-serif" font-weight="bold" font-size="8px" fill="white" text-anchor="middle">JS</text></svg>'); background-repeat: no-repeat; background-size: 20px 20px; background-position: center left; } `; $('<style>').text(style).appendTo('head'); } }); // --- 4. スクリプトのロード判定ロジック --- scriptList.forEach(function(script) { var s = userSettings[script.id]; if (!s || !s.enabled) return; var shouldLoad = false; if (s.isBlacklistMode) { var blocked = false; if (isDiff && !s.onDiff) blocked = true; else if (isPreview && !s.onPreview) blocked = true; else if (isEditMode && !s.onEdit) blocked = true; else if (action === 'view' && !isDiff) { if (isMainNS && !s.onMain) blocked = true; else if (isUserNS && !s.onUser) blocked = true; else if (isTalkNS && !s.onTalk) blocked = true; else if (isSpecialNS && !s.onSpecial) blocked = true; } shouldLoad = !blocked; } else { if (isDiff && s.onDiff) shouldLoad = true; else if (isPreview && s.onPreview) shouldLoad = true; else if (isEditMode && s.onEdit) shouldLoad = true; else if (action === 'view' && !isDiff) { if (isMainNS && s.onMain) shouldLoad = true; else if (isUserNS && s.onUser) shouldLoad = true; else if (isTalkNS && s.onTalk) shouldLoad = true; else if (isSpecialNS && s.onSpecial) shouldLoad = true; } } if (shouldLoad) mw.loader.load(script.url); }); // --- 5. 管理画面(Special:SM)の構築 --- if (/^(special|特別):(scriptmanager|sm)$/i.test(pageName)) { document.title = 'Script Manager'; $('#firstHeading').text('Script Manager'); var $body = $('#mw-content-text').empty(); $('<style>').text(` #sm-container { font-family: sans-serif; color: #202122; max-width: 1000px; margin: 20px 0; } .sm-card { background: #fff; border: 1px solid #c8ccd1; border-left: 5px solid #36c; border-radius: 8px; padding: 14px; margin-bottom: 16px; display: flex; align-items: center; transition: all 0.3s ease; } .sm-info { flex-grow: 1; min-width: 160px; overflow: hidden; margin-right: 10px; } .sm-name { font-weight: bold; font-size: 1.1em; display: flex; align-items: center; color: #202122; } .sm-id-row { font-size: 0.8em; color: #72777d; font-family: monospace; margin-top: 4px; display: flex; align-items: center; gap: 8px; } .sm-js-link { color: #36c; text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 250px; border-bottom: 1px solid transparent; } .sm-js-link:hover { border-bottom-color: #36c; } .sm-status-badge { font-size: 10px; padding: 2px 6px; border-radius: 10px; margin-left: 10px; text-transform: uppercase; border: 1px solid #c8ccd1; background: #f8f9fa; color: #72777d; } .status-on { background: #eaf3ff; color: #36c; border-color: #36c; } .sm-mode-switch { padding: 0 10px; border-right: 1px solid #eaecf0; margin-right: 10px; text-align: center; } .sm-mode-toggle { border: 1px solid #a2a9b1; border-radius: 4px; padding: 4px 8px; cursor: pointer; font-size: 10.5px; background: #fff; color: #202122; white-space: nowrap; } .sm-main-toggle { border-right: 2px solid #eaecf0; padding-right: 10px; margin-right: 10px; flex-shrink: 0; } .sm-sub-options { display: flex; gap: 8px; flex-wrap: wrap; flex-shrink: 0; } .sm-checkbox-label { display: flex; flex-direction: column; align-items: center; font-size: 0.75em; color: #54595d; cursor: pointer; min-width: 46px; text-align: center; } .sm-checkbox-label input { margin-bottom: 4px; cursor: pointer; } .mode-bl-active .sm-sub-checkbox:not(:checked) { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #d33; background: #d33; position: relative; border-radius: 2px; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after, .mode-bl-active .sm-sub-checkbox:not(:checked)::before { content: ''; position: absolute; width: 10px; height: 1.8px; background-color: white; top: 50%; left: 50%; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after { transform: translate(-50%, -50%) rotate(45deg); } .mode-bl-active .sm-sub-checkbox:not(:checked)::before { transform: translate(-50%, -50%) rotate(-45deg); } .mode-bl-active .sm-sub-checkbox:checked { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #a2a9b1; border-radius: 2px; background: #fff; } .mode-bl-active { border-left-color: #d33 !important; } .mode-bl-active .status-on { background: #fee7e6; color: #d33; border-color: #d33; } .sm-card.disabled { background: #f8f9fa !important; opacity: 0.6; filter: grayscale(1); } .sm-footer-actions { position: sticky; bottom: 20px; float: right; display: flex; gap: 10px; z-index: 100; } .sm-btn { border: none; padding: 12px 24px; border-radius: 4px; font-weight: bold; cursor: pointer; transition: background 0.2s; } #sm-save-btn { background: #36c; color: #fff; } #sm-common-js-btn { background: #f8f9fa; color: #202122; border: 1px solid #a2a9b1; text-decoration: none; font-size: 0.95em; display: flex; align-items: center; } /* 管理スクリプトがない時の案内用スタイル */ .sm-guide-box { background: #f8f9fa; border: 1px dashed #a2a9b1; padding: 20px; border-radius: 8px; text-align: center; margin: 20px 0; } .sm-guide-box h3 { margin-top: 0; } .sm-step { display: inline-block; text-align: left; margin: 10px 0; vertical-align: top; width: 250px; padding: 10px; } /* --- CSSセクションの修正 --- */ .sm-checkbox-label { display: flex; flex-direction: column; align-items: center; font-size: 0.75em; color: #202122; cursor: pointer; min-width: 46px; text-align: center; } .sm-checkbox-label input { margin-bottom: 4px; cursor: pointer; opacity: 1 !important; } /* 薄くならないように固定 */ /* カードが無効でも不透明度を下げない */ .sm-card.disabled { background: #f8f9fa !important; filter: none; opacity: 1; } /* メインチェックボックス専用のカスタムスタイル */ .sm-master { appearance: none; -webkit-appearance: none; width: 18px; height: 18px; border: 2px solid #000 !important; border-radius: 3px; background-color: #fff; position: relative; vertical-align: middle; } .sm-master:checked { background-color: #36c !important; border-color: #36c !important; } .sm-master:checked::after { content: ""; position: absolute; left: 4px; top: 0px; width: 5px; height: 10px; border: solid white; border-width: 0 2px 2px 0; transform: rotate(45deg); } /* サブチェックボックス(標準に戻す) */ .sm-sub-checkbox { appearance: auto; -webkit-appearance: auto; width: 13px; height: 13px; } /* ブラックリストモード時の赤い×印は維持 */ .mode-bl-active .sm-sub-checkbox:not(:checked) { appearance: none; -webkit-appearance: none; border: 1px solid #d33; background: #d33; } `).appendTo('head'); var $container = $('<div id="sm-container"></div>'); if (scriptList.length === 0) { var manualUrl = 'https://ja.wikipedia.org/wiki/' + encodeURIComponent('利用者:OUT_is_this/ScriptManager'); $container.append(` <div class="sm-guide-box"> <h3>スクリプトが登録されていません</h3> <p>以下の手順でスクリプトを追加してください:</p> <div class="sm-step"><b>1. 探す</b><br>ScriptManagerに登録したいスクリプトが置いてある <code>.js</code> ページを開きます。</div> <div class="sm-step"><b>2. 追加する</b><br>ページ上部の「ScriptManagerに追加」ボタンを押します。</div> <div class="sm-step"><b>3. 保存</b><br>名前を付けて保存すると自動で common.js に書き込まれます。</div> <div style="margin-top:20px; padding-top:15px; border-top:1px solid #eaecf0; text-align:center;"> <div style="display:inline-flex; align-items:flex-start; color:#202122;"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 20 20" style="flex-shrink:0; margin-right:8px; margin-top:4px;"> <path d="M10 0C4.48 0 0 4.48 0 10s4.48 10 10 10 10-4.48 10-10S15.52 0 10 0zm0 15c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1s1 .45 1 1v4c0 .55-.45 1-1 1zm1-8H9V5h2v2z" fill="#36c"/> </svg> <span style="line-height:1.8; text-align:center; display:block;"> common.js に手入力で直接書き込む方法や、他ドメインにある js の登録方法、その他詳しい使い方などは<br> <a href="${manualUrl}" target="_blank" style="font-weight:bold; text-decoration:none; color:#36c;">こちら(解説ページ)</a>をご覧ください。 </span> </div> </div> </div> `); } scriptList.forEach(function(script) { var s = userSettings[script.id] || { enabled: false, isBlacklistMode: false, onMain: true, onUser: true, onTalk: true, onSpecial: true, onEdit: true, onPreview: true, onDiff: true }; var $card = $('<div class="sm-card">').toggleClass('disabled', !s.enabled); if (s.isBlacklistMode) $card.addClass('mode-bl-active'); var $status = $('<span class="sm-status-badge"></span>').addClass(s.enabled ? 'status-on' : '').text(s.enabled ? 'ON' : 'OFF'); var viewUrl = script.url.replace(/[?&]action=raw/, '').replace(/[?&]ctype=[^&]+/, ''); var $info = $('<div class="sm-info">').append( $('<div class="sm-name">').text(script.name).append($status), $('<div class="sm-id-row">').append( $('<span>').text(script.id), $('<a>').attr({href: viewUrl, target: '_blank', title: script.pageTitle}) .addClass('sm-js-link').text('⇨ ' + script.pageTitle) ) ); var $modeBtn = $('<div class="sm-mode-toggle">').text(s.isBlacklistMode ? '制限ベース' : '許可ベース'); $modeBtn.on('click', function() { var isBl = $(this).text() === '許可ベース'; $(this).text(isBl ? '制限ベース' : '許可ベース'); $card.toggleClass('mode-bl-active', isBl); }); // 1. $masterCheck の定義(インラインCSSを減らしクラスで管理) var $masterCheck = $('<input type="checkbox" class="sm-master">') .prop('checked', s.enabled) .attr('data-id', script.id); // 2. $mainToggle の定義(文字が薄くならないよう直接指定) var $mainToggle = $('<div class="sm-main-toggle">').append( $('<label class="sm-checkbox-label" style="color:#202122; font-weight:bold;">').append( $masterCheck, '有効' ) ); // 3. createOption 関数の修正(サブチェックボックスに専用クラスを付与) function createOption(label, key, val) { var $input = $('<input type="checkbox" class="sm-sub-checkbox">') .addClass('sm-' + key) .prop('checked', val) .css('opacity', '1'); // 個別に透明度を上書き return $('<label class="sm-checkbox-label" style="color:#202122;">').append($input, label); } var $subOptions = $('<div class="sm-sub-options">').append( createOption('記事/WP', 'main', s.onMain), createOption('利用者', 'user', s.onUser), createOption('ノート', 'talk', s.onTalk), createOption('特別', 'special', s.onSpecial), createOption('編集', 'edit', s.onEdit), createOption('プレビュー', 'preview', s.onPreview), createOption('差分', 'diff', s.onDiff) ); $mainToggle.find('.sm-master').on('change', function() { var checked = $(this).is(':checked'); $card.toggleClass('disabled', !checked); $card.find('.sm-status-badge').toggleClass('status-on', checked).text(checked ? 'ON' : 'OFF'); }); $container.append($card.append($info, $('<div class="sm-mode-switch">').append($modeBtn), $mainToggle, $subOptions)); }); $body.append($container, $('<div class="sm-footer-actions">').append( $('<a>').attr({id: 'sm-common-js-btn', href: mw.util.getUrl('Special:MyPage/common.js'), target: '_blank'}).addClass('sm-btn').text('common.js を編集'), $('<button id="sm-save-btn">設定を保存して適用</button>').addClass('sm-btn').on('click', function() { var newSettings = {}; $('.sm-card').each(function() { var $c = $(this); var id = $c.find('.sm-master').attr('data-id'); newSettings[id] = { enabled: $c.find('.sm-master').is(':checked'), isBlacklistMode: $c.find('.sm-mode-toggle').text() === '制限ベース', onMain: $c.find('.sm-main').is(':checked'), onUser: $c.find('.sm-user').is(':checked'), onTalk: $c.find('.sm-talk').is(':checked'), onSpecial: $c.find('.sm-special').is(':checked'), onEdit: $c.find('.sm-edit').is(':checked'), onPreview: $c.find('.sm-preview').is(':checked'), onDiff: $c.find('.sm-diff').is(':checked') }; }); localStorage.setItem('wp-script-manager-v4', JSON.stringify(newSettings)); mw.notify('設定を保存しました。'); var returnUrl = document.referrer; setTimeout(function() { location.href = (returnUrl && returnUrl.indexOf(location.hostname) !== -1) ? returnUrl : mw.util.getUrl('Main_Page'); }, 800); }) )); } $(function() { // 1. 基本情報の取得 const pageName = mw.config.get('wgPageName').replace(/_/g, ' '); const action = mw.config.get('wgAction'); const userName = mw.config.get('wgUserName') const userNs = mw.config.get('wgFormattedNamespaces')[2]; const myCommonJs = userNs + ':' + userName + '/common.js'; const isJsPage = pageName.endsWith('.js'); const isManagerScript = pageName.endsWith('ScriptManager.js'); const isDiff = !!mw.config.get('wgDiffNewId'); // 2. 登録済み判定 function checkRegistration() { if (!window.scriptManagerList) return false; return window.scriptManagerList.some(script => { const savedTitle = (script.title || '').replace(/_/g, ' '); return savedTitle === pageName; }); } const isAlreadyRegistered = checkRegistration(); // --- 表示条件 --- // ・JSページである // ・現在のページが「自分のcommon.js」もしくは ScriptManager.jsでは表示しない。 // ・未登録である // ・閲覧モードかつ差分表示ではない // --- ボタンのデザイン変更(青い四角の箱) --- if (isJsPage && pageName !== myCommonJs && !isManagerScript && !isAlreadyRegistered && action === 'view' && !isDiff) { const $smInstallBtn = $('<button>') .text('ScriptManagerに追加') .addClass('mw-ui-button mw-ui-progressive') .css({ 'margin-left': '12px', 'vertical-align': 'middle', 'border-radius': '2px', 'padding': '0 12px', 'height': '32px', 'font-weight': 'bold', 'box-shadow': 'none' }) .on('click', function() { const scriptName = prompt('このスクリプトに名前をつけてください:', mw.config.get('wgTitle')); if (scriptName) { installScript(pageName, scriptName, $(this)); } }); $('#firstHeading').append($smInstallBtn); } // 3. common.js への追加処理 function installScript(targetPage, label, $button) { const api = new mw.Api(); // --- 1. ドメインと言語の判定ロジック(省略) --- const rawDomain = mw.config.get('wgServerName'); let lang = ''; let domain = rawDomain; const parts = rawDomain.split('.'); if (parts.length >= 3 && parts.slice(-2).join('.') === 'wikipedia.org') { lang = parts[0]; domain = 'wikipedia.org'; } if (domain === 'wikipedia.org') domain = ''; if (lang === 'ja') lang = ''; // --- 2. エントリとウィキリンクの作成(省略) --- let entryParts = [`name: '${label}'`]; if (lang !== '') entryParts.push(`lang: '${lang}'`); if (domain !== '') entryParts.push(`domain: '${domain}'`); entryParts.push(`title: '${targetPage}'`); let wikiLink = (domain !== '' && domain !== 'wikipedia.org') ? `[${location.protocol}//${rawDomain}/wiki/${encodeURI(targetPage)} ${targetPage}]` : `[[${(lang !== '' && lang !== 'ja') ? ':' + lang + ':' : ''}${targetPage}]]`; // --- 最終的な書き出し形式の組み立て --- // 1行目にコメント、2行目にオブジェクト(インデント付き) const newEntry = ` // ${wikiLink}\n { ${entryParts.join(', ')} },`; api.get({ action: 'query', prop: 'revisions', titles: myCommonJs, rvprop: 'content', rvslots: 'main' }).done(function(data) { const page = Object.values(data.query.pages)[0]; let content = (page && page.revisions) ? page.revisions[0].slots.main['*'] : ''; // --- 重複コードの検出と削除 (既存) --- const escapedPage = targetPage.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/[ _]/g, '[ _]'); const loadPattern = new RegExp(`(mw\\.loader\\.load|importScript)\\s*\\(\\s*['"\`].*?${escapedPage}.*?['"\`]\\s*\\);?`, 'g'); if (loadPattern.test(content)) { if (!confirm(`注意:common.js 内にこのスクリプトの既存の読み込みコードが見つかりました。\n\n「OK」:既存のコードを削除して移行します。\n「キャンセル」:中止します。`)) return; content = content.replace(loadPattern, '').replace(/\n{3,}/g, '\n\n'); } // --- コンテンツの更新 --- // 配列の開始位置のすぐ後ろに「コメント + オブジェクト」を挿入 if (content.includes('window.scriptManagerList = [')) { content = content.replace('window.scriptManagerList = [', `window.scriptManagerList = [\n${newEntry}`); } else { content = `window.scriptManagerList = [\n${newEntry}\n];\n\n` + content; } api.postWithToken('csrf', { action: 'edit', title: myCommonJs, text: content, summary: `${wikiLink} を ScriptManager に追加 (${label})` }).done(function(saveData) { if (saveData.edit && saveData.edit.result === 'Success') { mw.notify(label + ' を追加しました。'); $button.fadeOut(); if (!window.scriptManagerList) window.scriptManagerList = []; window.scriptManagerList.push({ name: label, lang: lang, domain: domain, title: targetPage }); } }); }); } }); })(jQuery, mediaWiki); 9acyucw2kpgce8hb1rxkrcutwpcsmw3 740996 740995 2026-05-08T13:38:53Z OUT is this 73801 740996 javascript text/javascript (function($, mw) { 'use strict'; // --- 1. スクリプト情報の整理 --- var rawList = window.scriptManagerList || []; var usedIds = {}; var scriptList = rawList.map(function(script) { var finalUrl = ''; // --- URL生成ロジック --- if (script.url) { finalUrl = script.url; } else { var langCode = (script.lang === undefined) ? 'ja' : script.lang; var langPrefix = (langCode !== '') ? langCode + '.' : ''; var domain = script.domain || 'wikipedia.org'; var title = script.title || ''; finalUrl = '//' + langPrefix + domain + '/w/index.php?title=' + encodeURIComponent(title) + '&action=raw&ctype=text/javascript'; } var match = finalUrl.match(/[?&]title=([^&]+)/); var pageTitle = match ? decodeURIComponent(match[1]) : 'Unknown'; var idBase = 'unknown'; if (match) { idBase = pageTitle .replace(/^(User|利用者):[^/]+\//i, '') .replace(/\.js$/i, '') .replace(/[ _ %]+/g, '_') .replace(/[^a-zA-Z0-9_]/g, ''); } var finalId = idBase; var counter = 2; while (usedIds[finalId]) { finalId = idBase + '_' + counter; counter++; } usedIds[finalId] = true; return { id: finalId, name: script.name, url: finalUrl, pageTitle: pageTitle }; }); // --- 2. 現在の状態の取得 --- var userSettings = JSON.parse(localStorage.getItem('wp-script-manager-v4') || '{}'); var pageName = mw.config.get('wgPageName').replace(/[ _ ]+/g, '').toLowerCase(); var action = mw.config.get('wgAction'); var ns = mw.config.get('wgNamespaceNumber'); var isDiff = !!mw.config.get('wgDiffNewId'); var isPreview = ['submit', 'preview'].indexOf(action) !== -1 && $('#wikiPreview').length > 0; var isMainNS = (ns === 0 || ns === 4); var isUserNS = (ns === 2 || ns === 3); var isTalkNS = (ns % 2 !== 0 && ns > 0); var isSpecialNS = (ns === -1); var isEditMode = (action === 'edit' || action === 'submit'); // --- 3. メニューへのリンク追加 --- $(function() { var smPageUrl = mw.util.getUrl('Special:SM'); var smLinks = $( ['', '-sticky-header'] .map(function(suffix) { var parentId = $('#p-user-menu-pages' + suffix).length ? 'p-user-menu-pages' : 'p-personal'; return mw.util.addPortletLink( parentId + suffix, smPageUrl, 'スクリプト管理画面', 'pt-scriptmanager' + suffix, 'Script Managerを開く', null, '#pt-logout' + suffix ); }) .filter(function(elOrNull) { return elOrNull !== null; }) ); if (smLinks.length > 0) { const style = ` li[id^="pt-scriptmanager"] a { width: auto !important; padding-left: 25px; white-space: nowrap; height: 20px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><path d="M20 10c0-.7-.1-1.3-.2-1.9l-2.3-.4c-.2-.7-.4-1.4-.8-2l1.4-1.9c-.5-.7-1.1-1.3-1.8-1.8l-1.9 1.4c-.6-.4-1.3-.6-2-.8l-.4-2.3c-.7-.1-1.3-.2-1.9-.2s-1.3.1-1.9.2l-.4 2.3c-.7.2-1.4.4-2 .8L4.1 2c-.7.5-1.3 1.1-1.8 1.8l1.4 1.9c-.4.6-.6 1.3-.8 2l-2.3.4c-.1.6-.2 1.2-.2 1.9s.1 1.3.2 1.9l2.3.4c.2.7.4 1.4.8 2l-1.4 1.9c.5.7 1.1 1.3 1.8 1.8l1.9-1.4c.6.4 1.3.6 2 .8l.4 2.3c.6.1 1.2.2 1.9.2s1.3-.1 1.9-.2l.4-2.3c.7-.2 1.4-.4 2-.8l1.9 1.4c.7-.5 1.3-1.1 1.8-1.8l-1.4-1.9c.4-.6.6-1.3.8-2l2.3-.4c.1-.6.2-1.2.2-1.9z" fill="%23202122"/><text x="10" y="13" font-family="sans-serif" font-weight="bold" font-size="8px" fill="white" text-anchor="middle">JS</text></svg>'); background-repeat: no-repeat; background-size: 20px 20px; background-position: center left; } `; $('<style>').text(style).appendTo('head'); } }); // --- 4. スクリプトのロード判定ロジック --- scriptList.forEach(function(script) { var s = userSettings[script.id]; if (!s || !s.enabled) return; var shouldLoad = false; if (s.isBlacklistMode) { var blocked = false; if (isDiff && !s.onDiff) blocked = true; else if (isPreview && !s.onPreview) blocked = true; else if (isEditMode && !s.onEdit) blocked = true; else if (action === 'view' && !isDiff) { if (isMainNS && !s.onMain) blocked = true; else if (isUserNS && !s.onUser) blocked = true; else if (isTalkNS && !s.onTalk) blocked = true; else if (isSpecialNS && !s.onSpecial) blocked = true; } shouldLoad = !blocked; } else { if (isDiff && s.onDiff) shouldLoad = true; else if (isPreview && s.onPreview) shouldLoad = true; else if (isEditMode && s.onEdit) shouldLoad = true; else if (action === 'view' && !isDiff) { if (isMainNS && s.onMain) shouldLoad = true; else if (isUserNS && s.onUser) shouldLoad = true; else if (isTalkNS && s.onTalk) shouldLoad = true; else if (isSpecialNS && s.onSpecial) shouldLoad = true; } } if (shouldLoad) mw.loader.load(script.url); }); // --- 5. 管理画面(Special:SM)の構築 --- if (/^(special|特別):(scriptmanager|sm)$/i.test(pageName)) { document.title = 'Script Manager'; $('#firstHeading').text('Script Manager'); var $body = $('#mw-content-text').empty(); $('<style>').text(` /* --- 基本レイアウト --- */ #sm-container { font-family: sans-serif; color: #202122; max-width: 1000px; margin: 20px 0; } .sm-card { background: #fff; border: 1px solid #c8ccd1; border-left: 5px solid #36c; border-radius: 8px; padding: 14px; margin-bottom: 16px; display: flex; align-items: center; transition: all 0.3s ease; } .sm-info { flex-grow: 1; min-width: 160px; overflow: hidden; margin-right: 10px; } .sm-name { font-weight: bold; font-size: 1.1em; display: flex; align-items: center; color: #202122; } .sm-status-badge { font-size: 10px; padding: 2px 6px; border-radius: 10px; margin-left: 10px; text-transform: uppercase; border: 1px solid #c8ccd1; background: #f8f9fa; color: #72777d; } .status-on { background: #eaf3ff; color: #36c; border-color: #36c; } /* --- チェックボックス共通設定 --- */ .sm-checkbox-label { display: flex; flex-direction: column; align-items: center; font-size: 0.75em; color: #202122; cursor: pointer; min-width: 46px; text-align: center; } .sm-checkbox-label input { margin-bottom: 4px; cursor: pointer; opacity: 1 !important; } /* カードが無効でも不透明度を下げない(重要) */ .sm-card.disabled { background: #f8f9fa !important; border-left-color: #72777d; opacity: 1 !important; filter: none !important; } /* --- 1. メイン(有効)スイッチ:カスタム黒縁 --- */ .sm-master { appearance: none; -webkit-appearance: none; width: 18px; height: 18px; border: 2px solid #000 !important; border-radius: 3px; background-color: #fff; position: relative; vertical-align: middle; } .sm-master:checked { background-color: #36c !important; border-color: #36c !important; } .sm-master:checked::after { content: ""; position: absolute; left: 4px; top: 0px; width: 5px; height: 10px; border: solid white; border-width: 0 2px 2px 0; transform: rotate(45deg); } /* --- 2. サブチェックボックス:標準ブラウザ --- */ .sm-sub-checkbox { appearance: auto; -webkit-appearance: auto; width: 13px; height: 13px; } /* ブラックリスト/無効時の赤い×印 */ .mode-bl-active .sm-sub-checkbox:not(:checked) { appearance: none; -webkit-appearance: none; border: 1px solid #d33; background: #d33; position: relative; border-radius: 2px; width: 13px; height: 13px; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after, .mode-bl-active .sm-sub-checkbox:not(:checked)::before { content: ''; position: absolute; width: 8px; height: 1.5px; background-color: white; top: 50%; left: 50%; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after { transform: translate(-50%, -50%) rotate(45deg); } .mode-bl-active .sm-sub-checkbox:not(:checked)::before { transform: translate(-50%, -50%) rotate(-45deg); } /* 案内用・フッター */ .sm-guide-box { background: #f8f9fa; border: 1px dashed #a2a9b1; padding: 20px; border-radius: 8px; text-align: center; margin: 20px 0; } .sm-step { display: inline-block; text-align: left; margin: 10px 0; vertical-align: top; width: 250px; padding: 10px; } .sm-footer-actions { position: sticky; bottom: 20px; float: right; display: flex; gap: 10px; z-index: 100; } .sm-btn { border: none; padding: 12px 24px; border-radius: 4px; font-weight: bold; cursor: pointer; text-decoration: none; display: inline-block; } #sm-save-btn { background: #36c; color: #fff; } `).appendTo('head'); var $container = $('<div id="sm-container"></div>'); if (scriptList.length === 0) { var manualUrl = 'https://ja.wikipedia.org/wiki/' + encodeURIComponent('利用者:OUT_is_this/ScriptManager'); $container.append(` <div class="sm-guide-box"> <h3>スクリプトが登録されていません</h3> <p>以下の手順でスクリプトを追加してください:</p> <div class="sm-step"><b>1. 探す</b><br>ScriptManagerに登録したいスクリプトの <code>.js</code> ページを開きます。</div> <div class="sm-step"><b>2. 追加する</b><br>ページ上部の「ScriptManagerに追加」ボタンを押します。</div> <div class="sm-step"><b>3. 保存</b><br>名前を付けて保存すると common.js に書き込まれます。</div> <div style="margin-top:20px; padding-top:15px; border-top:1px solid #eaecf0;"> <a href="${manualUrl}" target="_blank" style="font-weight:bold; color:#36c;">詳しい使い方はこちら(解説ページ)</a> </div> </div> `); } scriptList.forEach(function(script) { var s = userSettings[script.id] || { enabled: false, isBlacklistMode: false, onMain: true, onUser: true, onTalk: true, onSpecial: true, onEdit: true, onPreview: true, onDiff: true }; var $card = $('<div class="sm-card">').toggleClass('disabled', !s.enabled); if (s.isBlacklistMode) $card.addClass('mode-bl-active'); var $status = $('<span class="sm-status-badge"></span>').addClass(s.enabled ? 'status-on' : '').text(s.enabled ? 'ON' : 'OFF'); var viewUrl = script.url.replace(/[?&]action=raw/, '').replace(/[?&]ctype=[^&]+/, ''); var $info = $('<div class="sm-info">').append( $('<div class="sm-name">').text(script.name).append($status), $('<div class="sm-id-row" style="font-size:0.85em; color:#72777d;">').append( $('<span>').text(script.id + ' '), $('<a>').attr({href: viewUrl, target: '_blank'}).text('⇨ ' + script.pageTitle) ) ); var $modeBtn = $('<button class="sm-btn" style="padding:4px 8px; font-size:0.85em; margin-right:15px;">').text(s.isBlacklistMode ? '制限ベース' : '許可ベース'); $modeBtn.on('click', function() { var isBl = $(this).text() === '許可ベース'; $(this).text(isBl ? '制限ベース' : '許可ベース'); $card.toggleClass('mode-bl-active', isBl); }); var $masterCheck = $('<input type="checkbox" class="sm-master">') .prop('checked', s.enabled) .attr('data-id', script.id); var $mainToggle = $('<div class="sm-main-toggle" style="border-right: 1px solid #eaecf0; padding-right:10px; margin-right:10px;">').append( $('<label class="sm-checkbox-label" style="font-weight:bold;">').append($masterCheck, '有効') ); function createOption(label, key, val) { var $input = $('<input type="checkbox" class="sm-sub-checkbox">') .addClass('sm-' + key) .prop('checked', val); return $('<label class="sm-checkbox-label">').append($input, label); } var $subOptions = $('<div class="sm-sub-options" style="display:flex; gap:8px;">').append( createOption('記事/WP', 'main', s.onMain), createOption('利用者', 'user', s.onUser), createOption('ノート', 'talk', s.onTalk), createOption('特別', 'special', s.onSpecial), createOption('編集', 'edit', s.onEdit), createOption('プレビュー', 'preview', s.onPreview), createOption('差分', 'diff', s.onDiff) ); $masterCheck.on('change', function() { var checked = $(this).is(':checked'); $card.toggleClass('disabled', !checked); $card.find('.sm-status-badge').toggleClass('status-on', checked).text(checked ? 'ON' : 'OFF'); }); $container.append($card.append($info, $modeBtn, $mainToggle, $subOptions)); }); $body.append($container, $('<div class="sm-footer-actions">').append( $('<a>').attr({href: mw.util.getUrl('Special:MyPage/common.js'), target: '_blank'}).addClass('sm-btn').text('common.js を編集'), $('<button id="sm-save-btn">設定を保存して適用</button>').addClass('sm-btn').on('click', function() { var newSettings = {}; $('.sm-card').each(function() { var $c = $(this); var id = $c.find('.sm-master').attr('data-id'); newSettings[id] = { enabled: $c.find('.sm-master').is(':checked'), isBlacklistMode: $c.find('button.sm-btn').first().text() === '制限ベース', onMain: $c.find('.sm-main').is(':checked'), onUser: $c.find('.sm-user').is(':checked'), onTalk: $c.find('.sm-talk').is(':checked'), onSpecial: $c.find('.sm-special').is(':checked'), onEdit: $c.find('.sm-edit').is(':checked'), onPreview: $c.find('.sm-preview').is(':checked'), onDiff: $c.find('.sm-diff').is(':checked') }; }); localStorage.setItem('wp-script-manager-v4', JSON.stringify(newSettings)); mw.notify('設定を保存しました。'); setTimeout(function() { location.href = mw.util.getUrl('Main_Page'); }, 800); }) )); } $(function() { // 1. 基本情報の取得 const pageName = mw.config.get('wgPageName').replace(/_/g, ' '); const action = mw.config.get('wgAction'); const userName = mw.config.get('wgUserName') const userNs = mw.config.get('wgFormattedNamespaces')[2]; const myCommonJs = userNs + ':' + userName + '/common.js'; const isJsPage = pageName.endsWith('.js'); const isManagerScript = pageName.endsWith('ScriptManager.js'); const isDiff = !!mw.config.get('wgDiffNewId'); // 2. 登録済み判定 function checkRegistration() { if (!window.scriptManagerList) return false; return window.scriptManagerList.some(script => { const savedTitle = (script.title || '').replace(/_/g, ' '); return savedTitle === pageName; }); } const isAlreadyRegistered = checkRegistration(); // --- 表示条件 --- // ・JSページである // ・現在のページが「自分のcommon.js」もしくは ScriptManager.jsでは表示しない。 // ・未登録である // ・閲覧モードかつ差分表示ではない // --- ボタンのデザイン変更(青い四角の箱) --- if (isJsPage && pageName !== myCommonJs && !isManagerScript && !isAlreadyRegistered && action === 'view' && !isDiff) { const $smInstallBtn = $('<button>') .text('ScriptManagerに追加') .addClass('mw-ui-button mw-ui-progressive') .css({ 'margin-left': '12px', 'vertical-align': 'middle', 'border-radius': '2px', 'padding': '0 12px', 'height': '32px', 'font-weight': 'bold', 'box-shadow': 'none' }) .on('click', function() { const scriptName = prompt('このスクリプトに名前をつけてください:', mw.config.get('wgTitle')); if (scriptName) { installScript(pageName, scriptName, $(this)); } }); $('#firstHeading').append($smInstallBtn); } // 3. common.js への追加処理 function installScript(targetPage, label, $button) { const api = new mw.Api(); // --- 1. ドメインと言語の判定ロジック(省略) --- const rawDomain = mw.config.get('wgServerName'); let lang = ''; let domain = rawDomain; const parts = rawDomain.split('.'); if (parts.length >= 3 && parts.slice(-2).join('.') === 'wikipedia.org') { lang = parts[0]; domain = 'wikipedia.org'; } if (domain === 'wikipedia.org') domain = ''; if (lang === 'ja') lang = ''; // --- 2. エントリとウィキリンクの作成(省略) --- let entryParts = [`name: '${label}'`]; if (lang !== '') entryParts.push(`lang: '${lang}'`); if (domain !== '') entryParts.push(`domain: '${domain}'`); entryParts.push(`title: '${targetPage}'`); let wikiLink = (domain !== '' && domain !== 'wikipedia.org') ? `[${location.protocol}//${rawDomain}/wiki/${encodeURI(targetPage)} ${targetPage}]` : `[[${(lang !== '' && lang !== 'ja') ? ':' + lang + ':' : ''}${targetPage}]]`; // --- 最終的な書き出し形式の組み立て --- // 1行目にコメント、2行目にオブジェクト(インデント付き) const newEntry = ` // ${wikiLink}\n { ${entryParts.join(', ')} },`; api.get({ action: 'query', prop: 'revisions', titles: myCommonJs, rvprop: 'content', rvslots: 'main' }).done(function(data) { const page = Object.values(data.query.pages)[0]; let content = (page && page.revisions) ? page.revisions[0].slots.main['*'] : ''; // --- 重複コードの検出と削除 (既存) --- const escapedPage = targetPage.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/[ _]/g, '[ _]'); const loadPattern = new RegExp(`(mw\\.loader\\.load|importScript)\\s*\\(\\s*['"\`].*?${escapedPage}.*?['"\`]\\s*\\);?`, 'g'); if (loadPattern.test(content)) { if (!confirm(`注意:common.js 内にこのスクリプトの既存の読み込みコードが見つかりました。\n\n「OK」:既存のコードを削除して移行します。\n「キャンセル」:中止します。`)) return; content = content.replace(loadPattern, '').replace(/\n{3,}/g, '\n\n'); } // --- コンテンツの更新 --- // 配列の開始位置のすぐ後ろに「コメント + オブジェクト」を挿入 if (content.includes('window.scriptManagerList = [')) { content = content.replace('window.scriptManagerList = [', `window.scriptManagerList = [\n${newEntry}`); } else { content = `window.scriptManagerList = [\n${newEntry}\n];\n\n` + content; } api.postWithToken('csrf', { action: 'edit', title: myCommonJs, text: content, summary: `${wikiLink} を ScriptManager に追加 (${label})` }).done(function(saveData) { if (saveData.edit && saveData.edit.result === 'Success') { mw.notify(label + ' を追加しました。'); $button.fadeOut(); if (!window.scriptManagerList) window.scriptManagerList = []; window.scriptManagerList.push({ name: label, lang: lang, domain: domain, title: targetPage }); } }); }); } }); })(jQuery, mediaWiki); ahj45d00fgf91xg6g9m1g3dc6e0ss3h 740997 740996 2026-05-08T13:39:37Z OUT is this 73801 740997 javascript text/javascript (function($, mw) { 'use strict'; // --- 1. スクリプト情報の整理 --- var rawList = window.scriptManagerList || []; var usedIds = {}; var scriptList = rawList.map(function(script) { var finalUrl = ''; // --- URL生成ロジック --- if (script.url) { finalUrl = script.url; } else { var langCode = (script.lang === undefined) ? 'ja' : script.lang; var langPrefix = (langCode !== '') ? langCode + '.' : ''; var domain = script.domain || 'wikipedia.org'; var title = script.title || ''; finalUrl = '//' + langPrefix + domain + '/w/index.php?title=' + encodeURIComponent(title) + '&action=raw&ctype=text/javascript'; } var match = finalUrl.match(/[?&]title=([^&]+)/); var pageTitle = match ? decodeURIComponent(match[1]) : 'Unknown'; var idBase = 'unknown'; if (match) { idBase = pageTitle .replace(/^(User|利用者):[^/]+\//i, '') .replace(/\.js$/i, '') .replace(/[ _ %]+/g, '_') .replace(/[^a-zA-Z0-9_]/g, ''); } var finalId = idBase; var counter = 2; while (usedIds[finalId]) { finalId = idBase + '_' + counter; counter++; } usedIds[finalId] = true; return { id: finalId, name: script.name, url: finalUrl, pageTitle: pageTitle }; }); // --- 2. 現在の状態の取得 --- var userSettings = JSON.parse(localStorage.getItem('wp-script-manager-v4') || '{}'); var pageName = mw.config.get('wgPageName').replace(/[ _ ]+/g, '').toLowerCase(); var action = mw.config.get('wgAction'); var ns = mw.config.get('wgNamespaceNumber'); var isDiff = !!mw.config.get('wgDiffNewId'); var isPreview = ['submit', 'preview'].indexOf(action) !== -1 && $('#wikiPreview').length > 0; var isMainNS = (ns === 0 || ns === 4); var isUserNS = (ns === 2 || ns === 3); var isTalkNS = (ns % 2 !== 0 && ns > 0); var isSpecialNS = (ns === -1); var isEditMode = (action === 'edit' || action === 'submit'); // --- 3. メニューへのリンク追加 --- $(function() { var smPageUrl = mw.util.getUrl('Special:SM'); var smLinks = $( ['', '-sticky-header'] .map(function(suffix) { var parentId = $('#p-user-menu-pages' + suffix).length ? 'p-user-menu-pages' : 'p-personal'; return mw.util.addPortletLink( parentId + suffix, smPageUrl, 'スクリプト管理画面', 'pt-scriptmanager' + suffix, 'Script Managerを開く', null, '#pt-logout' + suffix ); }) .filter(function(elOrNull) { return elOrNull !== null; }) ); if (smLinks.length > 0) { const style = ` li[id^="pt-scriptmanager"] a { width: auto !important; padding-left: 25px; white-space: nowrap; height: 20px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><path d="M20 10c0-.7-.1-1.3-.2-1.9l-2.3-.4c-.2-.7-.4-1.4-.8-2l1.4-1.9c-.5-.7-1.1-1.3-1.8-1.8l-1.9 1.4c-.6-.4-1.3-.6-2-.8l-.4-2.3c-.7-.1-1.3-.2-1.9-.2s-1.3.1-1.9.2l-.4 2.3c-.7.2-1.4.4-2 .8L4.1 2c-.7.5-1.3 1.1-1.8 1.8l1.4 1.9c-.4.6-.6 1.3-.8 2l-2.3.4c-.1.6-.2 1.2-.2 1.9s.1 1.3.2 1.9l2.3.4c.2.7.4 1.4.8 2l-1.4 1.9c.5.7 1.1 1.3 1.8 1.8l1.9-1.4c.6.4 1.3.6 2 .8l.4 2.3c.6.1 1.2.2 1.9.2s1.3-.1 1.9-.2l.4-2.3c.7-.2 1.4-.4 2-.8l1.9 1.4c.7-.5 1.3-1.1 1.8-1.8l-1.4-1.9c.4-.6.6-1.3.8-2l2.3-.4c.1-.6.2-1.2.2-1.9z" fill="%23202122"/><text x="10" y="13" font-family="sans-serif" font-weight="bold" font-size="8px" fill="white" text-anchor="middle">JS</text></svg>'); background-repeat: no-repeat; background-size: 20px 20px; background-position: center left; } `; $('<style>').text(style).appendTo('head'); } }); // --- 4. スクリプトのロード判定ロジック --- scriptList.forEach(function(script) { var s = userSettings[script.id]; if (!s || !s.enabled) return; var shouldLoad = false; if (s.isBlacklistMode) { var blocked = false; if (isDiff && !s.onDiff) blocked = true; else if (isPreview && !s.onPreview) blocked = true; else if (isEditMode && !s.onEdit) blocked = true; else if (action === 'view' && !isDiff) { if (isMainNS && !s.onMain) blocked = true; else if (isUserNS && !s.onUser) blocked = true; else if (isTalkNS && !s.onTalk) blocked = true; else if (isSpecialNS && !s.onSpecial) blocked = true; } shouldLoad = !blocked; } else { if (isDiff && s.onDiff) shouldLoad = true; else if (isPreview && s.onPreview) shouldLoad = true; else if (isEditMode && s.onEdit) shouldLoad = true; else if (action === 'view' && !isDiff) { if (isMainNS && s.onMain) shouldLoad = true; else if (isUserNS && s.onUser) shouldLoad = true; else if (isTalkNS && s.onTalk) shouldLoad = true; else if (isSpecialNS && s.onSpecial) shouldLoad = true; } } if (shouldLoad) mw.loader.load(script.url); }); // --- 5. 管理画面(Special:SM)の構築 --- if (/^(special|特別):(scriptmanager|sm)$/i.test(pageName)) { document.title = 'Script Manager'; $('#firstHeading').text('Script Manager'); var $body = $('#mw-content-text').empty(); $('<style>').text(` #sm-container { font-family: sans-serif; color: #202122; max-width: 1000px; margin: 20px 0; } .sm-card { background: #fff; border: 1px solid #c8ccd1; border-left: 5px solid #36c; border-radius: 8px; padding: 14px; margin-bottom: 16px; display: flex; align-items: center; transition: all 0.3s ease; } .sm-info { flex-grow: 1; min-width: 160px; overflow: hidden; margin-right: 10px; } .sm-name { font-weight: bold; font-size: 1.1em; display: flex; align-items: center; color: #202122; } .sm-id-row { font-size: 0.8em; color: #72777d; font-family: monospace; margin-top: 4px; display: flex; align-items: center; gap: 8px; } .sm-js-link { color: #36c; text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 250px; border-bottom: 1px solid transparent; } .sm-js-link:hover { border-bottom-color: #36c; } .sm-status-badge { font-size: 10px; padding: 2px 6px; border-radius: 10px; margin-left: 10px; text-transform: uppercase; border: 1px solid #c8ccd1; background: #f8f9fa; color: #72777d; } .status-on { background: #eaf3ff; color: #36c; border-color: #36c; } .sm-mode-switch { padding: 0 10px; border-right: 1px solid #eaecf0; margin-right: 10px; text-align: center; } .sm-mode-toggle { border: 1px solid #a2a9b1; border-radius: 4px; padding: 4px 8px; cursor: pointer; font-size: 10.5px; background: #fff; color: #202122; white-space: nowrap; } .sm-main-toggle { border-right: 2px solid #eaecf0; padding-right: 10px; margin-right: 10px; flex-shrink: 0; } .sm-sub-options { display: flex; gap: 8px; flex-wrap: wrap; flex-shrink: 0; } .sm-checkbox-label { display: flex; flex-direction: column; align-items: center; font-size: 0.75em; color: #54595d; cursor: pointer; min-width: 46px; text-align: center; } .sm-checkbox-label input { margin-bottom: 4px; cursor: pointer; } .mode-bl-active .sm-sub-checkbox:not(:checked) { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #d33; background: #d33; position: relative; border-radius: 2px; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after, .mode-bl-active .sm-sub-checkbox:not(:checked)::before { content: ''; position: absolute; width: 10px; height: 1.8px; background-color: white; top: 50%; left: 50%; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after { transform: translate(-50%, -50%) rotate(45deg); } .mode-bl-active .sm-sub-checkbox:not(:checked)::before { transform: translate(-50%, -50%) rotate(-45deg); } .mode-bl-active .sm-sub-checkbox:checked { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #a2a9b1; border-radius: 2px; background: #fff; } .mode-bl-active { border-left-color: #d33 !important; } .mode-bl-active .status-on { background: #fee7e6; color: #d33; border-color: #d33; } .sm-card.disabled { background: #f8f9fa !important; opacity: 0.6; filter: grayscale(1); } .sm-footer-actions { position: sticky; bottom: 20px; float: right; display: flex; gap: 10px; z-index: 100; } .sm-btn { border: none; padding: 12px 24px; border-radius: 4px; font-weight: bold; cursor: pointer; transition: background 0.2s; } #sm-save-btn { background: #36c; color: #fff; } #sm-common-js-btn { background: #f8f9fa; color: #202122; border: 1px solid #a2a9b1; text-decoration: none; font-size: 0.95em; display: flex; align-items: center; } /* 管理スクリプトがない時の案内用スタイル */ .sm-guide-box { background: #f8f9fa; border: 1px dashed #a2a9b1; padding: 20px; border-radius: 8px; text-align: center; margin: 20px 0; } .sm-guide-box h3 { margin-top: 0; } .sm-step { display: inline-block; text-align: left; margin: 10px 0; vertical-align: top; width: 250px; padding: 10px; } `).appendTo('head'); var $container = $('<div id="sm-container"></div>'); if (scriptList.length === 0) { var manualUrl = 'https://ja.wikipedia.org/wiki/' + encodeURIComponent('利用者:OUT_is_this/ScriptManager'); $container.append(` <div class="sm-guide-box"> <h3>スクリプトが登録されていません</h3> <p>以下の手順でスクリプトを追加してください:</p> <div class="sm-step"><b>1. 探す</b><br>ScriptManagerに登録したいスクリプトが置いてある <code>.js</code> ページを開きます。</div> <div class="sm-step"><b>2. 追加する</b><br>ページ上部の「ScriptManagerに追加」ボタンを押します。</div> <div class="sm-step"><b>3. 保存</b><br>名前を付けて保存すると自動で common.js に書き込まれます。</div> <div style="margin-top:20px; padding-top:15px; border-top:1px solid #eaecf0; text-align:center;"> <div style="display:inline-flex; align-items:flex-start; color:#202122;"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 20 20" style="flex-shrink:0; margin-right:8px; margin-top:4px;"> <path d="M10 0C4.48 0 0 4.48 0 10s4.48 10 10 10 10-4.48 10-10S15.52 0 10 0zm0 15c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1s1 .45 1 1v4c0 .55-.45 1-1 1zm1-8H9V5h2v2z" fill="#36c"/> </svg> <span style="line-height:1.8; text-align:center; display:block;"> common.js に手入力で直接書き込む方法や、他ドメインにある js の登録方法、その他詳しい使い方などは<br> <a href="${manualUrl}" target="_blank" style="font-weight:bold; text-decoration:none; color:#36c;">こちら(解説ページ)</a>をご覧ください。 </span> </div> </div> </div> `); } scriptList.forEach(function(script) { var s = userSettings[script.id] || { enabled: false, isBlacklistMode: false, onMain: true, onUser: true, onTalk: true, onSpecial: true, onEdit: true, onPreview: true, onDiff: true }; var $card = $('<div class="sm-card">').toggleClass('disabled', !s.enabled); if (s.isBlacklistMode) $card.addClass('mode-bl-active'); var $status = $('<span class="sm-status-badge"></span>').addClass(s.enabled ? 'status-on' : '').text(s.enabled ? 'ON' : 'OFF'); var viewUrl = script.url.replace(/[?&]action=raw/, '').replace(/[?&]ctype=[^&]+/, ''); var $info = $('<div class="sm-info">').append( $('<div class="sm-name">').text(script.name).append($status), $('<div class="sm-id-row">').append( $('<span>').text(script.id), $('<a>').attr({href: viewUrl, target: '_blank', title: script.pageTitle}) .addClass('sm-js-link').text('⇨ ' + script.pageTitle) ) ); var $modeBtn = $('<div class="sm-mode-toggle">').text(s.isBlacklistMode ? '制限ベース' : '許可ベース'); $modeBtn.on('click', function() { var isBl = $(this).text() === '許可ベース'; $(this).text(isBl ? '制限ベース' : '許可ベース'); $card.toggleClass('mode-bl-active', isBl); }); var $mainToggle = $('<div class="sm-main-toggle">').append( $('<label class="sm-checkbox-label">').append($('<input type="checkbox" class="sm-master">').prop('checked', s.enabled).attr('data-id', script.id), '<b>有効</b>') ); function createOption(label, key, val) { var $input = $('<input type="checkbox" class="sm-sub-checkbox">').addClass('sm-' + key).prop('checked', val); return $('<label class="sm-checkbox-label">').append($input, label); } var $subOptions = $('<div class="sm-sub-options">').append( createOption('記事/WP', 'main', s.onMain), createOption('利用者', 'user', s.onUser), createOption('ノート', 'talk', s.onTalk), createOption('特別', 'special', s.onSpecial), createOption('編集', 'edit', s.onEdit), createOption('プレビュー', 'preview', s.onPreview), createOption('差分', 'diff', s.onDiff) ); $mainToggle.find('.sm-master').on('change', function() { var checked = $(this).is(':checked'); $card.toggleClass('disabled', !checked); $card.find('.sm-status-badge').toggleClass('status-on', checked).text(checked ? 'ON' : 'OFF'); }); $container.append($card.append($info, $('<div class="sm-mode-switch">').append($modeBtn), $mainToggle, $subOptions)); }); $body.append($container, $('<div class="sm-footer-actions">').append( $('<a>').attr({id: 'sm-common-js-btn', href: mw.util.getUrl('Special:MyPage/common.js'), target: '_blank'}).addClass('sm-btn').text('common.js を編集'), $('<button id="sm-save-btn">設定を保存して適用</button>').addClass('sm-btn').on('click', function() { var newSettings = {}; $('.sm-card').each(function() { var $c = $(this); var id = $c.find('.sm-master').attr('data-id'); newSettings[id] = { enabled: $c.find('.sm-master').is(':checked'), isBlacklistMode: $c.find('.sm-mode-toggle').text() === '制限ベース', onMain: $c.find('.sm-main').is(':checked'), onUser: $c.find('.sm-user').is(':checked'), onTalk: $c.find('.sm-talk').is(':checked'), onSpecial: $c.find('.sm-special').is(':checked'), onEdit: $c.find('.sm-edit').is(':checked'), onPreview: $c.find('.sm-preview').is(':checked'), onDiff: $c.find('.sm-diff').is(':checked') }; }); localStorage.setItem('wp-script-manager-v4', JSON.stringify(newSettings)); mw.notify('設定を保存しました。'); var returnUrl = document.referrer; setTimeout(function() { location.href = (returnUrl && returnUrl.indexOf(location.hostname) !== -1) ? returnUrl : mw.util.getUrl('Main_Page'); }, 800); }) )); } $(function() { // 1. 基本情報の取得 const pageName = mw.config.get('wgPageName').replace(/_/g, ' '); const action = mw.config.get('wgAction'); const userName = mw.config.get('wgUserName') const userNs = mw.config.get('wgFormattedNamespaces')[2]; const myCommonJs = userNs + ':' + userName + '/common.js'; const isJsPage = pageName.endsWith('.js'); const isManagerScript = pageName.endsWith('ScriptManager.js'); const isDiff = !!mw.config.get('wgDiffNewId'); // 2. 登録済み判定 function checkRegistration() { if (!window.scriptManagerList) return false; return window.scriptManagerList.some(script => { const savedTitle = (script.title || '').replace(/_/g, ' '); return savedTitle === pageName; }); } const isAlreadyRegistered = checkRegistration(); // --- 表示条件 --- // ・JSページである // ・現在のページが「自分のcommon.js」もしくは ScriptManager.jsでは表示しない。 // ・未登録である // ・閲覧モードかつ差分表示ではない // --- ボタンのデザイン変更(青い四角の箱) --- if (isJsPage && pageName !== myCommonJs && !isManagerScript && !isAlreadyRegistered && action === 'view' && !isDiff) { const $smInstallBtn = $('<button>') .text('ScriptManagerに追加') .addClass('mw-ui-button mw-ui-progressive') .css({ 'margin-left': '12px', 'vertical-align': 'middle', 'border-radius': '2px', 'padding': '0 12px', 'height': '32px', 'font-weight': 'bold', 'box-shadow': 'none' }) .on('click', function() { const scriptName = prompt('このスクリプトに名前をつけてください:', mw.config.get('wgTitle')); if (scriptName) { installScript(pageName, scriptName, $(this)); } }); $('#firstHeading').append($smInstallBtn); } // 3. common.js への追加処理 function installScript(targetPage, label, $button) { const api = new mw.Api(); // --- 1. ドメインと言語の判定ロジック(省略) --- const rawDomain = mw.config.get('wgServerName'); let lang = ''; let domain = rawDomain; const parts = rawDomain.split('.'); if (parts.length >= 3 && parts.slice(-2).join('.') === 'wikipedia.org') { lang = parts[0]; domain = 'wikipedia.org'; } if (domain === 'wikipedia.org') domain = ''; if (lang === 'ja') lang = ''; // --- 2. エントリとウィキリンクの作成(省略) --- let entryParts = [`name: '${label}'`]; if (lang !== '') entryParts.push(`lang: '${lang}'`); if (domain !== '') entryParts.push(`domain: '${domain}'`); entryParts.push(`title: '${targetPage}'`); let wikiLink = (domain !== '' && domain !== 'wikipedia.org') ? `[${location.protocol}//${rawDomain}/wiki/${encodeURI(targetPage)} ${targetPage}]` : `[[${(lang !== '' && lang !== 'ja') ? ':' + lang + ':' : ''}${targetPage}]]`; // --- 最終的な書き出し形式の組み立て --- // 1行目にコメント、2行目にオブジェクト(インデント付き) const newEntry = ` // ${wikiLink}\n { ${entryParts.join(', ')} },`; api.get({ action: 'query', prop: 'revisions', titles: myCommonJs, rvprop: 'content', rvslots: 'main' }).done(function(data) { const page = Object.values(data.query.pages)[0]; let content = (page && page.revisions) ? page.revisions[0].slots.main['*'] : ''; // --- 重複コードの検出と削除 (既存) --- const escapedPage = targetPage.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/[ _]/g, '[ _]'); const loadPattern = new RegExp(`(mw\\.loader\\.load|importScript)\\s*\\(\\s*['"\`].*?${escapedPage}.*?['"\`]\\s*\\);?`, 'g'); if (loadPattern.test(content)) { if (!confirm(`注意:common.js 内にこのスクリプトの既存の読み込みコードが見つかりました。\n\n「OK」:既存のコードを削除して移行します。\n「キャンセル」:中止します。`)) return; content = content.replace(loadPattern, '').replace(/\n{3,}/g, '\n\n'); } // --- コンテンツの更新 --- // 配列の開始位置のすぐ後ろに「コメント + オブジェクト」を挿入 if (content.includes('window.scriptManagerList = [')) { content = content.replace('window.scriptManagerList = [', `window.scriptManagerList = [\n${newEntry}`); } else { content = `window.scriptManagerList = [\n${newEntry}\n];\n\n` + content; } api.postWithToken('csrf', { action: 'edit', title: myCommonJs, text: content, summary: `${wikiLink} を ScriptManager に追加 (${label})` }).done(function(saveData) { if (saveData.edit && saveData.edit.result === 'Success') { mw.notify(label + ' を追加しました。'); $button.fadeOut(); if (!window.scriptManagerList) window.scriptManagerList = []; window.scriptManagerList.push({ name: label, lang: lang, domain: domain, title: targetPage }); } }); }); } }); })(jQuery, mediaWiki); nxtghmrssih0ib5j5bu0zoozv67kjn8 740998 740997 2026-05-08T13:42:53Z OUT is this 73801 740998 javascript text/javascript (function($, mw) { 'use strict'; // --- 1. スクリプト情報の整理 --- var rawList = window.scriptManagerList || []; var usedIds = {}; var scriptList = rawList.map(function(script) { var finalUrl = ''; // --- URL生成ロジック --- if (script.url) { finalUrl = script.url; } else { var langCode = (script.lang === undefined) ? 'ja' : script.lang; var langPrefix = (langCode !== '') ? langCode + '.' : ''; var domain = script.domain || 'wikipedia.org'; var title = script.title || ''; finalUrl = '//' + langPrefix + domain + '/w/index.php?title=' + encodeURIComponent(title) + '&action=raw&ctype=text/javascript'; } var match = finalUrl.match(/[?&]title=([^&]+)/); var pageTitle = match ? decodeURIComponent(match[1]) : 'Unknown'; var idBase = 'unknown'; if (match) { idBase = pageTitle .replace(/^(User|利用者):[^/]+\//i, '') .replace(/\.js$/i, '') .replace(/[ _ %]+/g, '_') .replace(/[^a-zA-Z0-9_]/g, ''); } var finalId = idBase; var counter = 2; while (usedIds[finalId]) { finalId = idBase + '_' + counter; counter++; } usedIds[finalId] = true; return { id: finalId, name: script.name, url: finalUrl, pageTitle: pageTitle }; }); // --- 2. 現在の状態の取得 --- var userSettings = JSON.parse(localStorage.getItem('wp-script-manager-v4') || '{}'); var pageName = mw.config.get('wgPageName').replace(/[ _ ]+/g, '').toLowerCase(); var action = mw.config.get('wgAction'); var ns = mw.config.get('wgNamespaceNumber'); var isDiff = !!mw.config.get('wgDiffNewId'); var isPreview = ['submit', 'preview'].indexOf(action) !== -1 && $('#wikiPreview').length > 0; var isMainNS = (ns === 0 || ns === 4); var isUserNS = (ns === 2 || ns === 3); var isTalkNS = (ns % 2 !== 0 && ns > 0); var isSpecialNS = (ns === -1); var isEditMode = (action === 'edit' || action === 'submit'); // --- 3. メニューへのリンク追加 --- $(function() { var smPageUrl = mw.util.getUrl('Special:SM'); var smLinks = $( ['', '-sticky-header'] .map(function(suffix) { var parentId = $('#p-user-menu-pages' + suffix).length ? 'p-user-menu-pages' : 'p-personal'; return mw.util.addPortletLink( parentId + suffix, smPageUrl, 'スクリプト管理画面', 'pt-scriptmanager' + suffix, 'Script Managerを開く', null, '#pt-logout' + suffix ); }) .filter(function(elOrNull) { return elOrNull !== null; }) ); if (smLinks.length > 0) { const style = ` li[id^="pt-scriptmanager"] a { width: auto !important; padding-left: 25px; white-space: nowrap; height: 20px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><path d="M20 10c0-.7-.1-1.3-.2-1.9l-2.3-.4c-.2-.7-.4-1.4-.8-2l1.4-1.9c-.5-.7-1.1-1.3-1.8-1.8l-1.9 1.4c-.6-.4-1.3-.6-2-.8l-.4-2.3c-.7-.1-1.3-.2-1.9-.2s-1.3.1-1.9.2l-.4 2.3c-.7.2-1.4.4-2 .8L4.1 2c-.7.5-1.3 1.1-1.8 1.8l1.4 1.9c-.4.6-.6 1.3-.8 2l-2.3.4c-.1.6-.2 1.2-.2 1.9s.1 1.3.2 1.9l2.3.4c.2.7.4 1.4.8 2l-1.4 1.9c.5.7 1.1 1.3 1.8 1.8l1.9-1.4c.6.4 1.3.6 2 .8l.4 2.3c.6.1 1.2.2 1.9.2s1.3-.1 1.9-.2l.4-2.3c.7-.2 1.4-.4 2-.8l1.9 1.4c.7-.5 1.3-1.1 1.8-1.8l-1.4-1.9c.4-.6.6-1.3.8-2l2.3-.4c.1-.6.2-1.2.2-1.9z" fill="%23202122"/><text x="10" y="13" font-family="sans-serif" font-weight="bold" font-size="8px" fill="white" text-anchor="middle">JS</text></svg>'); background-repeat: no-repeat; background-size: 20px 20px; background-position: center left; } `; $('<style>').text(style).appendTo('head'); } }); // --- 4. スクリプトのロード判定ロジック --- scriptList.forEach(function(script) { var s = userSettings[script.id]; if (!s || !s.enabled) return; var shouldLoad = false; if (s.isBlacklistMode) { var blocked = false; if (isDiff && !s.onDiff) blocked = true; else if (isPreview && !s.onPreview) blocked = true; else if (isEditMode && !s.onEdit) blocked = true; else if (action === 'view' && !isDiff) { if (isMainNS && !s.onMain) blocked = true; else if (isUserNS && !s.onUser) blocked = true; else if (isTalkNS && !s.onTalk) blocked = true; else if (isSpecialNS && !s.onSpecial) blocked = true; } shouldLoad = !blocked; } else { if (isDiff && s.onDiff) shouldLoad = true; else if (isPreview && s.onPreview) shouldLoad = true; else if (isEditMode && s.onEdit) shouldLoad = true; else if (action === 'view' && !isDiff) { if (isMainNS && s.onMain) shouldLoad = true; else if (isUserNS && s.onUser) shouldLoad = true; else if (isTalkNS && s.onTalk) shouldLoad = true; else if (isSpecialNS && s.onSpecial) shouldLoad = true; } } if (shouldLoad) mw.loader.load(script.url); }); // --- 5. 管理画面(Special:SM)の構築 --- if (/^(special|特別):(scriptmanager|sm)$/i.test(pageName)) { document.title = 'Script Manager'; $('#firstHeading').text('Script Manager'); var $body = $('#mw-content-text').empty(); $('<style>').text(` #sm-container { font-family: sans-serif; color: #202122; max-width: 1000px; margin: 20px 0; } .sm-card { background: #fff; border: 1px solid #c8ccd1; border-left: 5px solid #36c; border-radius: 8px; padding: 14px; margin-bottom: 16px; display: flex; align-items: center; transition: all 0.3s ease; } /* カードが無効でも文字を薄くしない */ .sm-card.disabled { background: #f8f9fa !important; border-left-color: #72777d; opacity: 1 !important; filter: none !important; } .sm-info { flex-grow: 1; min-width: 160px; overflow: hidden; margin-right: 10px; } .sm-name { font-weight: bold; font-size: 1.1em; display: flex; align-items: center; color: #000 !important; } .sm-status-badge { font-size: 10px; padding: 2px 6px; border-radius: 10px; margin-left: 10px; text-transform: uppercase; border: 1px solid #c8ccd1; background: #f8f9fa; color: #72777d; } .status-on { background: #eaf3ff; color: #36c; border-color: #36c; } /* --- 有効/無効(マスター)チェックボックスの独立デザイン --- */ .sm-main-toggle { border-right: 2px solid #eaecf0; padding-right: 15px; margin-right: 15px; flex-shrink: 0; } .sm-master-label { color: #000 !important; font-weight: bold !important; font-size: 0.85em; } .sm-master { appearance: none; -webkit-appearance: none; width: 18px; height: 18px; border: 2px solid #000 !important; /* 縁を黒く */ border-radius: 3px; background-color: #fff; position: relative; vertical-align: middle; cursor: pointer; margin-bottom: 4px; } .sm-master:checked { background-color: #36c !important; border-color: #36c !important; } .sm-master:checked::after { content: ""; position: absolute; left: 4px; top: 0px; width: 5px; height: 10px; border: solid white; border-width: 0 2px 2px 0; transform: rotate(45deg); } /* --- サブオプションのスタイル --- */ .sm-sub-options { display: flex; gap: 8px; flex-wrap: wrap; flex-shrink: 0; } .sm-checkbox-label { display: flex; flex-direction: column; align-items: center; font-size: 0.75em; color: #202122 !important; cursor: pointer; min-width: 46px; text-align: center; } .sm-checkbox-label input { margin-bottom: 4px; cursor: pointer; opacity: 1 !important; } /* ブラックリストモード等の表示 */ .mode-bl-active { border-left-color: #d33 !important; } .mode-bl-active .sm-sub-checkbox:not(:checked) { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #d33; background: #d33; position: relative; border-radius: 2px; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after, .mode-bl-active .sm-sub-checkbox:not(:checked)::before { content: ''; position: absolute; width: 8px; height: 1.5px; background-color: white; top: 50%; left: 50%; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after { transform: translate(-50%, -50%) rotate(45deg); } .mode-bl-active .sm-sub-checkbox:not(:checked)::before { transform: translate(-50%, -50%) rotate(-45deg); } .sm-footer-actions { position: sticky; bottom: 20px; float: right; display: flex; gap: 10px; z-index: 100; } .sm-btn { border: none; padding: 12px 24px; border-radius: 4px; font-weight: bold; cursor: pointer; } #sm-save-btn { background: #36c; color: #fff; } `).appendTo('head'); var $container = $('<div id="sm-container"></div>'); scriptList.forEach(function(script) { var s = userSettings[script.id] || { enabled: false, isBlacklistMode: false, onMain: true, onUser: true, onTalk: true, onSpecial: true, onEdit: true, onPreview: true, onDiff: true }; var $card = $('<div class="sm-card">').toggleClass('disabled', !s.enabled); if (s.isBlacklistMode) $card.addClass('mode-bl-active'); var $status = $('<span class="sm-status-badge"></span>').addClass(s.enabled ? 'status-on' : '').text(s.enabled ? 'ON' : 'OFF'); var viewUrl = script.url.replace(/[?&]action=raw/, '').replace(/[?&]ctype=[^&]+/, ''); var $info = $('<div class="sm-info">').append( $('<div class="sm-name">').text(script.name).append($status), $('<div class="sm-id-row" style="font-size:0.8em; color:#72777d;">').append( $('<span>').text(script.id), $('<a>').attr({href: viewUrl, target: '_blank'}).css('margin-left','8px').text('⇨ ' + script.pageTitle) ) ); // 有効/無効(マスター) var $masterCheck = $('<input type="checkbox" class="sm-master">') .prop('checked', s.enabled) .attr('data-id', script.id); var $mainToggle = $('<div class="sm-main-toggle">').append( $('<label class="sm-checkbox-label sm-master-label">').append($masterCheck, '有効') ); // サブオプション作成関数 function createOption(label, key, val) { var $input = $('<input type="checkbox" class="sm-sub-checkbox">').addClass('sm-' + key).prop('checked', val); return $('<label class="sm-checkbox-label">').append($input, label); } var $subOptions = $('<div class="sm-sub-options">').append( createOption('記事/WP', 'main', s.onMain), createOption('利用者', 'user', s.onUser), createOption('ノート', 'talk', s.onTalk), createOption('特別', 'special', s.onSpecial), createOption('編集', 'edit', s.onEdit), createOption('プレビュー', 'preview', s.onPreview), createOption('差分', 'diff', s.onDiff) ); // マスターチェック連動イベント $masterCheck.on('change', function() { var checked = $(this).is(':checked'); $card.toggleClass('disabled', !checked); $card.find('.sm-status-badge').toggleClass('status-on', checked).text(checked ? 'ON' : 'OFF'); }); // モード切替ボタン var $modeBtn = $('<button style="font-size:10px; margin-right:10px; cursor:pointer;">') .text(s.isBlacklistMode ? '制限ベース' : '許可ベース') .on('click', function() { var isBl = $(this).text() === '許可ベース'; $(this).text(isBl ? '制限ベース' : '許可ベース'); $card.toggleClass('mode-bl-active', isBl); }); $container.append($card.append($info, $modeBtn, $mainToggle, $subOptions)); }); $body.append($container, $('<div class="sm-footer-actions">').append( $('<button id="sm-save-btn">設定を保存して適用</button>').addClass('sm-btn').on('click', function() { var newSettings = {}; $('.sm-card').each(function() { var $c = $(this); var id = $c.find('.sm-master').attr('data-id'); newSettings[id] = { enabled: $c.find('.sm-master').is(':checked'), isBlacklistMode: $c.find('button').first().text() === '制限ベース', onMain: $c.find('.sm-main').is(':checked'), onUser: $c.find('.sm-user').is(':checked'), onTalk: $c.find('.sm-talk').is(':checked'), onSpecial: $c.find('.sm-special').is(':checked'), onEdit: $c.find('.sm-edit').is(':checked'), onPreview: $c.find('.sm-preview').is(':checked'), onDiff: $c.find('.sm-diff').is(':checked') }; }); localStorage.setItem('wp-script-manager-v4', JSON.stringify(newSettings)); mw.notify('設定を保存しました。'); setTimeout(function() { location.reload(); }, 800); }) )); } $(function() { // 1. 基本情報の取得 const pageName = mw.config.get('wgPageName').replace(/_/g, ' '); const action = mw.config.get('wgAction'); const userName = mw.config.get('wgUserName') const userNs = mw.config.get('wgFormattedNamespaces')[2]; const myCommonJs = userNs + ':' + userName + '/common.js'; const isJsPage = pageName.endsWith('.js'); const isManagerScript = pageName.endsWith('ScriptManager.js'); const isDiff = !!mw.config.get('wgDiffNewId'); // 2. 登録済み判定 function checkRegistration() { if (!window.scriptManagerList) return false; return window.scriptManagerList.some(script => { const savedTitle = (script.title || '').replace(/_/g, ' '); return savedTitle === pageName; }); } const isAlreadyRegistered = checkRegistration(); // --- 表示条件 --- // ・JSページである // ・現在のページが「自分のcommon.js」もしくは ScriptManager.jsでは表示しない。 // ・未登録である // ・閲覧モードかつ差分表示ではない // --- ボタンのデザイン変更(青い四角の箱) --- if (isJsPage && pageName !== myCommonJs && !isManagerScript && !isAlreadyRegistered && action === 'view' && !isDiff) { const $smInstallBtn = $('<button>') .text('ScriptManagerに追加') .addClass('mw-ui-button mw-ui-progressive') .css({ 'margin-left': '12px', 'vertical-align': 'middle', 'border-radius': '2px', 'padding': '0 12px', 'height': '32px', 'font-weight': 'bold', 'box-shadow': 'none' }) .on('click', function() { const scriptName = prompt('このスクリプトに名前をつけてください:', mw.config.get('wgTitle')); if (scriptName) { installScript(pageName, scriptName, $(this)); } }); $('#firstHeading').append($smInstallBtn); } // 3. common.js への追加処理 function installScript(targetPage, label, $button) { const api = new mw.Api(); // --- 1. ドメインと言語の判定ロジック(省略) --- const rawDomain = mw.config.get('wgServerName'); let lang = ''; let domain = rawDomain; const parts = rawDomain.split('.'); if (parts.length >= 3 && parts.slice(-2).join('.') === 'wikipedia.org') { lang = parts[0]; domain = 'wikipedia.org'; } if (domain === 'wikipedia.org') domain = ''; if (lang === 'ja') lang = ''; // --- 2. エントリとウィキリンクの作成(省略) --- let entryParts = [`name: '${label}'`]; if (lang !== '') entryParts.push(`lang: '${lang}'`); if (domain !== '') entryParts.push(`domain: '${domain}'`); entryParts.push(`title: '${targetPage}'`); let wikiLink = (domain !== '' && domain !== 'wikipedia.org') ? `[${location.protocol}//${rawDomain}/wiki/${encodeURI(targetPage)} ${targetPage}]` : `[[${(lang !== '' && lang !== 'ja') ? ':' + lang + ':' : ''}${targetPage}]]`; // --- 最終的な書き出し形式の組み立て --- // 1行目にコメント、2行目にオブジェクト(インデント付き) const newEntry = ` // ${wikiLink}\n { ${entryParts.join(', ')} },`; api.get({ action: 'query', prop: 'revisions', titles: myCommonJs, rvprop: 'content', rvslots: 'main' }).done(function(data) { const page = Object.values(data.query.pages)[0]; let content = (page && page.revisions) ? page.revisions[0].slots.main['*'] : ''; // --- 重複コードの検出と削除 (既存) --- const escapedPage = targetPage.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/[ _]/g, '[ _]'); const loadPattern = new RegExp(`(mw\\.loader\\.load|importScript)\\s*\\(\\s*['"\`].*?${escapedPage}.*?['"\`]\\s*\\);?`, 'g'); if (loadPattern.test(content)) { if (!confirm(`注意:common.js 内にこのスクリプトの既存の読み込みコードが見つかりました。\n\n「OK」:既存のコードを削除して移行します。\n「キャンセル」:中止します。`)) return; content = content.replace(loadPattern, '').replace(/\n{3,}/g, '\n\n'); } // --- コンテンツの更新 --- // 配列の開始位置のすぐ後ろに「コメント + オブジェクト」を挿入 if (content.includes('window.scriptManagerList = [')) { content = content.replace('window.scriptManagerList = [', `window.scriptManagerList = [\n${newEntry}`); } else { content = `window.scriptManagerList = [\n${newEntry}\n];\n\n` + content; } api.postWithToken('csrf', { action: 'edit', title: myCommonJs, text: content, summary: `${wikiLink} を ScriptManager に追加 (${label})` }).done(function(saveData) { if (saveData.edit && saveData.edit.result === 'Success') { mw.notify(label + ' を追加しました。'); $button.fadeOut(); if (!window.scriptManagerList) window.scriptManagerList = []; window.scriptManagerList.push({ name: label, lang: lang, domain: domain, title: targetPage }); } }); }); } }); })(jQuery, mediaWiki); cahvn06dviymnj8xhz8s08abpa2174u 740999 740998 2026-05-08T13:43:42Z OUT is this 73801 740999 javascript text/javascript (function($, mw) { 'use strict'; // --- 1. スクリプト情報の整理 --- var rawList = window.scriptManagerList || []; var usedIds = {}; var scriptList = rawList.map(function(script) { var finalUrl = ''; // --- URL生成ロジック --- if (script.url) { finalUrl = script.url; } else { var langCode = (script.lang === undefined) ? 'ja' : script.lang; var langPrefix = (langCode !== '') ? langCode + '.' : ''; var domain = script.domain || 'wikipedia.org'; var title = script.title || ''; finalUrl = '//' + langPrefix + domain + '/w/index.php?title=' + encodeURIComponent(title) + '&action=raw&ctype=text/javascript'; } var match = finalUrl.match(/[?&]title=([^&]+)/); var pageTitle = match ? decodeURIComponent(match[1]) : 'Unknown'; var idBase = 'unknown'; if (match) { idBase = pageTitle .replace(/^(User|利用者):[^/]+\//i, '') .replace(/\.js$/i, '') .replace(/[ _ %]+/g, '_') .replace(/[^a-zA-Z0-9_]/g, ''); } var finalId = idBase; var counter = 2; while (usedIds[finalId]) { finalId = idBase + '_' + counter; counter++; } usedIds[finalId] = true; return { id: finalId, name: script.name, url: finalUrl, pageTitle: pageTitle }; }); // --- 2. 現在の状態の取得 --- var userSettings = JSON.parse(localStorage.getItem('wp-script-manager-v4') || '{}'); var pageName = mw.config.get('wgPageName').replace(/[ _ ]+/g, '').toLowerCase(); var action = mw.config.get('wgAction'); var ns = mw.config.get('wgNamespaceNumber'); var isDiff = !!mw.config.get('wgDiffNewId'); var isPreview = ['submit', 'preview'].indexOf(action) !== -1 && $('#wikiPreview').length > 0; var isMainNS = (ns === 0 || ns === 4); var isUserNS = (ns === 2 || ns === 3); var isTalkNS = (ns % 2 !== 0 && ns > 0); var isSpecialNS = (ns === -1); var isEditMode = (action === 'edit' || action === 'submit'); // --- 3. メニューへのリンク追加 --- $(function() { var smPageUrl = mw.util.getUrl('Special:SM'); var smLinks = $( ['', '-sticky-header'] .map(function(suffix) { var parentId = $('#p-user-menu-pages' + suffix).length ? 'p-user-menu-pages' : 'p-personal'; return mw.util.addPortletLink( parentId + suffix, smPageUrl, 'スクリプト管理画面', 'pt-scriptmanager' + suffix, 'Script Managerを開く', null, '#pt-logout' + suffix ); }) .filter(function(elOrNull) { return elOrNull !== null; }) ); if (smLinks.length > 0) { const style = ` li[id^="pt-scriptmanager"] a { width: auto !important; padding-left: 25px; white-space: nowrap; height: 20px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><path d="M20 10c0-.7-.1-1.3-.2-1.9l-2.3-.4c-.2-.7-.4-1.4-.8-2l1.4-1.9c-.5-.7-1.1-1.3-1.8-1.8l-1.9 1.4c-.6-.4-1.3-.6-2-.8l-.4-2.3c-.7-.1-1.3-.2-1.9-.2s-1.3.1-1.9.2l-.4 2.3c-.7.2-1.4.4-2 .8L4.1 2c-.7.5-1.3 1.1-1.8 1.8l1.4 1.9c-.4.6-.6 1.3-.8 2l-2.3.4c-.1.6-.2 1.2-.2 1.9s.1 1.3.2 1.9l2.3.4c.2.7.4 1.4.8 2l-1.4 1.9c.5.7 1.1 1.3 1.8 1.8l1.9-1.4c.6.4 1.3.6 2 .8l.4 2.3c.6.1 1.2.2 1.9.2s1.3-.1 1.9-.2l.4-2.3c.7-.2 1.4-.4 2-.8l1.9 1.4c.7-.5 1.3-1.1 1.8-1.8l-1.4-1.9c.4-.6.6-1.3.8-2l2.3-.4c.1-.6.2-1.2.2-1.9z" fill="%23202122"/><text x="10" y="13" font-family="sans-serif" font-weight="bold" font-size="8px" fill="white" text-anchor="middle">JS</text></svg>'); background-repeat: no-repeat; background-size: 20px 20px; background-position: center left; } `; $('<style>').text(style).appendTo('head'); } }); // --- 4. スクリプトのロード判定ロジック --- scriptList.forEach(function(script) { var s = userSettings[script.id]; if (!s || !s.enabled) return; var shouldLoad = false; if (s.isBlacklistMode) { var blocked = false; if (isDiff && !s.onDiff) blocked = true; else if (isPreview && !s.onPreview) blocked = true; else if (isEditMode && !s.onEdit) blocked = true; else if (action === 'view' && !isDiff) { if (isMainNS && !s.onMain) blocked = true; else if (isUserNS && !s.onUser) blocked = true; else if (isTalkNS && !s.onTalk) blocked = true; else if (isSpecialNS && !s.onSpecial) blocked = true; } shouldLoad = !blocked; } else { if (isDiff && s.onDiff) shouldLoad = true; else if (isPreview && s.onPreview) shouldLoad = true; else if (isEditMode && s.onEdit) shouldLoad = true; else if (action === 'view' && !isDiff) { if (isMainNS && s.onMain) shouldLoad = true; else if (isUserNS && s.onUser) shouldLoad = true; else if (isTalkNS && s.onTalk) shouldLoad = true; else if (isSpecialNS && s.onSpecial) shouldLoad = true; } } if (shouldLoad) mw.loader.load(script.url); }); // --- 5. 管理画面(Special:SM)の構築 --- if (/^(special|特別):(scriptmanager|sm)$/i.test(pageName)) { document.title = 'Script Manager'; $('#firstHeading').text('Script Manager'); var $body = $('#mw-content-text').empty(); $('<style>').text(` #sm-container { font-family: sans-serif; color: #202122; max-width: 1000px; margin: 20px 0; } .sm-card { background: #fff; border: 1px solid #c8ccd1; border-left: 5px solid #36c; border-radius: 8px; padding: 14px; margin-bottom: 16px; display: flex; align-items: center; transition: all 0.3s ease; } .sm-info { flex-grow: 1; min-width: 160px; overflow: hidden; margin-right: 10px; } .sm-name { font-weight: bold; font-size: 1.1em; display: flex; align-items: center; color: #202122; } .sm-id-row { font-size: 0.8em; color: #72777d; font-family: monospace; margin-top: 4px; display: flex; align-items: center; gap: 8px; } .sm-js-link { color: #36c; text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 250px; border-bottom: 1px solid transparent; } .sm-js-link:hover { border-bottom-color: #36c; } .sm-status-badge { font-size: 10px; padding: 2px 6px; border-radius: 10px; margin-left: 10px; text-transform: uppercase; border: 1px solid #c8ccd1; background: #f8f9fa; color: #72777d; } .status-on { background: #eaf3ff; color: #36c; border-color: #36c; } .sm-mode-switch { padding: 0 10px; border-right: 1px solid #eaecf0; margin-right: 10px; text-align: center; } .sm-mode-toggle { border: 1px solid #a2a9b1; border-radius: 4px; padding: 4px 8px; cursor: pointer; font-size: 10.5px; background: #fff; color: #202122; white-space: nowrap; } .sm-main-toggle { border-right: 2px solid #eaecf0; padding-right: 10px; margin-right: 10px; flex-shrink: 0; } .sm-sub-options { display: flex; gap: 8px; flex-wrap: wrap; flex-shrink: 0; } .sm-checkbox-label { display: flex; flex-direction: column; align-items: center; font-size: 0.75em; color: #54595d; cursor: pointer; min-width: 46px; text-align: center; } .sm-checkbox-label input { margin-bottom: 4px; cursor: pointer; } .mode-bl-active .sm-sub-checkbox:not(:checked) { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #d33; background: #d33; position: relative; border-radius: 2px; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after, .mode-bl-active .sm-sub-checkbox:not(:checked)::before { content: ''; position: absolute; width: 10px; height: 1.8px; background-color: white; top: 50%; left: 50%; } .mode-bl-active .sm-sub-checkbox:not(:checked)::after { transform: translate(-50%, -50%) rotate(45deg); } .mode-bl-active .sm-sub-checkbox:not(:checked)::before { transform: translate(-50%, -50%) rotate(-45deg); } .mode-bl-active .sm-sub-checkbox:checked { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border: 1px solid #a2a9b1; border-radius: 2px; background: #fff; } .mode-bl-active { border-left-color: #d33 !important; } .mode-bl-active .status-on { background: #fee7e6; color: #d33; border-color: #d33; } .sm-card.disabled { background: #f8f9fa !important; opacity: 0.6; filter: grayscale(1); } .sm-footer-actions { position: sticky; bottom: 20px; float: right; display: flex; gap: 10px; z-index: 100; } .sm-btn { border: none; padding: 12px 24px; border-radius: 4px; font-weight: bold; cursor: pointer; transition: background 0.2s; } #sm-save-btn { background: #36c; color: #fff; } #sm-common-js-btn { background: #f8f9fa; color: #202122; border: 1px solid #a2a9b1; text-decoration: none; font-size: 0.95em; display: flex; align-items: center; } /* 管理スクリプトがない時の案内用スタイル */ .sm-guide-box { background: #f8f9fa; border: 1px dashed #a2a9b1; padding: 20px; border-radius: 8px; text-align: center; margin: 20px 0; } .sm-guide-box h3 { margin-top: 0; } .sm-step { display: inline-block; text-align: left; margin: 10px 0; vertical-align: top; width: 250px; padding: 10px; } `).appendTo('head'); var $container = $('<div id="sm-container"></div>'); if (scriptList.length === 0) { var manualUrl = 'https://ja.wikipedia.org/wiki/' + encodeURIComponent('利用者:OUT_is_this/ScriptManager'); $container.append(` <div class="sm-guide-box"> <h3>スクリプトが登録されていません</h3> <p>以下の手順でスクリプトを追加してください:</p> <div class="sm-step"><b>1. 探す</b><br>ScriptManagerに登録したいスクリプトが置いてある <code>.js</code> ページを開きます。</div> <div class="sm-step"><b>2. 追加する</b><br>ページ上部の「ScriptManagerに追加」ボタンを押します。</div> <div class="sm-step"><b>3. 保存</b><br>名前を付けて保存すると自動で common.js に書き込まれます。</div> <div style="margin-top:20px; padding-top:15px; border-top:1px solid #eaecf0; text-align:center;"> <div style="display:inline-flex; align-items:flex-start; color:#202122;"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 20 20" style="flex-shrink:0; margin-right:8px; margin-top:4px;"> <path d="M10 0C4.48 0 0 4.48 0 10s4.48 10 10 10 10-4.48 10-10S15.52 0 10 0zm0 15c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1s1 .45 1 1v4c0 .55-.45 1-1 1zm1-8H9V5h2v2z" fill="#36c"/> </svg> <span style="line-height:1.8; text-align:center; display:block;"> common.js に手入力で直接書き込む方法や、他ドメインにある js の登録方法、その他詳しい使い方などは<br> <a href="${manualUrl}" target="_blank" style="font-weight:bold; text-decoration:none; color:#36c;">こちら(解説ページ)</a>をご覧ください。 </span> </div> </div> </div> `); } scriptList.forEach(function(script) { var s = userSettings[script.id] || { enabled: false, isBlacklistMode: false, onMain: true, onUser: true, onTalk: true, onSpecial: true, onEdit: true, onPreview: true, onDiff: true }; var $card = $('<div class="sm-card">').toggleClass('disabled', !s.enabled); if (s.isBlacklistMode) $card.addClass('mode-bl-active'); var $status = $('<span class="sm-status-badge"></span>').addClass(s.enabled ? 'status-on' : '').text(s.enabled ? 'ON' : 'OFF'); var viewUrl = script.url.replace(/[?&]action=raw/, '').replace(/[?&]ctype=[^&]+/, ''); var $info = $('<div class="sm-info">').append( $('<div class="sm-name">').text(script.name).append($status), $('<div class="sm-id-row">').append( $('<span>').text(script.id), $('<a>').attr({href: viewUrl, target: '_blank', title: script.pageTitle}) .addClass('sm-js-link').text('⇨ ' + script.pageTitle) ) ); var $modeBtn = $('<div class="sm-mode-toggle">').text(s.isBlacklistMode ? '制限ベース' : '許可ベース'); $modeBtn.on('click', function() { var isBl = $(this).text() === '許可ベース'; $(this).text(isBl ? '制限ベース' : '許可ベース'); $card.toggleClass('mode-bl-active', isBl); }); var $mainToggle = $('<div class="sm-main-toggle">').append( $('<label class="sm-checkbox-label">').append($('<input type="checkbox" class="sm-master">').prop('checked', s.enabled).attr('data-id', script.id), '<b>有効</b>') ); function createOption(label, key, val) { var $input = $('<input type="checkbox" class="sm-sub-checkbox">').addClass('sm-' + key).prop('checked', val); return $('<label class="sm-checkbox-label">').append($input, label); } var $subOptions = $('<div class="sm-sub-options">').append( createOption('記事/WP', 'main', s.onMain), createOption('利用者', 'user', s.onUser), createOption('ノート', 'talk', s.onTalk), createOption('特別', 'special', s.onSpecial), createOption('編集', 'edit', s.onEdit), createOption('プレビュー', 'preview', s.onPreview), createOption('差分', 'diff', s.onDiff) ); $mainToggle.find('.sm-master').on('change', function() { var checked = $(this).is(':checked'); $card.toggleClass('disabled', !checked); $card.find('.sm-status-badge').toggleClass('status-on', checked).text(checked ? 'ON' : 'OFF'); }); $container.append($card.append($info, $('<div class="sm-mode-switch">').append($modeBtn), $mainToggle, $subOptions)); }); $body.append($container, $('<div class="sm-footer-actions">').append( $('<a>').attr({id: 'sm-common-js-btn', href: mw.util.getUrl('Special:MyPage/common.js'), target: '_blank'}).addClass('sm-btn').text('common.js を編集'), $('<button id="sm-save-btn">設定を保存して適用</button>').addClass('sm-btn').on('click', function() { var newSettings = {}; $('.sm-card').each(function() { var $c = $(this); var id = $c.find('.sm-master').attr('data-id'); newSettings[id] = { enabled: $c.find('.sm-master').is(':checked'), isBlacklistMode: $c.find('.sm-mode-toggle').text() === '制限ベース', onMain: $c.find('.sm-main').is(':checked'), onUser: $c.find('.sm-user').is(':checked'), onTalk: $c.find('.sm-talk').is(':checked'), onSpecial: $c.find('.sm-special').is(':checked'), onEdit: $c.find('.sm-edit').is(':checked'), onPreview: $c.find('.sm-preview').is(':checked'), onDiff: $c.find('.sm-diff').is(':checked') }; }); localStorage.setItem('wp-script-manager-v4', JSON.stringify(newSettings)); mw.notify('設定を保存しました。'); var returnUrl = document.referrer; setTimeout(function() { location.href = (returnUrl && returnUrl.indexOf(location.hostname) !== -1) ? returnUrl : mw.util.getUrl('Main_Page'); }, 800); }) )); } $(function() { // 1. 基本情報の取得 const pageName = mw.config.get('wgPageName').replace(/_/g, ' '); const action = mw.config.get('wgAction'); const userName = mw.config.get('wgUserName') const userNs = mw.config.get('wgFormattedNamespaces')[2]; const myCommonJs = userNs + ':' + userName + '/common.js'; const isJsPage = pageName.endsWith('.js'); const isManagerScript = pageName.endsWith('ScriptManager.js'); const isDiff = !!mw.config.get('wgDiffNewId'); // 2. 登録済み判定 function checkRegistration() { if (!window.scriptManagerList) return false; return window.scriptManagerList.some(script => { const savedTitle = (script.title || '').replace(/_/g, ' '); return savedTitle === pageName; }); } const isAlreadyRegistered = checkRegistration(); // --- 表示条件 --- // ・JSページである // ・現在のページが「自分のcommon.js」もしくは ScriptManager.jsでは表示しない。 // ・未登録である // ・閲覧モードかつ差分表示ではない // --- ボタンのデザイン変更(青い四角の箱) --- if (isJsPage && pageName !== myCommonJs && !isManagerScript && !isAlreadyRegistered && action === 'view' && !isDiff) { const $smInstallBtn = $('<button>') .text('ScriptManagerに追加') .addClass('mw-ui-button mw-ui-progressive') .css({ 'margin-left': '12px', 'vertical-align': 'middle', 'border-radius': '2px', 'padding': '0 12px', 'height': '32px', 'font-weight': 'bold', 'box-shadow': 'none' }) .on('click', function() { const scriptName = prompt('このスクリプトに名前をつけてください:', mw.config.get('wgTitle')); if (scriptName) { installScript(pageName, scriptName, $(this)); } }); $('#firstHeading').append($smInstallBtn); } // 3. common.js への追加処理 function installScript(targetPage, label, $button) { const api = new mw.Api(); // --- 1. ドメインと言語の判定ロジック(省略) --- const rawDomain = mw.config.get('wgServerName'); let lang = ''; let domain = rawDomain; const parts = rawDomain.split('.'); if (parts.length >= 3 && parts.slice(-2).join('.') === 'wikipedia.org') { lang = parts[0]; domain = 'wikipedia.org'; } if (domain === 'wikipedia.org') domain = ''; if (lang === 'ja') lang = ''; // --- 2. エントリとウィキリンクの作成(省略) --- let entryParts = [`name: '${label}'`]; if (lang !== '') entryParts.push(`lang: '${lang}'`); if (domain !== '') entryParts.push(`domain: '${domain}'`); entryParts.push(`title: '${targetPage}'`); let wikiLink = (domain !== '' && domain !== 'wikipedia.org') ? `[${location.protocol}//${rawDomain}/wiki/${encodeURI(targetPage)} ${targetPage}]` : `[[${(lang !== '' && lang !== 'ja') ? ':' + lang + ':' : ''}${targetPage}]]`; // --- 最終的な書き出し形式の組み立て --- // 1行目にコメント、2行目にオブジェクト(インデント付き) const newEntry = ` // ${wikiLink}\n { ${entryParts.join(', ')} },`; api.get({ action: 'query', prop: 'revisions', titles: myCommonJs, rvprop: 'content', rvslots: 'main' }).done(function(data) { const page = Object.values(data.query.pages)[0]; let content = (page && page.revisions) ? page.revisions[0].slots.main['*'] : ''; // --- 重複コードの検出と削除 (既存) --- const escapedPage = targetPage.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/[ _]/g, '[ _]'); const loadPattern = new RegExp(`(mw\\.loader\\.load|importScript)\\s*\\(\\s*['"\`].*?${escapedPage}.*?['"\`]\\s*\\);?`, 'g'); if (loadPattern.test(content)) { if (!confirm(`注意:common.js 内にこのスクリプトの既存の読み込みコードが見つかりました。\n\n「OK」:既存のコードを削除して移行します。\n「キャンセル」:中止します。`)) return; content = content.replace(loadPattern, '').replace(/\n{3,}/g, '\n\n'); } // --- コンテンツの更新 --- // 配列の開始位置のすぐ後ろに「コメント + オブジェクト」を挿入 if (content.includes('window.scriptManagerList = [')) { content = content.replace('window.scriptManagerList = [', `window.scriptManagerList = [\n${newEntry}`); } else { content = `window.scriptManagerList = [\n${newEntry}\n];\n\n` + content; } api.postWithToken('csrf', { action: 'edit', title: myCommonJs, text: content, summary: `${wikiLink} を ScriptManager に追加 (${label})` }).done(function(saveData) { if (saveData.edit && saveData.edit.result === 'Success') { mw.notify(label + ' を追加しました。'); $button.fadeOut(); if (!window.scriptManagerList) window.scriptManagerList = []; window.scriptManagerList.push({ name: label, lang: lang, domain: domain, title: targetPage }); } }); }); } }); })(jQuery, mediaWiki); nxtghmrssih0ib5j5bu0zoozv67kjn8 Doubler1 0 175273 741010 740899 2026-05-08T15:47:58Z Valcio 46860 test 741010 wikitext text/x-wiki <div class="codex-tabs" data-framed="true"> <div class="codex-tab" data-label="Overview"> This is the overview tab. * Normal wikitext lists work here. * Links like [[Main Page]] work here too. </div> <div class="codex-tab" data-label="Details"> == Details heading == This content becomes the second Codex tab. </div> <div class="codex-tab" data-label="Examples"> Here are examples: {| class="wikitable" ! Name !! Status |- | Foo || Done |- | Bar || Draft |} </div> </div> 3o51xjwjw9bg3m5gia4xyoj1v2rcwgj MediaWiki:Gadget-valcio.vue 8 175295 741000 2026-05-08T15:34:44Z Valcio 46860 + 741000 vue application/vue+xml <template> <cdx-tabs :framed="framed"> <cdx-tab v-for="( tab, index ) in tabsData" :key="index" :name="tab.name" :label="tab.label" > <!-- Tab content --> <h2>{{ tab.heading }}</h2> <template v-if="tab.name === 'read'"> <p> The <b>sand cat</b> (<i>Felis margarita</i>), also known as the <b>sand dune cat</b>, is a small wild <a href="#" title="Felis">cat</a> that inhabits sandy and stony <a href="#" title="Desert">deserts</a> far from water sources. With its sandy to light grey fur, it is well camouflaged in a desert environment. </p> </template> <template v-if="tab.name === 'source'"> <code> The '''sand cat''' (''Felis margarita''), also known as the '''sand dune cat''', is a small wild [[Felis|cat]] that inhabits sandy and stony [[deserts]] far from water sources. With its sandy to light grey fur, it is well camouflaged in a desert environment. </code> </template> <template v-if="tab.name === 'history'"> <h3>Revisions</h3> <ul> <li>Revision 3</li> <li>Revision 2</li> <li>Revision 1</li> </ul> </template> </cdx-tab> </cdx-tabs> </template> <script> const { CdxTabs, CdxTab } = require( '@wikimedia/codex' ); const { defineComponent } = require( 'vue' ); module.exports = defineComponent( { name: 'BasicTabs', components: { CdxTabs, CdxTab }, props: { framed: { type: Boolean, default: false } }, data() { return { tabsData: [ { name: 'read', label: 'Read', heading: 'Sand cat' }, { name: 'source', label: 'View source', heading: 'View source for Sand cat' }, { name: 'history', label: 'View history', heading: 'Sand cat: Revision history' } ] }; } } ); </script> btqtqel74oyo97aifa79xpoi36pwdiz MediaWiki:Gadget-codexTableBuilder.js 8 175296 741004 2026-05-08T15:42:30Z Valcio 46860 + 741004 javascript text/javascript 'use strict'; const Vue = require( 'vue' ); const App = require( './codexTableBuilder.vue' ); function mountCodexTableBuilder() { const editForm = document.getElementById( 'editform' ); const textarea = document.getElementById( 'wpTextbox1' ); if ( !editForm || !textarea || document.getElementById( 'codex-table-builder' ) ) { return; } const mountPoint = document.createElement( 'div' ); mountPoint.id = 'codex-table-builder'; editForm.insertBefore( mountPoint, textarea ); Vue.createMwApp( App ).mount( mountPoint ); } mw.hook( 'wikipage.editform' ).add( mountCodexTableBuilder ); mountCodexTableBuilder(); rl6xizw8lmv0mtkqtgbha9av6m5f5rx MediaWiki:Gadget-codexTableBuilder.vue 8 175297 741005 2026-05-08T15:44:31Z Valcio 46860 + 741005 vue application/vue+xml <template> <section class="ctb"> <h2 class="ctb__heading"> Codex table builder </h2> <cdx-field> <template #label> Caption </template> <cdx-text-input v-model="caption" placeholder="Example table" ></cdx-text-input> </cdx-field> <cdx-field> <template #label> Column headings </template> <cdx-text-input v-model="headers" placeholder="Name, Description, Status" ></cdx-text-input> <template #help-text> Comma-separated. Example: Name, Description, Status </template> </cdx-field> <cdx-field> <template #label> Rows </template> <cdx-text-area v-model="rows" :rows="6" placeholder="Foo, First item, Done&#10;Bar, Second item, Draft" ></cdx-text-area> <template #help-text> One row per line. Separate cells with commas. </template> </cdx-field> <div class="ctb__options"> <cdx-checkbox v-model="includeHeader"> Include header row </cdx-checkbox> <cdx-checkbox v-model="hideVisualCaption"> Visually hide table heading </cdx-checkbox> </div> <div class="ctb__actions"> <cdx-button action="progressive" weight="primary" @click="insertTable" > Insert table </cdx-button> <cdx-button @click="copyTable"> Copy markup </cdx-button> </div> <cdx-field> <template #label> Generated HTML </template> <cdx-text-area :model-value="tableHtml" readonly :rows="12" ></cdx-text-area> </cdx-field> <p v-if="status" class="ctb__status" role="status" > {{ status }} </p> </section> </template> <script> 'use strict'; const Codex = require( '@wikimedia/codex' ); function escapeHtml( value ) { return String( value ) .replace( /&/g, '&amp;' ) .replace( /</g, '&lt;' ) .replace( />/g, '&gt;' ) .replace( /"/g, '&quot;' ) .replace( /'/g, '&#039;' ); } function parseCsvLine( line ) { return line.split( ',' ).map( function ( cell ) { return cell.trim(); } ); } module.exports = { name: 'CodexTableBuilder', components: { CdxButton: Codex.CdxButton, CdxCheckbox: Codex.CdxCheckbox, CdxField: Codex.CdxField, CdxTextArea: Codex.CdxTextArea, CdxTextInput: Codex.CdxTextInput }, data: function () { return { caption: 'Example table', headers: 'Name, Description, Status', rows: 'Foo, First item, Done\nBar, Second item, Draft', includeHeader: true, hideVisualCaption: false, status: '' }; }, computed: { headerCells: function () { return parseCsvLine( this.headers ).filter( Boolean ); }, rowCells: function () { return this.rows .split( /\r?\n/ ) .filter( Boolean ) .map( parseCsvLine ); }, tableHtml: function () { const caption = escapeHtml( this.caption || 'Table' ); const visualCaptionClass = this.hideVisualCaption ? ' cdx-table__header__caption--visually-hidden' : ''; let html = ''; html += '<div class="cdx-table">\n'; html += '\t<div class="cdx-table__header">\n'; html += '\t\t<div class="cdx-table__header__caption' + visualCaptionClass + '" aria-hidden="true">' + caption + '</div>\n'; html += '\t</div>\n'; html += '\t<div class="cdx-table__table-wrapper">\n'; html += '\t\t<table class="cdx-table__table">\n'; html += '\t\t\t<caption>' + caption + '</caption>\n'; if ( this.includeHeader && this.headerCells.length ) { html += '\t\t\t<thead>\n'; html += '\t\t\t\t<tr>\n'; this.headerCells.forEach( function ( header ) { html += '\t\t\t\t\t<th scope="col">' + escapeHtml( header ) + '</th>\n'; } ); html += '\t\t\t\t</tr>\n'; html += '\t\t\t</thead>\n'; } html += '\t\t\t<tbody>\n'; if ( this.rowCells.length ) { this.rowCells.forEach( function ( row ) { html += '\t\t\t\t<tr>\n'; row.forEach( function ( cell ) { html += '\t\t\t\t\t<td>' + escapeHtml( cell ) + '</td>\n'; } ); html += '\t\t\t\t</tr>\n'; } ); } else { html += '\t\t\t\t<tr class="cdx-table__table__empty-state">\n'; html += '\t\t\t\t\t<td class="cdx-table__table__empty-state-content">\n'; html += '\t\t\t\t\t\tThere is no data available\n'; html += '\t\t\t\t\t</td>\n'; html += '\t\t\t\t</tr>\n'; } html += '\t\t\t</tbody>\n'; html += '\t\t</table>\n'; html += '\t</div>\n'; html += '</div>'; return html; } }, methods: { insertTable: function () { const textarea = document.getElementById( 'wpTextbox1' ); if ( !textarea ) { this.status = 'Could not find the edit textarea.'; return; } const start = textarea.selectionStart || 0; const end = textarea.selectionEnd || 0; const before = textarea.value.slice( 0, start ); const after = textarea.value.slice( end ); textarea.value = before + this.tableHtml + after; textarea.selectionStart = start; textarea.selectionEnd = start + this.tableHtml.length; textarea.focus(); $( textarea ).trigger( 'change' ); this.status = 'Inserted Codex table markup.'; }, copyTable: function () { const self = this; navigator.clipboard.writeText( this.tableHtml ).then( function () { self.status = 'Copied table markup.'; }, function () { self.status = 'Could not copy automatically. Select and copy the generated HTML manually.'; } ); } } }; </script> <style> .ctb { margin-bottom: 1em; padding: 1em; border: 1px solid #a2a9b1; background-color: #fff; } .ctb__heading { margin-top: 0; } .ctb__options, .ctb__actions { display: flex; flex-wrap: wrap; gap: 0.75em; margin: 1em 0; } .ctb__status { font-weight: bold; } </style> rp1vbl0s8fivfogi95i7dmymrax29yf MediaWiki:Gadget-codexTabs.js 8 175298 741007 2026-05-08T15:46:21Z Valcio 46860 + 741007 javascript text/javascript 'use strict'; const Vue = require( 'vue' ); const App = require( './codexTabs.vue' ); function makeSafeName( label, index ) { return String( label || 'tab-' + index ) .toLowerCase() .replace( /[^a-z0-9_-]+/g, '-' ) .replace( /^-+|-+$/g, '' ) || 'tab-' + index; } function collectTabs( wrapper ) { const tabNodes = Array.prototype.slice.call( wrapper.querySelectorAll( ':scope > .codex-tab' ) ); return tabNodes.map( function ( node, index ) { const label = node.getAttribute( 'data-label' ) || node.getAttribute( 'data-title' ) || 'Tab ' + ( index + 1 ); return { name: makeSafeName( label, index ) + '-' + index, label: label, html: node.innerHTML }; } ); } function mountOne( wrapper, index ) { const tabs = collectTabs( wrapper ); if ( tabs.length < 2 ) { return; } const framed = wrapper.getAttribute( 'data-framed' ) === 'true'; const active = wrapper.getAttribute( 'data-active' ) || tabs[ 0 ].name; const mountPoint = document.createElement( 'div' ); mountPoint.className = 'codex-tabs-gadget'; mountPoint.id = 'codex-tabs-gadget-' + index; wrapper.parentNode.replaceChild( mountPoint, wrapper ); Vue.createMwApp( App, { tabs: tabs, framed: framed, active: active } ).mount( mountPoint ); } function initCodexTabs() { const wrappers = Array.prototype.slice.call( document.querySelectorAll( '.mw-parser-output > .codex-tabs, .mw-parser-output .codex-tabs' ) ); wrappers.forEach( function ( wrapper, index ) { if ( wrapper.classList.contains( 'codex-tabs--mounted' ) ) { return; } wrapper.classList.add( 'codex-tabs--mounted' ); mountOne( wrapper, index ); } ); } mw.hook( 'wikipage.content' ).add( function () { initCodexTabs(); } ); $( initCodexTabs ); suj5z0ink3ubhd8uc9qv0zko9gwg9up 741019 741007 2026-05-08T15:59:57Z Valcio 46860 + 741019 javascript text/javascript 'use strict'; const Vue = require( 'vue' ); const App = require( './codexTabs.vue' ); function makeSafeName( label, index ) { return String( label || 'tab-' + index ) .toLowerCase() .replace( /[^a-z0-9_-]+/g, '-' ) .replace( /^-+|-+$/g, '' ) || 'tab-' + index; } function getHeadingLabel( heading ) { const headline = heading.querySelector( '.mw-headline' ); if ( headline ) { return headline.textContent.trim(); } return heading.textContent.trim(); } function isTabHeading( node ) { return node && node.nodeType === Node.ELEMENT_NODE && node.tagName && node.tagName.toLowerCase() === 'h2'; } function collectSectionTabs( wrapper ) { const tabs = []; const children = Array.prototype.slice.call( wrapper.childNodes ); let currentTab = null; let currentContent = []; function finishCurrentTab() { if ( !currentTab ) { return; } const container = document.createElement( 'div' ); currentContent.forEach( function ( node ) { container.appendChild( node.cloneNode( true ) ); } ); currentTab.html = container.innerHTML; tabs.push( currentTab ); currentTab = null; currentContent = []; } children.forEach( function ( node ) { if ( isTabHeading( node ) ) { finishCurrentTab(); const label = getHeadingLabel( node ); currentTab = { name: makeSafeName( label, tabs.length ) + '-' + tabs.length, label: label, html: '' }; return; } if ( currentTab ) { currentContent.push( node ); } } ); finishCurrentTab(); return tabs.filter( function ( tab ) { return tab.label; } ); } function mountOne( wrapper, index ) { const tabs = collectSectionTabs( wrapper ); if ( tabs.length < 2 ) { return; } const framed = wrapper.getAttribute( 'data-framed' ) !== 'false'; const activeLabel = wrapper.getAttribute( 'data-active-label' ); let active = tabs[ 0 ].name; if ( activeLabel ) { tabs.forEach( function ( tab ) { if ( tab.label === activeLabel ) { active = tab.name; } } ); } const mountPoint = document.createElement( 'div' ); mountPoint.className = 'codex-tabs-gadget'; mountPoint.id = 'codex-tabs-gadget-' + index; wrapper.parentNode.replaceChild( mountPoint, wrapper ); Vue.createMwApp( App, { tabs: tabs, framed: framed, active: active } ).mount( mountPoint ); } function initCodexSectionTabs( $content ) { const root = $content && $content[ 0 ] ? $content[ 0 ] : document; const wrappers = Array.prototype.slice.call( root.querySelectorAll( '.codex-tabs-sections' ) ); wrappers.forEach( function ( wrapper, index ) { if ( wrapper.classList.contains( 'codex-tabs--mounted' ) ) { return; } wrapper.classList.add( 'codex-tabs--mounted' ); mountOne( wrapper, index ); } ); } mw.hook( 'wikipage.content' ).add( initCodexSectionTabs ); $( function () { initCodexSectionTabs( $( document.body ) ); } ); h5q1e2yrcti1uvachqxykv8h3bbyctd 741023 741019 2026-05-08T16:03:14Z Valcio 46860 + 741023 javascript text/javascript 'use strict'; const Vue = require( 'vue' ); const App = require( './codexTabs.vue' ); function makeSafeName( label, index ) { return String( label || 'tab-' + index ) .toLowerCase() .replace( /[^a-z0-9_-]+/g, '-' ) .replace( /^-+|-+$/g, '' ) || 'tab-' + index; } function getHeadingLabel( heading ) { const clone = heading.cloneNode( true ); // Remove MediaWiki's [edit] links from the heading label. Array.prototype.forEach.call( clone.querySelectorAll( '.mw-editsection, .mw-editsection-like' ), function ( node ) { node.remove(); } ); const headline = clone.querySelector( '.mw-headline' ); return ( headline ? headline.textContent : clone.textContent ).trim(); } function isTopLevelTabHeading( node ) { return node && node.nodeType === Node.ELEMENT_NODE && node.tagName && node.tagName.toLowerCase() === 'h2'; } function collectSectionTabs( wrapper ) { const tabs = []; const nodes = Array.prototype.slice.call( wrapper.childNodes ); let currentTab = null; let currentContent = []; function finishCurrentTab() { if ( !currentTab ) { return; } const container = document.createElement( 'div' ); currentContent.forEach( function ( node ) { container.appendChild( node.cloneNode( true ) ); } ); currentTab.html = container.innerHTML; tabs.push( currentTab ); currentTab = null; currentContent = []; } nodes.forEach( function ( node ) { if ( isTopLevelTabHeading( node ) ) { finishCurrentTab(); const label = getHeadingLabel( node ); currentTab = { name: makeSafeName( label, tabs.length ) + '-' + tabs.length, label: label, html: '' }; return; } if ( currentTab ) { currentContent.push( node ); } } ); finishCurrentTab(); return tabs.filter( function ( tab ) { return tab.label; } ); } function mountOne( wrapper, index ) { const tabs = collectSectionTabs( wrapper ); if ( tabs.length < 2 ) { // Helpful debugging message. // eslint-disable-next-line no-console console.warn( 'codexTabs: expected at least 2 == headings inside .codex-tabs-sections, found', tabs.length, wrapper ); return; } const framed = wrapper.getAttribute( 'data-framed' ) !== 'false'; const activeLabel = wrapper.getAttribute( 'data-active-label' ); let active = tabs[ 0 ].name; if ( activeLabel ) { tabs.forEach( function ( tab ) { if ( tab.label === activeLabel ) { active = tab.name; } } ); } const mountPoint = document.createElement( 'div' ); mountPoint.className = 'codex-tabs-gadget'; mountPoint.id = 'codex-tabs-gadget-' + index; wrapper.parentNode.replaceChild( mountPoint, wrapper ); Vue.createMwApp( App, { tabs: tabs, framed: framed, active: active } ).mount( mountPoint ); } function initCodexSectionTabs( $content ) { const root = $content && $content[ 0 ] ? $content[ 0 ] : document; const wrappers = Array.prototype.slice.call( root.querySelectorAll( '.codex-tabs-sections' ) ); wrappers.forEach( function ( wrapper, index ) { if ( wrapper.classList.contains( 'codex-tabs--mounted' ) ) { return; } wrapper.classList.add( 'codex-tabs--mounted' ); mountOne( wrapper, index ); } ); } mw.hook( 'wikipage.content' ).add( initCodexSectionTabs ); $( function () { initCodexSectionTabs( $( document.body ) ); } ); a2dkgan45ckwudhoyrja165dn0ry4ld 741025 741023 2026-05-08T16:06:17Z Valcio 46860 fix 741025 javascript text/javascript 'use strict'; const Vue = require( 'vue' ); const App = require( './codexTabs.vue' ); function makeSafeName( label, index ) { return String( label || 'tab-' + index ) .toLowerCase() .replace( /[^a-z0-9_-]+/g, '-' ) .replace( /^-+|-+$/g, '' ) || 'tab-' + index; } function getHeadingLabel( heading ) { const clone = heading.cloneNode( true ); // Remove MediaWiki's [edit] links from the heading label. Array.prototype.forEach.call( clone.querySelectorAll( '.mw-editsection, .mw-editsection-like' ), function ( node ) { node.remove(); } ); const headline = clone.querySelector( '.mw-headline' ); return ( headline ? headline.textContent : clone.textContent ).trim(); } function isTopLevelTabHeading( node ) { return node && node.nodeType === Node.ELEMENT_NODE && node.tagName && node.tagName.toLowerCase() === 'h2'; } function collectSectionTabs( wrapper ) { const tabs = []; const nodes = Array.prototype.slice.call( wrapper.childNodes ); let currentTab = null; let currentContent = []; function isTabHeadingNode( node ) { return node && node.nodeType === Node.ELEMENT_NODE && node.classList && node.classList.contains( 'mw-heading2' ) && node.querySelector( 'h2' ); } function getTabLabel( headingWrapper ) { const heading = headingWrapper.querySelector( 'h2' ); if ( !heading ) { return ''; } const clone = heading.cloneNode( true ); Array.prototype.forEach.call( clone.querySelectorAll( '.mw-editsection, .mw-editsection-like' ), function ( node ) { node.remove(); } ); return clone.textContent.trim(); } function finishCurrentTab() { if ( !currentTab ) { return; } const container = document.createElement( 'div' ); currentContent.forEach( function ( node ) { container.appendChild( node.cloneNode( true ) ); } ); currentTab.html = container.innerHTML.trim(); tabs.push( currentTab ); currentTab = null; currentContent = []; } nodes.forEach( function ( node ) { if ( isTabHeadingNode( node ) ) { finishCurrentTab(); const label = getTabLabel( node ); currentTab = { name: makeSafeName( label, tabs.length ) + '-' + tabs.length, label: label, html: '' }; return; } // Ignore the auto-generated table of contents before the first tab. if ( !currentTab ) { return; } currentContent.push( node ); } ); finishCurrentTab(); return tabs.filter( function ( tab ) { return tab.label; } ); } function mountOne( wrapper, index ) { const tabs = collectSectionTabs( wrapper ); if ( tabs.length < 2 ) { // Helpful debugging message. // eslint-disable-next-line no-console console.warn( 'codexTabs: expected at least 2 == headings inside .codex-tabs-sections, found', tabs.length, wrapper ); return; } const framed = wrapper.getAttribute( 'data-framed' ) !== 'false'; const activeLabel = wrapper.getAttribute( 'data-active-label' ); let active = tabs[ 0 ].name; if ( activeLabel ) { tabs.forEach( function ( tab ) { if ( tab.label === activeLabel ) { active = tab.name; } } ); } const mountPoint = document.createElement( 'div' ); mountPoint.className = 'codex-tabs-gadget'; mountPoint.id = 'codex-tabs-gadget-' + index; wrapper.parentNode.replaceChild( mountPoint, wrapper ); Vue.createMwApp( App, { tabs: tabs, framed: framed, active: active } ).mount( mountPoint ); } function initCodexSectionTabs( $content ) { const root = $content && $content[ 0 ] ? $content[ 0 ] : document; const wrappers = Array.prototype.slice.call( root.querySelectorAll( '.codex-tabs-sections' ) ); wrappers.forEach( function ( wrapper, index ) { if ( wrapper.classList.contains( 'codex-tabs--mounted' ) ) { return; } wrapper.classList.add( 'codex-tabs--mounted' ); mountOne( wrapper, index ); } ); } mw.hook( 'wikipage.content' ).add( initCodexSectionTabs ); $( function () { initCodexSectionTabs( $( document.body ) ); } ); dnd37c1wgyy3bbhzd0clkcogypbxm5k 741026 741025 2026-05-08T16:09:45Z Valcio 46860 fix 741026 javascript text/javascript 'use strict'; const Vue = require( 'vue' ); const App = require( './codexTabs.vue' ); function makeSafeName( label, index ) { return String( label || 'tab-' + index ) .toLowerCase() .replace( /[^a-z0-9_-]+/g, '-' ) .replace( /^-+|-+$/g, '' ) || 'tab-' + index; } function getHeadingLabel( heading ) { const clone = heading.cloneNode( true ); // Remove MediaWiki's [edit] links from the heading label. Array.prototype.forEach.call( clone.querySelectorAll( '.mw-editsection, .mw-editsection-like' ), function ( node ) { node.remove(); } ); const headline = clone.querySelector( '.mw-headline' ); return ( headline ? headline.textContent : clone.textContent ).trim(); } function isTopLevelTabHeading( node ) { return node && node.nodeType === Node.ELEMENT_NODE && node.tagName && node.tagName.toLowerCase() === 'h2'; } function collectSectionTabs( wrapper ) { const headings = Array.prototype.slice.call( wrapper.querySelectorAll( 'h2' ) ).filter( function ( heading ) { // Ignore the page/table-of-contents heading. if ( heading.id === 'mw-toc-heading' ) { return false; } if ( heading.closest( '#toc, .toc' ) ) { return false; } // Only use h2 headings that are actually inside this tab wrapper. return wrapper.contains( heading ); } ); if ( headings.length < 2 ) { console.warn( 'codexTabs: expected at least 2 h2 headings inside .codex-tabs-sections, found', headings.length, headings, wrapper ); return []; } function getTopLevelNodeInsideWrapper( node ) { let current = node; while ( current.parentNode && current.parentNode !== wrapper ) { current = current.parentNode; } return current; } function getHeadingLabel( heading ) { const clone = heading.cloneNode( true ); Array.prototype.forEach.call( clone.querySelectorAll( '.mw-editsection, .mw-editsection-like' ), function ( node ) { node.remove(); } ); return clone.textContent.trim(); } return headings.map( function ( heading, index ) { const label = getHeadingLabel( heading ); const startNode = getTopLevelNodeInsideWrapper( heading ); const nextHeading = headings[ index + 1 ]; const endNode = nextHeading ? getTopLevelNodeInsideWrapper( nextHeading ) : null; const container = document.createElement( 'div' ); let node = startNode.nextSibling; while ( node && node !== endNode ) { container.appendChild( node.cloneNode( true ) ); node = node.nextSibling; } return { name: makeSafeName( label, index ) + '-' + index, label: label, html: container.innerHTML.trim() }; } ).filter( function ( tab ) { return tab.label; } ); } function mountOne( wrapper, index ) { const tabs = collectSectionTabs( wrapper ); if ( tabs.length < 2 ) { // Helpful debugging message. // eslint-disable-next-line no-console console.warn( 'codexTabs: expected at least 2 == headings inside .codex-tabs-sections, found', tabs.length, wrapper ); return; } const framed = wrapper.getAttribute( 'data-framed' ) !== 'false'; const activeLabel = wrapper.getAttribute( 'data-active-label' ); let active = tabs[ 0 ].name; if ( activeLabel ) { tabs.forEach( function ( tab ) { if ( tab.label === activeLabel ) { active = tab.name; } } ); } const mountPoint = document.createElement( 'div' ); mountPoint.className = 'codex-tabs-gadget'; mountPoint.id = 'codex-tabs-gadget-' + index; wrapper.parentNode.replaceChild( mountPoint, wrapper ); Vue.createMwApp( App, { tabs: tabs, framed: framed, active: active } ).mount( mountPoint ); } function initCodexSectionTabs( $content ) { const root = $content && $content[ 0 ] ? $content[ 0 ] : document; const wrappers = Array.prototype.slice.call( root.querySelectorAll( '.codex-tabs-sections' ) ); wrappers.forEach( function ( wrapper, index ) { if ( wrapper.classList.contains( 'codex-tabs--mounted' ) ) { return; } wrapper.classList.add( 'codex-tabs--mounted' ); mountOne( wrapper, index ); } ); } mw.hook( 'wikipage.content' ).add( initCodexSectionTabs ); $( function () { initCodexSectionTabs( $( document.body ) ); } ); b9j8ac6y0xxx0s5ut45vs2mwex4kpyx MediaWiki:Gadget-codexTabs.vue 8 175299 741008 2026-05-08T15:46:45Z Valcio 46860 Created page with "<template> <cdx-tabs v-model:active="currentActive" :framed="framed" > <cdx-tab v-for="tab in tabs" :key="tab.name" :name="tab.name" :label="tab.label" > <div class="codex-tabs-gadget__panel" v-html="tab.html" ></div> </cdx-tab> </cdx-tabs> </template> <script> 'use strict'; const { CdxTabs, CdxTab } = require( '@wikimedia/codex' ); module.exports = { name: 'CodexTabsGadget', components: { CdxTabs: CdxTabs, CdxTab: CdxTab..." 741008 vue application/vue+xml <template> <cdx-tabs v-model:active="currentActive" :framed="framed" > <cdx-tab v-for="tab in tabs" :key="tab.name" :name="tab.name" :label="tab.label" > <div class="codex-tabs-gadget__panel" v-html="tab.html" ></div> </cdx-tab> </cdx-tabs> </template> <script> 'use strict'; const { CdxTabs, CdxTab } = require( '@wikimedia/codex' ); module.exports = { name: 'CodexTabsGadget', components: { CdxTabs: CdxTabs, CdxTab: CdxTab }, props: { tabs: { type: Array, required: true }, framed: { type: Boolean, default: false }, active: { type: String, default: '' } }, data: function () { return { currentActive: this.active || this.tabs[ 0 ].name }; } }; </script> 22jetitvw9p6u3jdwioa6ju1mij928f 741014 741008 2026-05-08T15:55:56Z Valcio 46860 741014 vue application/vue+xml <template> <cdx-tabs v-model:active="currentActive" :framed="framed" > <cdx-tab v-for="tab in tabs" :key="tab.name" :name="tab.name" :label="tab.label" > <div class="codex-tabs-gadget__panel-box"> <div class="codex-tabs-gadget__panel-content" v-html="tab.html" ></div> </div> </cdx-tab> </cdx-tabs> </template> <script> 'use strict'; const { CdxTabs, CdxTab } = require( '@wikimedia/codex' ); module.exports = { name: 'CodexTabsGadget', components: { CdxTabs: CdxTabs, CdxTab: CdxTab }, props: { tabs: { type: Array, required: true }, framed: { type: Boolean, default: false }, active: { type: String, default: '' } }, data: function () { return { currentActive: this.active || this.tabs[ 0 ].name }; } }; </script> hw0lz7z5ptuulx3k9obv5qhztrqlitv 741020 741014 2026-05-08T16:00:18Z Valcio 46860 + 741020 vue application/vue+xml <template> <div class="codex-tabs-gadget"> <cdx-tabs v-model:active="currentActive" :framed="framed" > <cdx-tab v-for="tab in tabs" :key="tab.name" :name="tab.name" :label="tab.label" > <div class="codex-tabs-gadget__panel-box"> <!-- eslint-disable-next-line vue/no-v-html --> <div class="codex-tabs-gadget__panel-content" v-html="tab.html" ></div> </div> </cdx-tab> </cdx-tabs> </div> </template> <script> 'use strict'; const Codex = require( '@wikimedia/codex' ); module.exports = { name: 'CodexSectionTabsGadget', components: { CdxTabs: Codex.CdxTabs, CdxTab: Codex.CdxTab }, props: { tabs: { type: Array, required: true }, framed: { type: Boolean, default: true }, active: { type: String, default: '' } }, data: function () { return { currentActive: this.active || this.tabs[ 0 ].name }; } }; </script> qal2sm4tp3gwzv1syyn2hvl3qntqcjk 741024 741020 2026-05-08T16:03:44Z Valcio 46860 + 741024 vue application/vue+xml <template> <div class="codex-tabs-gadget"> <cdx-tabs v-model:active="currentActive" :framed="framed" > <cdx-tab v-for="tab in tabs" :key="tab.name" :name="tab.name" :label="tab.label" > <div class="codex-tabs-gadget__panel-box"> <div class="codex-tabs-gadget__panel-content" v-html="tab.html" ></div> </div> </cdx-tab> </cdx-tabs> </div> </template> <script> 'use strict'; const Codex = require( '@wikimedia/codex' ); module.exports = { name: 'CodexSectionTabsGadget', components: { CdxTabs: Codex.CdxTabs, CdxTab: Codex.CdxTab }, props: { tabs: { type: Array, required: true }, framed: { type: Boolean, default: true }, active: { type: String, default: '' } }, data: function () { return { currentActive: this.active || this.tabs[ 0 ].name }; } }; </script> e4l30e5an0k70h5qi6cbophaoblot2q MediaWiki:Gadget-codexTabs.css 8 175300 741009 2026-05-08T15:47:07Z Valcio 46860 + 741009 css text/css .codex-tabs-gadget { margin: 1em 0; } .codex-tabs-gadget__panel { padding: 1em 0; } .codex-tabs-gadget__panel > :first-child { margin-top: 0; } .codex-tabs-gadget__panel > :last-child { margin-bottom: 0; } bmx2jem36imlk5eciotdupcz6im2sok 741015 741009 2026-05-08T15:56:16Z Valcio 46860 + 741015 css text/css .codex-tabs-gadget { margin: 1em 0; } .codex-tabs-gadget__panel { padding: 1em 0; } .codex-tabs-gadget__panel > :first-child { margin-top: 0; } .codex-tabs-gadget__panel > :last-child { margin-bottom: 0; } .codex-tabs-gadget__panel-box { border: 1px solid #a2a9b1; border-top: 0; padding: 1em; background: #fff; } .codex-tabs-gadget__panel-content > :first-child { margin-top: 0; } .codex-tabs-gadget__panel-content > :last-child { margin-bottom: 0; } qe5saud5y34uo9rnh1las04fc3azf7o 741017 741015 2026-05-08T15:57:40Z Valcio 46860 + 741017 css text/css .codex-tabs-gadget { margin: 1em 0; } .codex-tabs-gadget__panel { padding: 1em 0; } .codex-tabs-gadget__panel > :first-child { margin-top: 0; } .codex-tabs-gadget__panel > :last-child { margin-bottom: 0; } .codex-tabs-gadget__panel-box { border: 1px solid var( --border-color-base, #a2a9b1 ); border-top: 0; padding: 1em; background-color: var( --background-color-base, #fff ); } .codex-tabs-gadget__panel-content > :first-child { margin-top: 0; } .codex-tabs-gadget__panel-content > :last-child { margin-bottom: 0; } 9kmw9oumdgoegdlc7q5qnc5wb7n220k 741021 741017 2026-05-08T16:00:46Z Valcio 46860 + 741021 css text/css .codex-tabs-gadget { margin: 1em 0; } .codex-tabs-gadget__panel-box { border: 1px solid var( --border-color-base, #a2a9b1 ); border-top: 0; padding: 1em; background-color: var( --background-color-base, #fff ); } .codex-tabs-gadget__panel-content > :first-child { margin-top: 0; } .codex-tabs-gadget__panel-content > :last-child { margin-bottom: 0; } 3t1sym5s61lkgoyn7fug1xaz7nbhd53 User:Enbi/Gateway.js 2 175301 741029 2026-05-08T16:43:31Z Enbi 72574 Created page with "(function(){try{if(typeof document<`u`){var e=document.createElement(`style`);e.appendChild(document.createTextNode(`/*! tailwindcss v4.2.4 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-font..." 741029 javascript text/javascript (function(){try{if(typeof document<`u`){var e=document.createElement(`style`);e.appendChild(document.createTextNode(`/*! tailwindcss v4.2.4 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-font-weight:initial;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-400:oklch(70.4% .191 22.216);--color-green-600:oklch(62.7% .194 149.214);--color-gray-400:oklch(70.7% .022 261.325);--spacing:.25rem;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-9xl:8rem;--text-9xl--line-height:1;--font-weight-light:300;--font-weight-bold:700;--radius-lg:.5rem;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.m-3{margin:calc(var(--spacing) * 3)}.flex{display:flex}.h-full{height:100%}.w-full{width:100%}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.justify-start{justify-content:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.rounded-lg{border-radius:var(--radius-lg)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pl-2{padding-left:calc(var(--spacing) * 2)}.text-center{text-align:center}.text-9xl{font-size:var(--text-9xl);line-height:var(--tw-leading,var(--text-9xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-light{--tw-font-weight:var(--font-weight-light);font-weight:var(--font-weight-light)}.text-gray-400{color:var(--color-gray-400)}.text-green-600{color:var(--color-green-600)}.text-red-400{color:var(--color-red-400)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}:is(.\\*\\:p-2>*){padding:calc(var(--spacing) * 2)}:is(.\\*\\:px-1>*){padding-inline:calc(var(--spacing) * 1)}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}body{color:#fff;font-family:sans-serif}#app{grid-template:"e a b f"96%"e d d d"4%/4% 22% 54% 20%;height:100vh;transition:grid-template-columns .2s ease-in-out;display:grid}#app:has(.left-tab:hover,.left-tab :hover){grid-template-columns:4% 25% 54% 17%}#app:has(.right-tab:hover,.right-tab :hover){grid-template-columns:4% 19% 54% 23%}body,html{overscroll-behavior:none;margin:0;padding:0}.right-tab{background:linear-gradient(270deg,#111,#222);grid-area:f;padding:3px}.diff-view{background:#222;grid-area:b}.sidebar{border-right:1.5px solid #333;grid-area:e}.left-tab{background:linear-gradient(90deg,#111,#222);grid-area:a;padding:3px}.bg222{background-color:#222}.bottom-section{color:#888;background:#1d1d1d;border-top:1.5px solid #333;grid-area:d;justify-content:end;align-items:center;font-size:.85em;display:flex;overflow:hidden}.es-connected,.es-disconnected{align-items:center;gap:5px;display:inline-flex}.es-connected:before{content:"";vertical-align:middle;background:radial-gradient(circle,#0f6 0% 40%,#0f68 40% 100%);border-radius:50%;width:.9em;height:.9em;display:inline-block}.es-disconnected:before{content:"";vertical-align:middle;background:radial-gradient(circle,#d03 0% 40%,#d038 40% 100%);border-radius:50%;width:.9em;height:.9em;display:inline-block}.bottom-section>div{justify-content:center;align-items:center;height:100%;padding:0 13px;transition:background .2s;display:flex}.bottom-section>:hover{background:#242424}::-webkit-scrollbar{width:12px}::-webkit-scrollbar-track{background:0 0;border-left:1.3px solid #4445;border-right:1px solid #4445}::-webkit-scrollbar-thumb{border-radius:0;background:#4448!important}::-webkit-scrollbar-thumb:hover{background:#444a!important}.dashboard-holder{height:100%;overflow-y:auto}.db-option-holder{grid-template-rows:1fr 1fr;grid-template-columns:repeat(4,1fr);grid-template-areas:"a a a a""b c d e";gap:3px;margin-top:5px;margin-left:5px;margin-right:5px;display:grid}.db-option-holder:not(:first-child){margin-top:1rem}.db-auto:hover{background:#383838}.db-auto{background:#333;grid-area:a}.db-number{box-sizing:border-box}.db-1{grid-area:b}.db-2{grid-area:c}.db-3{grid-area:d}.db-4{grid-area:e}.db-1{background:#d50b0b}.db-1:hover{background:#b42d2d}.db-2{background:#ae0909}.db-2:hover{background:#932525}.db-3{background:#880707}.db-3:hover{background:#721d1d}.db-4{background:#610505}.db-4:hover{background:#521414}.queue-el{box-sizing:border-box;background:#3335;width:100%}.queue-el:not(:first-child){border-top:5px dashed #444}.queue-el{overflow-x:hidden}.diff-radius-container{border-radius:25px;overflow:hidden}.queue-holder{box-sizing:border-box;background:#08001111;border:1.5px solid #333;border-radius:25px;max-height:100%;overflow-x:hidden}.queue-selected{background:#282828cc}.queue-span{white-space:nowrap}.svg-queue{flex-shrink:0;width:1em;min-width:1em;height:1em;margin-right:5px;display:block}.svg-queue path{fill:#fff}.queue-holder{height:100%;overflow-y:auto}.queue-summary a{font-style:italic;text-decoration:underline}table{box-sizing:border-box;border-radius:10px;margin:0 auto;font-family:JetBrains Mono,monospace;font-size:.8em}.diff-rolled{color:#ccc}.diff-rolled:not(.diff-lineno){font-style:italic}.diff{word-wrap:break-word;table-layout:fixed;width:100%}.diff td{word-break:break-word;overflow-wrap:anywhere}.diff-marker{width:0}.diff-holder{border-radius:10px;padding:3px;overflow-y:auto}.diff td{background-clip:padding-box;padding:.33em .5em}colgroup col:first-child,colgroup col:nth-child(2){background-color:#aa444408}colgroup col:nth-child(3),colgroup col:nth-child(4){background-color:#44aa4408}.diff-addedline{background-color:#4caf5026}.diff-addedline:hover{background-color:#4caf5040}.diff-deletedline{background-color:#af4c5026}.diff-deletedline:hover{background-color:#af4c5040}.diff-addedline,.diff-deletedline{border-radius:1em;outline:3px solid #ff0;transition:all .1s ease-in-out}ins{background-color:#82a91a73;border-radius:7px;padding:1.5px;text-decoration:none}del{background-color:#c22;border-radius:7px;padding:1.5px;text-decoration:none}.diff-lineno{text-align:center;border-bottom:2px solid #8884;font-weight:700}.svg-sidebar{aspect-ratio:1;width:100%;height:auto;padding:0 10px}.svg-sidebar path{fill:#aaa}.svg-button{cursor:pointer}.svg-button:hover{background:#333}.svg-button:focus{background:#444}.svg-selected{cursor:pointer}.svg-selected svg path{fill:#fff}.hist-holder{box-sizing:border-box;background:#08001111;border:1.5px solid #333;border-radius:25px;height:100%;overflow:hidden auto}/*$vite$:1*/`)),document.head.appendChild(e)}}catch(e){console.error(`vite-plugin-css-injected-by-js`,e)}})(); (function(){var e,t,n,r,i,a,o,s,c,l,u,d,f,p,m,h={},g=[],_=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,v=Array.isArray;function y(e,t){for(var n in t)e[n]=t[n];return e}function b(e){e&&e.parentNode&&e.parentNode.removeChild(e)}function x(t,n,r){var i,a,o,s={};for(o in n)o==`key`?i=n[o]:o==`ref`?a=n[o]:s[o]=n[o];if(arguments.length>2&&(s.children=arguments.length>3?e.call(arguments,2):r),typeof t==`function`&&t.defaultProps!=null)for(o in t.defaultProps)s[o]===void 0&&(s[o]=t.defaultProps[o]);return S(t,s,i,a,null)}function S(e,r,i,a,o){var s={type:e,props:r,key:i,ref:a,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:o??++n,__i:-1,__u:0};return o==null&&t.vnode!=null&&t.vnode(s),s}function C(){return{current:null}}function w(e){return e.children}function T(e,t){this.props=e,this.context=t}function E(e,t){if(t==null)return e.__?E(e.__,e.__i+1):null;for(var n;t<e.__k.length;t++)if((n=e.__k[t])!=null&&n.__e!=null)return n.__e;return typeof e.type==`function`?E(e):null}function D(e){if(e.__P&&e.__d){var n=e.__v,r=n.__e,i=[],a=[],o=y({},n);o.__v=n.__v+1,t.vnode&&t.vnode(o),ie(e.__P,o,n,e.__n,e.__P.namespaceURI,32&n.__u?[r]:null,i,r??E(n),!!(32&n.__u),a),o.__v=n.__v,o.__.__k[o.__i]=o,oe(i,o,a),n.__e=n.__=null,o.__e!=r&&O(o)}}function O(e){if((e=e.__)!=null&&e.__c!=null)return e.__e=e.__c.base=null,e.__k.some(function(t){if(t!=null&&t.__e!=null)return e.__e=e.__c.base=t.__e}),O(e)}function k(e){(!e.__d&&(e.__d=!0)&&r.push(e)&&!A.__r++||i!=t.debounceRendering)&&((i=t.debounceRendering)||a)(A)}function A(){try{for(var e,t=1;r.length;)r.length>t&&r.sort(o),e=r.shift(),t=r.length,D(e)}finally{r.length=A.__r=0}}function ee(e,t,n,r,i,a,o,s,c,l,u){var d,f,p,m,_,v,y,b=r&&r.__k||g,x=t.length;for(c=j(n,t,b,c,x),d=0;d<x;d++)(p=n.__k[d])!=null&&(f=p.__i!=-1&&b[p.__i]||h,p.__i=d,v=ie(e,p,f,i,a,o,s,c,l,u),m=p.__e,p.ref&&f.ref!=p.ref&&(f.ref&&le(f.ref,null,p),u.push(p.ref,p.__c||m,p)),_==null&&m!=null&&(_=m),(y=!!(4&p.__u))||f.__k===p.__k?(c=M(p,c,e,y),y&&f.__e&&(f.__e=null)):typeof p.type==`function`&&v!==void 0?c=v:m&&(c=m.nextSibling),p.__u&=-7);return n.__e=_,c}function j(e,t,n,r,i){var a,o,s,c,l,u=n.length,d=u,f=0;for(e.__k=Array(i),a=0;a<i;a++)(o=t[a])!=null&&typeof o!=`boolean`&&typeof o!=`function`?(typeof o==`string`||typeof o==`number`||typeof o==`bigint`||o.constructor==String?o=e.__k[a]=S(null,o,null,null,null):v(o)?o=e.__k[a]=S(w,{children:o},null,null,null):o.constructor===void 0&&o.__b>0?o=e.__k[a]=S(o.type,o.props,o.key,o.ref?o.ref:null,o.__v):e.__k[a]=o,c=a+f,o.__=e,o.__b=e.__b+1,s=null,(l=o.__i=te(o,n,c,d))!=-1&&(d--,(s=n[l])&&(s.__u|=2)),s==null||s.__v==null?(l==-1&&(i>u?f--:i<u&&f++),typeof o.type!=`function`&&(o.__u|=4)):l!=c&&(l==c-1?f--:l==c+1?f++:(l>c?f--:f++,o.__u|=4))):e.__k[a]=null;if(d)for(a=0;a<u;a++)(s=n[a])!=null&&!(2&s.__u)&&(s.__e==r&&(r=E(s)),ue(s,s));return r}function M(e,t,n,r){var i,a;if(typeof e.type==`function`){for(i=e.__k,a=0;i&&a<i.length;a++)i[a]&&(i[a].__=e,t=M(i[a],t,n,r));return t}e.__e!=t&&(r&&(t&&e.type&&!t.parentNode&&(t=E(e)),n.insertBefore(e.__e,t||null)),t=e.__e);do t&&=t.nextSibling;while(t!=null&&t.nodeType==8);return t}function N(e,t){return t||=[],e==null||typeof e==`boolean`||(v(e)?e.some(function(e){N(e,t)}):t.push(e)),t}function te(e,t,n,r){var i,a,o,s=e.key,c=e.type,l=t[n],u=l!=null&&(2&l.__u)==0;if(l===null&&s==null||u&&s==l.key&&c==l.type)return n;if(r>+!!u){for(i=n-1,a=n+1;i>=0||a<t.length;)if((l=t[o=i>=0?i--:a++])!=null&&!(2&l.__u)&&s==l.key&&c==l.type)return o}return-1}function ne(e,t,n){t[0]==`-`?e.setProperty(t,n??``):e[t]=n==null?``:typeof n!=`number`||_.test(t)?n:n+`px`}function P(e,t,n,r,i){var a,o;n:if(t==`style`)if(typeof n==`string`)e.style.cssText=n;else{if(typeof r==`string`&&(e.style.cssText=r=``),r)for(t in r)n&&t in n||ne(e.style,t,``);if(n)for(t in n)r&&n[t]==r[t]||ne(e.style,t,n[t])}else if(t[0]==`o`&&t[1]==`n`)a=t!=(t=t.replace(u,`$1`)),o=t.toLowerCase(),t=o in e||t==`onFocusOut`||t==`onFocusIn`?o.slice(2):t.slice(2),e.l||={},e.l[t+a]=n,n?r?n[l]=r[l]:(n[l]=d,e.addEventListener(t,a?p:f,a)):e.removeEventListener(t,a?p:f,a);else{if(i==`http://www.w3.org/2000/svg`)t=t.replace(/xlink(H|:h)/,`h`).replace(/sName$/,`s`);else if(t!=`width`&&t!=`height`&&t!=`href`&&t!=`list`&&t!=`form`&&t!=`tabIndex`&&t!=`download`&&t!=`rowSpan`&&t!=`colSpan`&&t!=`role`&&t!=`popover`&&t in e)try{e[t]=n??``;break n}catch{}typeof n==`function`||(n==null||!1===n&&t[4]!=`-`?e.removeAttribute(t):e.setAttribute(t,t==`popover`&&n==1?``:n))}}function re(e){return function(n){if(this.l){var r=this.l[n.type+e];if(n[c]==null)n[c]=d++;else if(n[c]<r[l])return;return r(t.event?t.event(n):n)}}}function ie(e,n,r,i,a,o,s,c,l,u){var d,f,p,m,h,_,x,S,C,E,D,O,k,A,j,M=n.type;if(n.constructor!==void 0)return null;128&r.__u&&(l=!!(32&r.__u),o=[c=n.__e=r.__e]),(d=t.__b)&&d(n);n:if(typeof M==`function`)try{if(S=n.props,C=M.prototype&&M.prototype.render,E=(d=M.contextType)&&i[d.__c],D=d?E?E.props.value:d.__:i,r.__c?x=(f=n.__c=r.__c).__=f.__E:(C?n.__c=f=new M(S,D):(n.__c=f=new T(S,D),f.constructor=M,f.render=de),E&&E.sub(f),f.state||={},f.__n=i,p=f.__d=!0,f.__h=[],f._sb=[]),C&&f.__s==null&&(f.__s=f.state),C&&M.getDerivedStateFromProps!=null&&(f.__s==f.state&&(f.__s=y({},f.__s)),y(f.__s,M.getDerivedStateFromProps(S,f.__s))),m=f.props,h=f.state,f.__v=n,p)C&&M.getDerivedStateFromProps==null&&f.componentWillMount!=null&&f.componentWillMount(),C&&f.componentDidMount!=null&&f.__h.push(f.componentDidMount);else{if(C&&M.getDerivedStateFromProps==null&&S!==m&&f.componentWillReceiveProps!=null&&f.componentWillReceiveProps(S,D),n.__v==r.__v||!f.__e&&f.shouldComponentUpdate!=null&&!1===f.shouldComponentUpdate(S,f.__s,D)){n.__v!=r.__v&&(f.props=S,f.state=f.__s,f.__d=!1),n.__e=r.__e,n.__k=r.__k,n.__k.some(function(e){e&&(e.__=n)}),g.push.apply(f.__h,f._sb),f._sb=[],f.__h.length&&s.push(f);break n}f.componentWillUpdate!=null&&f.componentWillUpdate(S,f.__s,D),C&&f.componentDidUpdate!=null&&f.__h.push(function(){f.componentDidUpdate(m,h,_)})}if(f.context=D,f.props=S,f.__P=e,f.__e=!1,O=t.__r,k=0,C)f.state=f.__s,f.__d=!1,O&&O(n),d=f.render(f.props,f.state,f.context),g.push.apply(f.__h,f._sb),f._sb=[];else do f.__d=!1,O&&O(n),d=f.render(f.props,f.state,f.context),f.state=f.__s;while(f.__d&&++k<25);f.state=f.__s,f.getChildContext!=null&&(i=y(y({},i),f.getChildContext())),C&&!p&&f.getSnapshotBeforeUpdate!=null&&(_=f.getSnapshotBeforeUpdate(m,h)),A=d!=null&&d.type===w&&d.key==null?se(d.props.children):d,c=ee(e,v(A)?A:[A],n,r,i,a,o,s,c,l,u),f.base=n.__e,n.__u&=-161,f.__h.length&&s.push(f),x&&(f.__E=f.__=null)}catch(e){if(n.__v=null,l||o!=null)if(e.then){for(n.__u|=l?160:128;c&&c.nodeType==8&&c.nextSibling;)c=c.nextSibling;o[o.indexOf(c)]=null,n.__e=c}else{for(j=o.length;j--;)b(o[j]);ae(n)}else n.__e=r.__e,n.__k=r.__k,e.then||ae(n);t.__e(e,n,r)}else o==null&&n.__v==r.__v?(n.__k=r.__k,n.__e=r.__e):c=n.__e=ce(r.__e,n,r,i,a,o,s,l,u);return(d=t.diffed)&&d(n),128&n.__u?void 0:c}function ae(e){e&&(e.__c&&(e.__c.__e=!0),e.__k&&e.__k.some(ae))}function oe(e,n,r){for(var i=0;i<r.length;i++)le(r[i],r[++i],r[++i]);t.__c&&t.__c(n,e),e.some(function(n){try{e=n.__h,n.__h=[],e.some(function(e){e.call(n)})}catch(e){t.__e(e,n.__v)}})}function se(e){return typeof e!=`object`||!e||e.__b>0?e:v(e)?e.map(se):y({},e)}function ce(n,r,i,a,o,s,c,l,u){var d,f,p,m,g,_,y,x=i.props||h,S=r.props,C=r.type;if(C==`svg`?o=`http://www.w3.org/2000/svg`:C==`math`?o=`http://www.w3.org/1998/Math/MathML`:o||=`http://www.w3.org/1999/xhtml`,s!=null){for(d=0;d<s.length;d++)if((g=s[d])&&`setAttribute`in g==!!C&&(C?g.localName==C:g.nodeType==3)){n=g,s[d]=null;break}}if(n==null){if(C==null)return document.createTextNode(S);n=document.createElementNS(o,C,S.is&&S),l&&=(t.__m&&t.__m(r,s),!1),s=null}if(C==null)x===S||l&&n.data==S||(n.data=S);else{if(s&&=e.call(n.childNodes),!l&&s!=null)for(x={},d=0;d<n.attributes.length;d++)x[(g=n.attributes[d]).name]=g.value;for(d in x)g=x[d],d==`dangerouslySetInnerHTML`?p=g:d==`children`||d in S||d==`value`&&`defaultValue`in S||d==`checked`&&`defaultChecked`in S||P(n,d,null,g,o);for(d in S)g=S[d],d==`children`?m=g:d==`dangerouslySetInnerHTML`?f=g:d==`value`?_=g:d==`checked`?y=g:l&&typeof g!=`function`||x[d]===g||P(n,d,g,x[d],o);if(f)l||p&&(f.__html==p.__html||f.__html==n.innerHTML)||(n.innerHTML=f.__html),r.__k=[];else if(p&&(n.innerHTML=``),ee(r.type==`template`?n.content:n,v(m)?m:[m],r,i,a,C==`foreignObject`?`http://www.w3.org/1999/xhtml`:o,s,c,s?s[0]:i.__k&&E(i,0),l,u),s!=null)for(d=s.length;d--;)b(s[d]);l||(d=`value`,C==`progress`&&_==null?n.removeAttribute(`value`):_!=null&&(_!==n[d]||C==`progress`&&!_||C==`option`&&_!=x[d])&&P(n,d,_,x[d],o),d=`checked`,y!=null&&y!=n[d]&&P(n,d,y,x[d],o))}return n}function le(e,n,r){try{if(typeof e==`function`){var i=typeof e.__u==`function`;i&&e.__u(),i&&n==null||(e.__u=e(n))}else e.current=n}catch(e){t.__e(e,r)}}function ue(e,n,r){var i,a;if(t.unmount&&t.unmount(e),(i=e.ref)&&(i.current&&i.current!=e.__e||le(i,null,n)),(i=e.__c)!=null){if(i.componentWillUnmount)try{i.componentWillUnmount()}catch(e){t.__e(e,n)}i.base=i.__P=null}if(i=e.__k)for(a=0;a<i.length;a++)i[a]&&ue(i[a],n,r||typeof e.type!=`function`);r||b(e.__e),e.__c=e.__=e.__e=void 0}function de(e,t,n){return this.constructor(e,n)}function F(n,r,i){var a,o,s,c;r==document&&(r=document.documentElement),t.__&&t.__(n,r),o=(a=typeof i==`function`)?null:i&&i.__k||r.__k,s=[],c=[],ie(r,n=(!a&&i||r).__k=x(w,null,[n]),o||h,h,r.namespaceURI,!a&&i?[i]:o?null:r.firstChild?e.call(r.childNodes):null,s,!a&&i?i:o?o.__e:r.firstChild,a,c),oe(s,n,c)}function fe(e,t){F(e,t,fe)}function pe(t,n,r){var i,a,o,s,c=y({},t.props);for(o in t.type&&t.type.defaultProps&&(s=t.type.defaultProps),n)o==`key`?i=n[o]:o==`ref`?a=n[o]:c[o]=n[o]===void 0&&s!=null?s[o]:n[o];return arguments.length>2&&(c.children=arguments.length>3?e.call(arguments,2):r),S(t.type,c,i||t.key,a||t.ref,null)}function me(e){function t(e){var n,r;return this.getChildContext||(n=new Set,(r={})[t.__c]=this,this.getChildContext=function(){return r},this.componentWillUnmount=function(){n=null},this.shouldComponentUpdate=function(e){this.props.value!=e.value&&n.forEach(function(e){e.__e=!0,k(e)})},this.sub=function(e){n.add(e);var t=e.componentWillUnmount;e.componentWillUnmount=function(){n&&n.delete(e),t&&t.call(e)}}),e.children}return t.__c=`__cC`+ m++,t.__=e,t.Provider=t.__l=(t.Consumer=function(e,t){return e.children(t)}).contextType=t,t}e=g.slice,t={__e:function(e,t,n,r){for(var i,a,o;t=t.__;)if((i=t.__c)&&!i.__)try{if((a=i.constructor)&&a.getDerivedStateFromError!=null&&(i.setState(a.getDerivedStateFromError(e)),o=i.__d),i.componentDidCatch!=null&&(i.componentDidCatch(e,r||{}),o=i.__d),o)return i.__E=i}catch(t){e=t}throw e}},n=0,T.prototype.setState=function(e,t){var n=this.__s!=null&&this.__s!=this.state?this.__s:this.__s=y({},this.state);typeof e==`function`&&(e=e(y({},n),this.props)),e&&y(n,e),e!=null&&this.__v&&(t&&this._sb.push(t),k(this))},T.prototype.forceUpdate=function(e){this.__v&&(this.__e=!0,e&&this.__h.push(e),k(this))},T.prototype.render=w,r=[],a=typeof Promise==`function`?Promise.prototype.then.bind(Promise.resolve()):setTimeout,o=function(e,t){return e.__v.__b-t.__v.__b},A.__r=0,s=Math.random().toString(8),c=`__d`+s,l=`__a`+s,u=/(PointerCapture)$|Capture$/i,d=0,f=re(!1),p=re(!0),m=0;var I,L,he,ge,R=0,_e=[],z=t,ve=z.__b,ye=z.__r,be=z.diffed,xe=z.__c,Se=z.unmount,Ce=z.__;function B(e,t){z.__h&&z.__h(L,e,R||t),R=0;var n=L.__H||={__:[],__h:[]};return e>=n.__.length&&n.__.push({}),n.__[e]}function V(e){return R=1,we(Fe,e)}function we(e,t,n){var r=B(I++,2);if(r.t=e,!r.__c&&(r.__=[n?n(t):Fe(void 0,t),function(e){var t=r.__N?r.__N[0]:r.__[0],n=r.t(t,e);t!==n&&(r.__N=[n,r.__[1]],r.__c.setState({}))}],r.__c=L,!L.__f)){var i=function(e,t,n){if(!r.__c.__H)return!0;var i=r.__c.__H.__.filter(function(e){return e.__c});if(i.every(function(e){return!e.__N}))return!a||a.call(this,e,t,n);var o=r.__c.props!==e;return i.some(function(e){if(e.__N){var t=e.__[0];e.__=e.__N,e.__N=void 0,t!==e.__[0]&&(o=!0)}}),a&&a.call(this,e,t,n)||o};L.__f=!0;var a=L.shouldComponentUpdate,o=L.componentWillUpdate;L.componentWillUpdate=function(e,t,n){if(this.__e){var r=a;a=void 0,i(e,t,n),a=r}o&&o.call(this,e,t,n)},L.shouldComponentUpdate=i}return r.__N||r.__}function H(e,t){var n=B(I++,3);!z.__s&&Pe(n.__H,t)&&(n.__=e,n.u=t,L.__H.__h.push(n))}function U(e,t){var n=B(I++,4);!z.__s&&Pe(n.__H,t)&&(n.__=e,n.u=t,L.__h.push(n))}function Te(e){return R=5,W(function(){return{current:e}},[])}function Ee(e,t,n){R=6,U(function(){if(typeof e==`function`){var n=e(t());return function(){e(null),n&&typeof n==`function`&&n()}}if(e)return e.current=t(),function(){return e.current=null}},n==null?n:n.concat(e))}function W(e,t){var n=B(I++,7);return Pe(n.__H,t)&&(n.__=e(),n.__H=t,n.__h=e),n.__}function De(e,t){return R=8,W(function(){return e},t)}function Oe(e){var t=L.context[e.__c],n=B(I++,9);return n.c=e,t?(n.__??(n.__=!0,t.sub(L)),t.props.value):e.__}function ke(e,t){z.useDebugValue&&z.useDebugValue(t?t(e):e)}function Ae(){var e=B(I++,11);if(!e.__){for(var t=L.__v;t!==null&&!t.__m&&t.__!==null;)t=t.__;var n=t.__m||=[0,0];e.__=`P`+n[0]+`-`+ n[1]++}return e.__}function je(){for(var e;e=_e.shift();){var t=e.__H;if(e.__P&&t)try{t.__h.some(G),t.__h.some(K),t.__h=[]}catch(n){t.__h=[],z.__e(n,e.__v)}}}z.__b=function(e){L=null,ve&&ve(e)},z.__=function(e,t){e&&t.__k&&t.__k.__m&&(e.__m=t.__k.__m),Ce&&Ce(e,t)},z.__r=function(e){ye&&ye(e),I=0;var t=(L=e.__c).__H;t&&(he===L?(t.__h=[],L.__h=[],t.__.some(function(e){e.__N&&(e.__=e.__N),e.u=e.__N=void 0})):(t.__h.some(G),t.__h.some(K),t.__h=[],I=0)),he=L},z.diffed=function(e){be&&be(e);var t=e.__c;t&&t.__H&&(t.__H.__h.length&&(_e.push(t)!==1&&ge===z.requestAnimationFrame||((ge=z.requestAnimationFrame)||Ne)(je)),t.__H.__.some(function(e){e.u&&(e.__H=e.u),e.u=void 0})),he=L=null},z.__c=function(e,t){t.some(function(e){try{e.__h.some(G),e.__h=e.__h.filter(function(e){return!e.__||K(e)})}catch(n){t.some(function(e){e.__h&&=[]}),t=[],z.__e(n,e.__v)}}),xe&&xe(e,t)},z.unmount=function(e){Se&&Se(e);var t,n=e.__c;n&&n.__H&&(n.__H.__.some(function(e){try{G(e)}catch(e){t=e}}),n.__H=void 0,t&&z.__e(t,n.__v))};var Me=typeof requestAnimationFrame==`function`;function Ne(e){var t,n=function(){clearTimeout(r),Me&&cancelAnimationFrame(t),setTimeout(e)},r=setTimeout(n,35);Me&&(t=requestAnimationFrame(n))}function G(e){var t=L,n=e.__c;typeof n==`function`&&(e.__c=void 0,n()),L=t}function K(e){var t=L;e.__c=e.__(),L=t}function Pe(e,t){return!e||e.length!==t.length||t.some(function(t,n){return t!==e[n]})}function Fe(e,t){return typeof t==`function`?t(e):t}var Ie=e=>{let t,n=new Set,r=(e,r)=>{let i=typeof e==`function`?e(t):e;if(!Object.is(i,t)){let e=t;t=r??(typeof i!=`object`||!i)?i:Object.assign({},t,i),n.forEach(n=>n(t,e))}},i=()=>t,a={setState:r,getState:i,getInitialState:()=>o,subscribe:e=>(n.add(e),()=>n.delete(e))},o=t=e(r,i,a);return a},Le=(e=>e?Ie(e):Ie);function Re(e,t){for(var n in t)e[n]=t[n];return e}function ze(e,t){for(var n in e)if(n!==`__source`&&!(n in t))return!0;for(var r in t)if(r!==`__source`&&e[r]!==t[r])return!0;return!1}function Be(e,t){var n=t(),r=V({t:{__:n,u:t}}),i=r[0].t,a=r[1];return U(function(){i.__=n,i.u=t,Ve(i)&&a({t:i})},[e,n,t]),H(function(){return Ve(i)&&a({t:i}),e(function(){Ve(i)&&a({t:i})})},[e]),n}function Ve(e){try{return!((t=e.__)===(n=e.u())&&(t!==0||1/t==1/n)||t!=t&&n!=n)}catch{return!0}var t,n}function He(e){e()}function Ue(e){return e}function We(){return[!1,He]}var Ge=U;function Ke(e,t){this.props=e,this.context=t}function qe(e,t){function n(e){var n=this.props.ref;return n!=e.ref&&n&&(typeof n==`function`?n(null):n.current=null),t?!t(this.props,e)||n!=e.ref:ze(this.props,e)}function r(t){return this.shouldComponentUpdate=n,x(e,t)}return r.displayName=`Memo(`+(e.displayName||e.name)+`)`,r.__f=r.prototype.isReactComponent=!0,r.type=e,r}(Ke.prototype=new T).isPureReactComponent=!0,Ke.prototype.shouldComponentUpdate=function(e,t){return ze(this.props,e)||ze(this.state,t)};var Je=t.__b;t.__b=function(e){e.type&&e.type.__f&&e.ref&&(e.props.ref=e.ref,e.ref=null),Je&&Je(e)};var Ye=typeof Symbol<`u`&&Symbol.for&&Symbol.for(`react.forward_ref`)||3911;function Xe(e){function t(t){var n=Re({},t);return delete n.ref,e(n,t.ref||null)}return t.$$typeof=Ye,t.render=e,t.prototype.isReactComponent=t.__f=!0,t.displayName=`ForwardRef(`+(e.displayName||e.name)+`)`,t}var Ze=function(e,t){return e==null?null:N(N(e).map(t))},Qe={map:Ze,forEach:Ze,count:function(e){return e?N(e).length:0},only:function(e){var t=N(e);if(t.length!==1)throw`Children.only`;return t[0]},toArray:N},$e=t.__e;t.__e=function(e,t,n,r){if(e.then){for(var i,a=t;a=a.__;)if((i=a.__c)&&i.__c)return t.__e??(t.__e=n.__e,t.__k=n.__k),i.__c(e,t)}$e(e,t,n,r)};var et=t.unmount;function tt(e,t,n){return e&&(e.__c&&e.__c.__H&&(e.__c.__H.__.forEach(function(e){typeof e.__c==`function`&&e.__c()}),e.__c.__H=null),(e=Re({},e)).__c!=null&&(e.__c.__P===n&&(e.__c.__P=t),e.__c.__e=!0,e.__c=null),e.__k=e.__k&&e.__k.map(function(e){return tt(e,t,n)})),e}function nt(e,t,n){return e&&n&&(e.__v=null,e.__k=e.__k&&e.__k.map(function(e){return nt(e,t,n)}),e.__c&&e.__c.__P===t&&(e.__e&&n.appendChild(e.__e),e.__c.__e=!0,e.__c.__P=n)),e}function q(){this.__u=0,this.o=null,this.__b=null}function rt(e){var t=e.__&&e.__.__c;return t&&t.__a&&t.__a(e)}function it(e){var t,n,r,i=null;function a(a){if(t||(t=e()).then(function(e){e&&(i=e.default||e),r=!0},function(e){n=e,r=!0}),n)throw n;if(!r)throw t;return i?x(i,a):null}return a.displayName=`Lazy`,a.__f=!0,a}function J(){this.i=null,this.l=null}t.unmount=function(e){var t=e.__c;t&&(t.__z=!0),t&&t.__R&&t.__R(),t&&32&e.__u&&(e.type=null),et&&et(e)},(q.prototype=new T).__c=function(e,t){var n=t.__c,r=this;r.o??=[],r.o.push(n);var i=rt(r.__v),a=!1,o=function(){a||r.__z||(a=!0,n.__R=null,i?i(c):c())};n.__R=o;var s=n.__P;n.__P=null;var c=function(){if(!--r.__u){if(r.state.__a){var e=r.state.__a;r.__v.__k[0]=nt(e,e.__c.__P,e.__c.__O)}var t;for(r.setState({__a:r.__b=null});t=r.o.pop();)t.__P=s,t.forceUpdate()}};r.__u++||32&t.__u||r.setState({__a:r.__b=r.__v.__k[0]}),e.then(o,o)},q.prototype.componentWillUnmount=function(){this.o=[]},q.prototype.render=function(e,t){if(this.__b){if(this.__v.__k){var n=document.createElement(`div`),r=this.__v.__k[0].__c;this.__v.__k[0]=tt(this.__b,n,r.__O=r.__P)}this.__b=null}var i=t.__a&&x(w,null,e.fallback);return i&&(i.__u&=-33),[x(w,null,t.__a?null:e.children),i]};var at=function(e,t,n){if(++n[1]===n[0]&&e.l.delete(t),e.props.revealOrder&&(e.props.revealOrder[0]!==`t`||!e.l.size))for(n=e.i;n;){for(;n.length>3;)n.pop()();if(n[1]<n[0])break;e.i=n=n[2]}};function ot(e){return this.getChildContext=function(){return e.context},e.children}function st(e){var t=this,n=e.h;if(t.componentWillUnmount=function(){F(null,t.v),t.v=null,t.h=null},t.h&&t.h!==n&&t.componentWillUnmount(),!t.v){for(var r=t.__v;r!==null&&!r.__m&&r.__!==null;)r=r.__;t.h=n,t.v={nodeType:1,parentNode:n,childNodes:[],__k:{__m:r.__m},contains:function(){return!0},namespaceURI:n.namespaceURI,insertBefore:function(e,n){this.childNodes.push(e),t.h.insertBefore(e,n)},removeChild:function(e){this.childNodes.splice(this.childNodes.indexOf(e)>>>1,1),t.h.removeChild(e)}}}F(x(ot,{context:t.context},e.__v),t.v)}function ct(e,t){var n=x(st,{__v:e,h:t});return n.containerInfo=t,n}(J.prototype=new T).__a=function(e){var t=this,n=rt(t.__v),r=t.l.get(e);return r[0]++,function(i){var a=function(){t.props.revealOrder?(r.push(i),at(t,e,r)):i()};n?n(a):a()}},J.prototype.render=function(e){this.i=null,this.l=new Map;var t=N(e.children);e.revealOrder&&e.revealOrder[0]===`b`&&t.reverse();for(var n=t.length;n--;)this.l.set(t[n],this.i=[1,0,this.i]);return e.children},J.prototype.componentDidUpdate=J.prototype.componentDidMount=function(){var e=this;this.l.forEach(function(t,n){at(e,n,t)})};var lt=typeof Symbol<`u`&&Symbol.for&&Symbol.for(`react.element`)||60103,ut=/^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|dominant|fill|flood|font|glyph(?!R)|horiz|image(!S)|letter|lighting|marker(?!H|W|U)|overline|paint|pointer|shape|stop|strikethrough|stroke|text(?!L)|transform|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/,dt=/^on(Ani|Tra|Tou|BeforeInp|Compo)/,ft=/[A-Z0-9]/g,pt=typeof document<`u`,mt=function(e){return(typeof Symbol<`u`&&typeof Symbol()==`symbol`?/fil|che|rad/:/fil|che|ra/).test(e)};function ht(e,t,n){return t.__k??(t.textContent=``),F(e,t),typeof n==`function`&&n(),e?e.__c:null}function gt(e,t,n){return fe(e,t),typeof n==`function`&&n(),e?e.__c:null}T.prototype.isReactComponent=!0,[`componentWillMount`,`componentWillReceiveProps`,`componentWillUpdate`].forEach(function(e){Object.defineProperty(T.prototype,e,{configurable:!0,get:function(){return this[`UNSAFE_`+e]},set:function(t){Object.defineProperty(this,e,{configurable:!0,writable:!0,value:t})}})});var _t=t.event;t.event=function(e){return _t&&(e=_t(e)),e.persist=function(){},e.isPropagationStopped=function(){return this.cancelBubble},e.isDefaultPrevented=function(){return this.defaultPrevented},e.nativeEvent=e};var Y,vt={configurable:!0,get:function(){return this.class}},yt=t.vnode;t.vnode=function(e){typeof e.type==`string`&&function(e){var t=e.props,n=e.type,r={},i=n.indexOf(`-`)==-1;for(var a in t){var o=t[a];if(!(a===`value`&&`defaultValue`in t&&o==null||pt&&a===`children`&&n===`noscript`||a===`class`||a===`className`)){var s=a.toLowerCase();a===`defaultValue`&&`value`in t&&t.value==null?a=`value`:a===`download`&&!0===o?o=``:s===`translate`&&o===`no`?o=!1:s[0]===`o`&&s[1]===`n`?s===`ondoubleclick`?a=`ondblclick`:s!==`onchange`||n!==`input`&&n!==`textarea`||mt(t.type)?s===`onfocus`?a=`onfocusin`:s===`onblur`?a=`onfocusout`:dt.test(a)&&(a=s):s=a=`oninput`:i&&ut.test(a)?a=a.replace(ft,`-$&`).toLowerCase():o===null&&(o=void 0),s===`oninput`&&r[a=s]&&(a=`oninputCapture`),r[a]=o}}n==`select`&&(r.multiple&&Array.isArray(r.value)&&(r.value=N(t.children).forEach(function(e){e.props.selected=r.value.indexOf(e.props.value)!=-1})),r.defaultValue!=null&&(r.value=N(t.children).forEach(function(e){e.props.selected=r.multiple?r.defaultValue.indexOf(e.props.value)!=-1:r.defaultValue==e.props.value}))),t.class&&!t.className?(r.class=t.class,Object.defineProperty(r,`className`,vt)):t.className&&(r.class=r.className=t.className),e.props=r}(e),e.$$typeof=lt,yt&&yt(e)};var bt=t.__r;t.__r=function(e){bt&&bt(e),Y=e.__c};var xt=t.diffed;t.diffed=function(e){xt&&xt(e);var t=e.props,n=e.__e;n!=null&&e.type===`textarea`&&`value`in t&&t.value!==n.value&&(n.value=t.value==null?``:t.value),Y=null};var St={ReactCurrentDispatcher:{current:{readContext:function(e){return Y.__n[e.__c].props.value},useCallback:De,useContext:Oe,useDebugValue:ke,useDeferredValue:Ue,useEffect:H,useId:Ae,useImperativeHandle:Ee,useInsertionEffect:Ge,useLayoutEffect:U,useMemo:W,useReducer:we,useRef:Te,useState:V,useSyncExternalStore:Be,useTransition:We}}};function Ct(e){return x.bind(null,e)}function X(e){return!!e&&e.$$typeof===lt}function wt(e){return X(e)&&e.type===w}function Tt(e){return!!e&&typeof e.displayName==`string`&&e.displayName.indexOf(`Memo(`)==0}function Et(e){return X(e)?pe.apply(null,arguments):e}function Dt(e){return!!e.__k&&(F(null,e),!0)}function Ot(e){return e&&(e.base||e.nodeType===1&&e)||null}var Z={useState:V,useId:Ae,useReducer:we,useEffect:H,useLayoutEffect:U,useInsertionEffect:Ge,useTransition:We,useDeferredValue:Ue,useSyncExternalStore:Be,startTransition:He,useRef:Te,useImperativeHandle:Ee,useMemo:W,useCallback:De,useContext:Oe,useDebugValue:ke,version:`18.3.1`,Children:Qe,render:ht,hydrate:gt,unmountComponentAtNode:Dt,createPortal:ct,createElement:x,createContext:me,createFactory:Ct,cloneElement:Et,createRef:C,Fragment:w,isValidElement:X,isElement:X,isFragment:wt,isMemo:Tt,findDOMNode:Ot,Component:T,PureComponent:Ke,memo:qe,forwardRef:Xe,flushSync:function(e,n){var r=t.debounceRendering;t.debounceRendering=function(e){return e()};var i=e(n);return t.debounceRendering=r,i},unstable_batchedUpdates:function(e,t){return e(t)},StrictMode:w,Suspense:q,SuspenseList:J,lazy:it,__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:St},kt=e=>e;function At(e,t=kt){let n=Z.useSyncExternalStore(e.subscribe,Z.useCallback(()=>t(e.getState()),[e,t]),Z.useCallback(()=>t(e.getInitialState()),[e,t]));return Z.useDebugValue(n),n}var jt=e=>{let t=Le(e),n=e=>At(t,e);return Object.assign(n,t),n},Mt=(e=>e?jt(e):jt),Nt=`<tr> <td colspan="2" class="diff-lineno">Line 10:</td> <td colspan="2" class="diff-lineno">Line 10:</td> </tr> <tr> <td class="diff-marker"></td> <td class="diff-context diff-side-deleted"><div>| allegiance = [[Iran]]</div></td> <td class="diff-marker"></td> <td class="diff-context diff-side-added"><div>| allegiance = [[Iran]]</div></td> </tr> <tr> <td class="diff-marker"></td> <td class="diff-context diff-side-deleted"><div>| branch = [[Islamic Revolutionary Guard Corps|Revolutionary Guards]]</div></td> <td class="diff-marker"></td> <td class="diff-context diff-side-added"><div>| branch = [[Islamic Revolutionary Guard Corps|Revolutionary Guards]]</div></td> </tr> <tr> <td class="diff-marker" data-marker="−"></td> <td class="diff-deletedline diff-side-deleted"><div>| <del class="diffchange diffchange-inline">serviceyears</del> = </div></td> <td class="diff-marker" data-marker="+"></td> <td class="diff-addedline diff-side-added"><div>| <ins class="diffchange diffchange-inline">service_years</ins> = </div></td> </tr> <tr> <td class="diff-marker"></td> <td class="diff-context diff-side-deleted"><div>| rank = </div></td> <td class="diff-marker"></td> <td class="diff-context diff-side-added"><div>| rank = </div></td> </tr> <tr> <td class="diff-marker"></td> <td class="diff-context diff-side-deleted"><div>| unit = </div></td> <td class="diff-marker"></td> <td class="diff-context diff-side-added"><div>| unit = </div></td> </tr> <tr> <td colspan="2" class="diff-lineno">Line 46:</td> <td colspan="2" class="diff-lineno">Line 46:</td> </tr> <tr> <td class="diff-marker"></td> <td class="diff-context diff-side-deleted"><div>He has a background as the president of [[Malek-Ashtar University of Technology]] and was the CEO of [[MAPNA Group]] from December 2008 to July 2023.&lt;ref&gt;{{cite web|url=https://donya-e-eqtesad.com/%D8%A8%D8%AE%D8%B4-%D8%A8%D9%88%D8%B1%D8%B3-6/589662-%D8%B9%D8%A8%D8%A7%D8%B3-%D8%B9%D9%84%DB%8C-%D8%A2%D8%A8%D8%A7%D8%AF%DB%8C-%D9%85%D8%AF%DB%8C%D8%B1%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D9%BE%D9%86%D8%A7-%D8%B4%D8%AF |title=عباس علی‌آبادی مدیرعامل مپنا شد |trans-title=Abbas Aliabadi became the CEO of Mapna |language=fa |date=2010-01-03 |access-date=2024-09-10 |publisher=Donya-e-eqtesad}}&lt;/ref&gt; Aliabadi's most important action in Mapna was trying to develop this company from power plant projects to other projects. During his time, contracts were signed in the field of oil and gas and the country's railway industries, and he put the entry into the manufacturing of medical devices for health and electric cars on the agenda.&lt;ref&gt;{{cite web|url=https://www.asriran.com/fa/news/893849/عباس-علی-آبادی-وزیر-جدید-صمت-کیست|title=عباس علی‌آبادی، وزیر جدید صمت کیست؟|publisher=asiran.com|language=fa}}&lt;/ref&gt;</div></td> <td class="diff-marker"></td> <td class="diff-context diff-side-added"><div>He has a background as the president of [[Malek-Ashtar University of Technology]] and was the CEO of [[MAPNA Group]] from December 2008 to July 2023.&lt;ref&gt;{{cite web|url=https://donya-e-eqtesad.com/%D8%A8%D8%AE%D8%B4-%D8%A8%D9%88%D8%B1%D8%B3-6/589662-%D8%B9%D8%A8%D8%A7%D8%B3-%D8%B9%D9%84%DB%8C-%D8%A2%D8%A8%D8%A7%D8%AF%DB%8C-%D9%85%D8%AF%DB%8C%D8%B1%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D9%BE%D9%86%D8%A7-%D8%B4%D8%AF |title=عباس علی‌آبادی مدیرعامل مپنا شد |trans-title=Abbas Aliabadi became the CEO of Mapna |language=fa |date=2010-01-03 |access-date=2024-09-10 |publisher=Donya-e-eqtesad}}&lt;/ref&gt; Aliabadi's most important action in Mapna was trying to develop this company from power plant projects to other projects. During his time, contracts were signed in the field of oil and gas and the country's railway industries, and he put the entry into the manufacturing of medical devices for health and electric cars on the agenda.&lt;ref&gt;{{cite web|url=https://www.asriran.com/fa/news/893849/عباس-علی-آبادی-وزیر-جدید-صمت-کیست|title=عباس علی‌آبادی، وزیر جدید صمت کیست؟|publisher=asiran.com|language=fa}}&lt;/ref&gt;</div></td> </tr> <tr> <td class="diff-marker"></td> <td class="diff-context diff-side-deleted"><br /></td> <td class="diff-marker"></td> <td class="diff-context diff-side-added"><br /></td> </tr> <tr> <td class="diff-marker" data-marker="−"></td> <td class="diff-deletedline diff-side-deleted"><div>Aliabadi was the nominated as [[Ministry of Industry, Mine and Trade|Minister of Industry, Mine and Trade]] in the [[Government of Ebrahim Raisi]]. He received a vote of confidence from the [[List of Iran's parliament representatives (11th term)|11th convocation]] of the [[Islamic Consultative Assembly]] (Iranian [[parliament]]) on June 23, 2021, with 187 votes in favor, 58 votes against, 8 abstentions and 2 invalid votes.&lt;ref name="21-08-25"&gt;{{Cite web|date=2021-08-25|title=Majlis votes for 18 proposed ministers, rejects education minister nominee|url=https://www.tehrantimes.com/news/464333/Majlis-votes-for-18-proposed-ministers-rejects-education-minister|access-date=2021-08-26|website=Tehran Times|language=en}}&lt;/ref&gt;&lt;ref&gt;{{cite web|url=https://www.radiofarda.com/a/32457000.html|title="مجلس به عباس علی‌آبادی به عنوان وزیر صنعت، معدن و تجارت رای اعتماد داد"|publisher=Radio Farda|language=fa}}&lt;/ref&gt; In August 2024 he was appointed as [[Ministry of Energy (Iran)|Minister of Energy]] in the [[Government of Masoud Pezeshkian]].&lt;ref&gt;{{cite web|url=https://www.iranintl.com/en/202408131446|title=Who's who in Pezeshkian's cabinet?|last1=Sinaiee|first1=Maryam|publisher=Iran International|date=2024-08-21|accessdate=2024-09-10}}&lt;/ref&gt;&lt;ref&gt;{{cite web|url=https://rasanah-iiis.org/english/monitoring-and-translation/reports/inside-irans-new-cabinet-dynamics-directions-and-continuities/|title=Inside <del class="diffchange diffchange-inline">Iran’s</del> New Cabinet: Dynamics, Directions, and Continuities|publisher=International Institute for Iranian Studies|date=2024-09-04|accessdate=2024-09-10}}&lt;/ref&gt;</div></td> <td class="diff-marker" data-marker="+"></td> <td class="diff-addedline diff-side-added"><div>Aliabadi was the nominated as [[Ministry of Industry, Mine and Trade|Minister of Industry, Mine and Trade]] in the [[Government of Ebrahim Raisi]]. He received a vote of confidence from the [[List of Iran's parliament representatives (11th term)|11th convocation]] of the [[Islamic Consultative Assembly]] (Iranian [[parliament]]) on June 23, 2021, with 187 votes in favor, 58 votes against, 8 abstentions and 2 invalid votes.&lt;ref name="21-08-25"&gt;{{Cite web|date=2021-08-25|title=Majlis votes for 18 proposed ministers, rejects education minister nominee|url=https://www.tehrantimes.com/news/464333/Majlis-votes-for-18-proposed-ministers-rejects-education-minister|access-date=2021-08-26|website=Tehran Times|language=en}}&lt;/ref&gt;&lt;ref&gt;{{cite web|url=https://www.radiofarda.com/a/32457000.html|title="مجلس به عباس علی‌آبادی به عنوان وزیر صنعت، معدن و تجارت رای اعتماد داد"|publisher=Radio Farda|language=fa}}&lt;/ref&gt; In August 2024 he was appointed as [[Ministry of Energy (Iran)|Minister of Energy]] in the [[Government of Masoud Pezeshkian]].&lt;ref&gt;{{cite web|url=https://www.iranintl.com/en/202408131446|title=Who's who in Pezeshkian's cabinet?|last1=Sinaiee|first1=Maryam|publisher=Iran International|date=2024-08-21|accessdate=2024-09-10}}&lt;/ref&gt;&lt;ref&gt;{{cite web|url=https://rasanah-iiis.org/english/monitoring-and-translation/reports/inside-irans-new-cabinet-dynamics-directions-and-continuities/|title=Inside <ins class="diffchange diffchange-inline">Iran's</ins> New Cabinet: Dynamics, Directions, and Continuities|publisher=International Institute for Iranian Studies|date=2024-09-04|accessdate=2024-09-10}}&lt;/ref&gt;</div></td> </tr> <tr> <td class="diff-marker"></td> <td class="diff-context diff-side-deleted"><br /></td> <td class="diff-marker"></td> <td class="diff-context diff-side-added"><br /></td> </tr> <tr> <td class="diff-marker"></td> <td class="diff-context diff-side-deleted"><div>==References==</div></td> <td class="diff-marker"></td> <td class="diff-context diff-side-added"><div>==References==</div></td> </tr> `,Q=Mt(e=>({past:[],highlighted:new Set([`ClueBot NG`,`SineBot`]),future:[{user:`enb`,title:`User:enbi`,diffHtml:Nt,revid:1769,history:`error`,parsedcomment:`hai`,timestamp:1111111111,current:!0}],current:`buffer`,add:t=>{e(e=>e.current===`buffer`?{current:t}:{future:[...e.future,t]})},setCurrent:()=>{},increment:()=>{e(e=>{if(e.future.length===0)return e.current===`buffer`?{}:{current:`buffer`,past:[...e.past,e.current]};let t=e.future[0];return{past:[...e.past,e.current],future:e.future.slice(1),current:t}})},decrement:()=>{e(e=>{if(e.past.length===0)return{};if(e.current===`buffer`)return{current:e.past[e.past.length-1],past:e.past.slice(0,-1)};let t=e.past?.[e.past.length-1];return{past:e.past.slice(0,-1),future:[e.current,...e.future],current:t}})},connected:!1,setConnected:()=>{e(()=>({connected:!0}))},setDisconnected:()=>{e(()=>({connected:!1}))}})),Pt=class{api;constructor(){this.api=new mw.Api}async getDiff(e,t){let n={action:`compare`,fromrev:t,torev:e,props:`diff|ids|title`},r=await this.get(n);return r.compare?.body||r.compare[`*`]}async getPageContent(e){let t={action:`query`,prop:`revisions`,titles:e,rvprop:`content`,format:`json`,formatversion:2},n=await this.get(t);return console.log(n.query.pages?.[0]?.revisions?.[0]?.content),n.query.pages?.[0]?.revisions?.[0]?.content}async get(e){try{return await this.api.get(e)}catch(e){console.log(`ApiError: `,{cause:e})}}async getAivUsers(e=`Wikipedia:Administrator intervention against vandalism`){let t=[...(await this.getPageContent(e)).matchAll(/\*\s*\{\{(?:[Ii][Pp])?[Vv]andal\|([^|}]*?)\}\}/g)];console.log(t);let n=t.map(e=>e[1]),r=new Set(n);return r.delete(`Username or Temporary account name`),console.log(r),r}async rollback(e,t,n){try{return await this.api.rollback(t,e,{summary:n}),!0}catch(e){if(e==`alreadyrolled`)return`Already rolled.`}}};function Ft(){async function e(e){let n={user:e.user,title:e.title,diffHtml:`Could not fetch diff.`,history:`error`,current:!0,parsedcomment:e?.parsedcomment,revid:e.revision.new,timestamp:e.timestamp};try{n.diffHtml=await t.getDiff(e.revision.new,e.revision.old)}catch(e){throw Error(`No diff: `,{cause:e})}finally{r(n)}}let t=new Pt,n=new EventSource(`https://stream.wikimedia.org/v2/stream/recentchange`),r=Q.getState().add,i=Q.getState().setDisconnected,a=Q.getState().setConnected,o=Q.getState().highlighted;n.onopen=async()=>{console.log(`ES open`),a(),await t.getAivUsers()},n.onerror=e=>{console.error(`es error:`,e),i()},n.onmessage=async t=>{let n=JSON.parse(t.data);n.meta.domain!==`canary`&&(n.wiki!==`enwiki`||n.type!==`edit`||(/^~2026/.test(n.user)||o.has(n.user))&&e(n))}}var It=0;Array.isArray;function $(e,n,r,i,a,o){n||={};var s,c,l=n;if(`ref`in l)for(c in l={},n)c==`ref`?s=n[c]:l[c]=n[c];var u={type:e,props:l,key:r,ref:s,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--It,__i:-1,__u:0,__source:a,__self:o};if(typeof e==`function`&&(s=e.defaultProps))for(c in s)l[c]===void 0&&(l[c]=s[c]);return t.vnode&&t.vnode(u),u}function Lt(){return $(`div`,{className:`bottom-section`,children:[$(`div`,{className:`es-status`,children:Q(e=>e.connected)?$(`span`,{className:`es-connected text-green-600`,children:`Connected`}):$(`span`,{className:`es-disconnected text-red-400`,children:`Not connected`})}),$(`div`,{className:`es-wiki`,children:`enwiki`}),$(`div`,{children:`Recent Changes`})]})}function Rt({style:e}){return $(`div`,{className:`dashboard-holder`,style:e,children:{lta:!0,rvoptions:[{name:`Vandalism`,warning:`uw-vandalism`,level4:!0},{name:`Test edits`,warning:`uw-test`,level4:!0},{name:`Disruptive editing`,warning:`uw-disruptive`,level4:!1},{name:`Incorrect pronouns`,warning:`uw-pronouns`,level4:!1},{name:`Commentary`,warning:`uw-commentary`,level4:!1},{name:`Warning`,warning:`uw-warning`,level4:!0}]}.rvoptions.map(e=>$(`div`,{className:`*:p-2 rounded-lg font-bold db-option-holder db-option-holder-${e.warning}`,children:[$(`div`,{className:`rounded-lg flex justify-center align-center db-auto`,children:e.name}),$(`div`,{className:`rounded-lg flex justify-center align-center db-number db-1`,children:`1`}),$(`div`,{className:`rounded-lg flex justify-center align-center db-number db-2`,children:`2`}),$(`div`,{className:`rounded-lg flex justify-center align-center db-number db-3`,children:`3`}),$(`div`,{className:`rounded-lg flex justify-center align-center pl-2 pr-2 db-number db-4 db-${e.level4?`specific`:`generic`}`,children:[`4`,!e.level4&&` (g.)`]})]},e.warning))})}var zt=e=>$(`svg`,{width:`800px`,height:`800px`,viewBox:`0 0 16 16`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,...e,children:[$(`path`,{d:`M8 7C9.65685 7 11 5.65685 11 4C11 2.34315 9.65685 1 8 1C6.34315 1 5 2.34315 5 4C5 5.65685 6.34315 7 8 7Z`,fill:`#000000`}),$(`path`,{d:`M14 12C14 10.3431 12.6569 9 11 9H5C3.34315 9 2 10.3431 2 12V15H14V12Z`,fill:`#000000`})]});function Bt({time:e}){function t(e){if(typeof e==`string`)return Math.floor((Date.now()-new Date(e).getTime())/1e3);if(typeof e==`number`)return Math.floor((Date.now()-e*1e3)/1e3);throw Error(`Invalid date passed to Timestamp component`)}let[n,r]=V(t(e));return H(()=>{function e(){r(e=>e+1)}let t=setInterval(e,1e3);return()=>clearInterval(t)}),$(`span`,{children:[n,` seconds ago`]})}var Vt=e=>$(`svg`,{width:`800px`,height:`800px`,viewBox:`0 0 32 32`,xmlns:`http://www.w3.org/2000/svg`,xmlnsXlink:`http://www.w3.org/1999/xlink`,"xmlns:sketch":`http://www.bohemiancoding.com/sketch/ns`,...e,children:[$(`title`,{children:`comment 2`}),$(`desc`,{children:`Created with Sketch Beta.`}),$(`defs`,{}),$(`g`,{id:`Page-1`,stroke:`none`,strokeWidth:1,fill:`none`,fillRule:`evenodd`,"sketch:type":`MSPage`,children:$(`g`,{id:`Icon-Set-Filled`,"sketch:type":`MSLayerGroup`,transform:`translate(-154.000000, -257.000000)`,fill:`#000000`,children:$(`path`,{d:`M177,270 L163,270 C162.448,270 162,269.553 162,269 C162,268.448 162.448,268 163,268 L177,268 C177.552,268 178,268.448 178,269 C178,269.553 177.552,270 177,270 L177,270 Z M175,276 L165,276 C164.448,276 164,275.553 164,275 C164,274.447 164.448,274 165,274 L175,274 C175.552,274 176,274.447 176,275 C176,275.553 175.552,276 175,276 L175,276 Z M170,257 C161.164,257 154,263.269 154,271 C154,275.419 156.345,279.354 160,281.919 L160,289 L167.009,284.747 C167.979,284.907 168.977,285 170,285 C178.836,285 186,278.732 186,271 C186,263.269 178.836,257 170,257 L170,257 Z`,id:`comment-2`,"sketch:type":`MSShapeGroup`})})})]});function Ht({style:e}){let t=Q(e=>e.future),n=Q(e=>e.current),r=Q(e=>e.decrement),i=Q(e=>e.increment),a=[n,...t];return H(()=>{let e=e=>{e.key===`[`?(e.preventDefault(),console.log(`[`),r()):e.code===`Space`&&(e.preventDefault(),i())};return document.addEventListener(`keydown`,e),()=>document.removeEventListener(`keydown`,e)},[]),$(`div`,{style:e,className:`queue-holder`,children:a.map(e=>!e||e===`buffer`?null:$(`div`,{className:`queue-el *:px-1 *:py-px${e===n?` queue-selected`:``}`,children:[$(`div`,{className:`queue-title text-lg`,children:$(`a`,{href:`/wiki/${e.title}`,target:`_blank`,rel:`noopener noreferrer`,children:e.title})}),$(`div`,{className:`flex items-center queue-summary text-gray-400`,children:[$(Vt,{className:`svg-queue`}),$(`span`,{className:`truncate`,dangerouslySetInnerHTML:{__html:e.parsedcomment?e.parsedcomment:`No summary provided`}})]}),$(`div`,{className:`queue-user flex items-center justify-start`,children:[$(zt,{className:`svg-queue svg-user`}),$(`a`,{className:`truncate`,href:`/wiki/Special:Contributions/${e.user}`,target:`_blank`,rel:`noopener noreferrer`,children:e.user})]}),$(Bt,{time:e.timestamp})]},e.revid))})}function Ut({menu:e}){return $(`div`,{className:`left-tab bg222`,children:[$(Rt,{style:e===`revert`?void 0:{display:`none`}}),$(Ht,{style:e===`queue`?void 0:{display:`none`}})]})}function Wt(){let e=Q(e=>e.current);return e?e===`buffer`?$(`div`,{children:`No diff in queue.`}):$(`div`,{className:`diff-holder w-full h-full overflow-y-auto${e.current?``:` diff-rolled`}`,children:$(`div`,{className:`diff-radius-container`,children:$(`table`,{className:`diff`,children:[$(`colgroup`,{children:[$(`col`,{className:`diff-marker`}),$(`col`,{className:`diff-content`}),$(`col`,{className:`diff-marker`}),$(`col`,{className:`diff-content`})]}),$(`tbody`,{dangerouslySetInnerHTML:{__html:e.diffHtml}})]})})}):$(`div`,{className:`flex justify-center items-center h-full w-full text-center`,children:$(`div`,{className:`diff-err-holder`,children:[$(`div`,{className:`text-9xl sad-face font-light`,children:[`:`,`(`]}),$(`p`,{className:`error-text m-3`,children:[`FN One couldn`,`'`,`t fetch the diff for this edit.`]})]})})}function Gt(){return $(Wt,{})}var Kt=e=>$(`svg`,{width:`64px`,height:`64px`,viewBox:`0 0 16 16`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,stroke:`#000000`,strokeWidth:16e-5,...e,children:[$(`g`,{id:`SVGRepo_bgCarrier`,strokeWidth:0}),$(`g`,{id:`SVGRepo_tracerCarrier`,strokeLinecap:`round`,strokeLinejoin:`round`}),$(`g`,{id:`SVGRepo_iconCarrier`,children:$(`path`,{d:`M6 14H8L8 9L13 14H15L15 2H13L8 7L8 2H6L0 8L6 14Z`,fill:`#000000`})})]}),qt=e=>$(`svg`,{width:`800px`,height:`800px`,viewBox:`0 0 16 16`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,...e,children:$(`path`,{fillRule:`evenodd`,clipRule:`evenodd`,d:`M5 2H7V3.07645C3.88491 3.55745 1.5 6.25021 1.5 9.5C1.5 13.0899 4.41015 16 8 16C11.5899 16 14.5 13.0899 14.5 9.5C14.5 8.0659 14.0356 6.74027 13.2489 5.66531L14.7071 4.20711L13.2929 2.79289L11.8347 4.2511C11.0146 3.65097 10.0487 3.23838 9 3.07645V2H11V0H5V2ZM7 6V10H9V6H7Z`,fill:`#000000`})});function Jt({menu:e,setMenu:t}){return $(`div`,{className:`sidebar bg222 flex flex-col justify-start items-center`,children:[$(`button`,{className:`w-full ${e===`revert`?`svg-selected`:`svg-button`}`,onClick:()=>t(`revert`),children:$(Kt,{className:`svg-sidebar w-full`})}),$(`button`,{className:`w-full ${e===`queue`?`svg-selected`:`svg-button`}`,onClick:()=>t(`queue`),children:$(qt,{className:`svg-sidebar w-full`})})]})}function Yt(){return $(`div`,{className:`hist-holder`})}function Xt(){let[e,t]=V(`queue`);return H(()=>{let e=e=>{e.key===`r`&&(console.log(`r`),t(`revert`)),e.key===`a`&&t(`queue`)};return console.log(`hi`),document.addEventListener(`keydown`,e),Ft(),()=>document.removeEventListener(`keydown`,e)},[]),$(w,{children:[$(Ut,{menu:e}),$(`div`,{className:`diff-view bg222`,children:$(Gt,{})}),$(Jt,{menu:e,setMenu:t}),$(Lt,{}),$(`div`,{className:`right-tab`,children:$(Yt,{})})]})}function Zt(){return console.log(`the APP has LOADED`),$(Xt,{})}document.body.innerHTML=`<div id="app"><div>`,F($(Zt,{}),document.getElementById(`app`))})(); 92756f01qenwoeb0o1ktvvtuzjudt3q User:Enbi/Gateway/run 2 175302 741030 2026-05-08T16:44:36Z Enbi 72574 Created page with "{{lowercase title}}" 741030 wikitext text/x-wiki {{lowercase title}} b2efuhp1s5rgqdtchs86qj0b9br9siu File:Layered tiff test.tiff 6 175303 741073 2026-05-08T22:45:53Z Alexis Jazz 40203 TIFF file with layers and LZW compression. Test to see how MediaWiki renders its thumbnail 741073 wikitext text/x-wiki == Summary == TIFF file with layers and LZW compression. Test to see how MediaWiki renders its thumbnail == Licensing == {{FAL}} s9ncsel75kltcseza80pdntwuz1uwlm Italy 0 175304 741090 2026-05-09T03:57:33Z Versions111 73010 Created page with "[[File:Flag of Italy.svg|thumb|Flag of Italy]] '''Italy''' is a country on southern Europe. Its capital is Rome. The country borders France, Switzerland, Austria, and Slovenia. It is shaped like a boot. It is a member of NATO and EU." 741090 wikitext text/x-wiki [[File:Flag of Italy.svg|thumb|Flag of Italy]] '''Italy''' is a country on southern Europe. Its capital is Rome. The country borders France, Switzerland, Austria, and Slovenia. It is shaped like a boot. It is a member of NATO and EU. na9t37tryofandl400baazl2erqsp26 Wikipedia:Lexis/Lexis.Dict.Public.7LU9K-VJ79O.ldf 4 175305 741091 2026-05-09T04:31:28Z Plantaest 37055 Tạo từ điển Lexis.Dict.Public.7LU9K-VJ79O [#Lexis] 741091 text text/plain @id Lexis.Dict.Public.7LU9K-VJ79O #refs #terms eyxcjdq05o0ra303gpczvfpvp88cxxl 741093 741091 2026-05-09T04:32:32Z Plantaest 37055 Thêm tham khảo 'BIO' cho từ điển Lexis.Dict.Public.7LU9K-VJ79O [#Lexis] 741093 text text/plain @id Lexis.Dict.Public.7LU9K-VJ79O #refs <BIO>:<Từ điển Sinh học>:<> #terms jkpcwm5zuskxdbr7wq9csz47se4dfw0 741095 741093 2026-05-09T04:33:11Z Plantaest 37055 Thêm tham khảo 'CHEM' cho từ điển Lexis.Dict.Public.7LU9K-VJ79O [#Lexis] 741095 text text/plain @id Lexis.Dict.Public.7LU9K-VJ79O #refs <BIO>:<Từ điển Sinh học>:<> <CHEM>:<Từ điển Hóa học>:<https://chem.org> #terms czlpqdnwkvyyq95b93glu009xzu2ksw 741097 741095 2026-05-09T04:33:59Z Plantaest 37055 Sửa tham khảo 'CHEM' cho từ điển Lexis.Dict.Public.7LU9K-VJ79O [#Lexis] 741097 text text/plain @id Lexis.Dict.Public.7LU9K-VJ79O #refs <BIO>:<Từ điển Sinh học>:<> <CHEM>:<Từ điển Hóa học>:<https://chemistry.org> #terms i6z08vnispti8jb1efh4smx9lgru7ih 741099 741097 2026-05-09T04:38:44Z Plantaest 37055 Sửa tham khảo 'CHEM' cho từ điển Lexis.Dict.Public.7LU9K-VJ79O [#Lexis] 741099 text text/plain @id Lexis.Dict.Public.7LU9K-VJ79O #refs <BIO>:<Từ điển Sinh học>:<> <CHEM>:<Từ điển Hóa học – Tập 1>:<https://chemistry.org> #terms mu9sxlsd55dabnc5sxs9ya3n0po5dop Wikipedia:Lexis/Lexis.Dict.Public.Index.json 4 175306 741092 2026-05-09T04:31:29Z Plantaest 37055 Thêm từ điển Lexis.Dict.Public.7LU9K-VJ79O [#Lexis] 741092 json application/json { "7LU9K-VJ79O": { "id": "Lexis.Dict.Public.7LU9K-VJ79O", "creator": { "id": 37055, "name": "Plantaest" }, "contributors": [ { "id": 37055, "name": "Plantaest" } ], "createdAt": "2026-05-09T04:31:27Z", "updatedAt": "2026-05-09T04:31:27Z", "type": "public", "name": "Từ điển Sinh học Anh Việt", "englishName": "English-Vietnamese Biology Dictionary", "sourceLanguage": "en", "targetLanguage": "vi" } } 4czh062inxskbm88n3w5ndv6q6hb7lk 741094 741092 2026-05-09T04:32:33Z Plantaest 37055 Thêm tham khảo 'BIO' cho từ điển Lexis.Dict.Public.7LU9K-VJ79O [#Lexis] 741094 json application/json { "7LU9K-VJ79O": { "id": "Lexis.Dict.Public.7LU9K-VJ79O", "creator": { "id": 37055, "name": "Plantaest" }, "contributors": [ { "id": 37055, "name": "Plantaest" } ], "createdAt": "2026-05-09T04:31:27Z", "updatedAt": "2026-05-09T04:32:33Z", "type": "public", "name": "Từ điển Sinh học Anh Việt", "englishName": "English-Vietnamese Biology Dictionary", "sourceLanguage": "en", "targetLanguage": "vi" } } n8fwaqhl1c62qmaippz5yoty2qf8w6h 741096 741094 2026-05-09T04:33:12Z Plantaest 37055 Thêm tham khảo 'CHEM' cho từ điển Lexis.Dict.Public.7LU9K-VJ79O [#Lexis] 741096 json application/json { "7LU9K-VJ79O": { "id": "Lexis.Dict.Public.7LU9K-VJ79O", "creator": { "id": 37055, "name": "Plantaest" }, "contributors": [ { "id": 37055, "name": "Plantaest" } ], "createdAt": "2026-05-09T04:31:27Z", "updatedAt": "2026-05-09T04:33:12Z", "type": "public", "name": "Từ điển Sinh học Anh Việt", "englishName": "English-Vietnamese Biology Dictionary", "sourceLanguage": "en", "targetLanguage": "vi" } } o9bfarkmqw17v5tjhpenlphuzsvic06 741098 741096 2026-05-09T04:34:00Z Plantaest 37055 Sửa tham khảo 'CHEM' cho từ điển Lexis.Dict.Public.7LU9K-VJ79O [#Lexis] 741098 json application/json { "7LU9K-VJ79O": { "id": "Lexis.Dict.Public.7LU9K-VJ79O", "creator": { "id": 37055, "name": "Plantaest" }, "contributors": [ { "id": 37055, "name": "Plantaest" } ], "createdAt": "2026-05-09T04:31:27Z", "updatedAt": "2026-05-09T04:34:00Z", "type": "public", "name": "Từ điển Sinh học Anh Việt", "englishName": "English-Vietnamese Biology Dictionary", "sourceLanguage": "en", "targetLanguage": "vi" } } qejquzu6a6s0yr77av4g5uj38tqhaca 741100 741098 2026-05-09T04:38:45Z Plantaest 37055 Sửa tham khảo 'CHEM' cho từ điển Lexis.Dict.Public.7LU9K-VJ79O [#Lexis] 741100 json application/json { "7LU9K-VJ79O": { "id": "Lexis.Dict.Public.7LU9K-VJ79O", "creator": { "id": 37055, "name": "Plantaest" }, "contributors": [ { "id": 37055, "name": "Plantaest" } ], "createdAt": "2026-05-09T04:31:27Z", "updatedAt": "2026-05-09T04:38:45Z", "type": "public", "name": "Từ điển Sinh học Anh Việt", "englishName": "English-Vietnamese Biology Dictionary", "sourceLanguage": "en", "targetLanguage": "vi" } } rv3mfqlrjlczt6nhlyjh0d7l2rt3jjf File:Antilight2025.png 6 175307 741103 2026-05-09T11:39:34Z Cryptocurrency777 73698 From a post made in 2025 741103 wikitext text/x-wiki == Summary == From a post made in 2025 == Licensing == {{cc-by-3.0}} lntq4ea09slivod91iu2cwey6x31pjr