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,"&").replace(/</g,"<").replace(/>/g,">")}function js(i){return Ge(i).replace(/"/g,""")}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> টি বিভাগ' +
' | ' +
'<strong style="color: #14866d">' + toBengaliNum(withText) + '</strong> টি পাঠ্য সহ' +
' | ' +
'<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('←');
const redoBtn = $('<button>').addClass('sbs-icon-btn').attr('title', 'পুনরায় করুন').html('→');
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> টি বিভাগ' +
' | ' +
'<strong style="color: #14866d">' + toBengaliNum(withText) + '</strong> টি পাঠ্য সহ' +
' | ' +
'<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('←');
const redoBtn = $('<button>').addClass('sbs-icon-btn').attr('title', 'পুনরায় করুন').html('→');
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> টি বিভাগ' +
' | ' +
'<strong style="color: #14866d">' + toBengaliNum(withText) + '</strong> টি পাঠ্য সহ' +
' | ' +
'<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('←');
const redoBtn = $('<button>').addClass('sbs-icon-btn').attr('title', 'পুনরায় করুন').html('→');
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> টি বিভাগ' +
' | ' +
'<strong style="color: #14866d">' + toBengaliNum(withText) + '</strong> টি পাঠ্য সহ' +
' | ' +
'<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('←');
const redoBtn = $('<button>').addClass('sbs-icon-btn').attr('title', 'পুনরায় করুন').html('→');
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 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, '&' )
.replace( /</g, '<' )
.replace( />/g, '>' )
.replace( /"/g, '"' )
.replace( /'/g, ''' );
}
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.<ref>{{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}}</ref> 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.<ref>{{cite web|url=https://www.asriran.com/fa/news/893849/عباس-علی-آبادی-وزیر-جدید-صمت-کیست|title=عباس علیآبادی، وزیر جدید صمت کیست؟|publisher=asiran.com|language=fa}}</ref></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.<ref>{{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}}</ref> 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.<ref>{{cite web|url=https://www.asriran.com/fa/news/893849/عباس-علی-آبادی-وزیر-جدید-صمت-کیست|title=عباس علیآبادی، وزیر جدید صمت کیست؟|publisher=asiran.com|language=fa}}</ref></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.<ref name="21-08-25">{{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}}</ref><ref>{{cite web|url=https://www.radiofarda.com/a/32457000.html|title="مجلس به عباس علیآبادی به عنوان وزیر صنعت، معدن و تجارت رای اعتماد داد"|publisher=Radio Farda|language=fa}}</ref> In August 2024 he was appointed as [[Ministry of Energy (Iran)|Minister of Energy]] in the [[Government of Masoud Pezeshkian]].<ref>{{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}}</ref><ref>{{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}}</ref></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.<ref name="21-08-25">{{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}}</ref><ref>{{cite web|url=https://www.radiofarda.com/a/32457000.html|title="مجلس به عباس علیآبادی به عنوان وزیر صنعت، معدن و تجارت رای اعتماد داد"|publisher=Radio Farda|language=fa}}</ref> In August 2024 he was appointed as [[Ministry of Energy (Iran)|Minister of Energy]] in the [[Government of Masoud Pezeshkian]].<ref>{{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}}</ref><ref>{{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}}</ref></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