├── package.json ├── tweaks ├── General │ ├── BypassTrash │ │ ├── BypassTrash.css │ │ ├── BypassTrash.js │ │ └── BypassTrash.php │ ├── FakeFavicon │ │ └── FakeFavicon.php │ ├── EnableAllLanguages │ │ └── EnableAllLanguages.php │ ├── QuickAdd │ │ └── QuickAdd.php │ ├── RemoveVariations │ │ └── RemoveVariations.php │ └── QuickWebAuthnLogin │ │ └── QuickWebAuthnLogin.php ├── Modules │ ├── UpgradesRefresh │ │ ├── UpgradesRefresh.js │ │ └── UpgradesRefresh.php │ └── CollapseInfo │ │ └── CollapseInfo.php ├── PageList │ ├── FullRowHover │ │ ├── FullRowHover.php │ │ └── FullRowHover.css │ ├── AddModalParam │ │ ├── AddModalParam.php │ │ └── AddModalParam.js │ ├── ShowExtraActions │ │ ├── ShowExtraActions.php │ │ └── ShowExtraActions.js │ ├── TemplateLink │ │ └── TemplateLink.php │ └── NonSuperuserTrash │ │ └── NonSuperuserTrash.php ├── Inputfields │ ├── CheckAllCheckboxes │ │ ├── CheckAllCheckboxes.php │ │ ├── CheckAllCheckboxes.js │ │ └── CheckAllCheckboxes.css │ ├── AsmSearchBox │ │ ├── select2 │ │ │ ├── js │ │ │ │ ├── select2-v4.0.2.patch │ │ │ │ └── select2.min.js │ │ │ └── css │ │ │ │ └── select2.min.css │ │ ├── AsmSearchBox.php │ │ ├── AsmSearchBox.css │ │ └── AsmSearchBox.js │ ├── CopyFieldNames │ │ ├── CopyFieldNames.php │ │ └── CopyFieldNames.js │ ├── ColumnBreak │ │ ├── ColumnBreak.css │ │ ├── ColumnBreak.js │ │ ├── split.js │ │ │ └── split.min.js │ │ └── ColumnBreak.php │ ├── PageListSelectUnselectRestore │ │ ├── PageListSelectUnselectRestore.css │ │ ├── PageListSelectUnselectRestore.js │ │ └── PageListSelectUnselectRestore.php │ └── ImageDownload │ │ └── ImageDownload.php └── PageEdit │ ├── PrevNextPage │ ├── PrevNextPage.css │ ├── PrevNextPage.js │ └── PrevNextPage.php │ └── EditFieldLinks │ ├── EditFieldLinks.js │ ├── EditFieldLinks.css │ └── EditFieldLinks.php ├── README.md ├── .editorconfig ├── RockAdminTweaks.info.php ├── tweak.txt ├── .github └── workflows │ └── releases.yml ├── docs ├── assets │ └── readme.md └── readme.md ├── CHANGELOG.md ├── classes └── Tweak.php └── RockAdminTweaks.module.php /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.13.0" 3 | } 4 | -------------------------------------------------------------------------------- /tweaks/General/BypassTrash/BypassTrash.css: -------------------------------------------------------------------------------- 1 | a.aos-pagelist-confirm + a.aos-pagelist-confirm { 2 | margin-left: 3px; 3 | } 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RockAdminTweaks 2 | 3 | Please read the docs at https://www.baumrock.com/en/processwire/modules/rockadmintweaks/docs/ 4 | -------------------------------------------------------------------------------- /tweaks/Modules/UpgradesRefresh/UpgradesRefresh.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", function() { 2 | var upgrades_url = ProcessWire.config.urls.admin + 'setup/upgrades/'; 3 | $('a[href="' + upgrades_url + '"]').attr('href', upgrades_url + 'refresh'); 4 | }); 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | ; This file is for unifying the coding style for different editors and IDEs. 2 | ; More information at http://editorconfig.org 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | 7 | [*.{php,inc,module,js,css,less,scss}] 8 | indent_style = space 9 | indent_size = 2 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | -------------------------------------------------------------------------------- /tweaks/PageList/FullRowHover/FullRowHover.php: -------------------------------------------------------------------------------- 1 | 'Show pagelist actions on full row hover', 11 | ]; 12 | } 13 | 14 | public function ready(): void 15 | { 16 | $this->loadCSS(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /RockAdminTweaks.info.php: -------------------------------------------------------------------------------- 1 | 'RockAdminTweaks', 7 | 'version' => json_decode(file_get_contents(__DIR__ . '/package.json'))->version, 8 | 'summary' => 'Tweaks for the ProcessWire Backend.', 9 | 'autoload' => 'template=admin', 10 | 'singular' => true, 11 | 'icon' => 'magic', 12 | 'requires' => [ 13 | 'PHP>=8.1', 14 | ], 15 | ]; 16 | -------------------------------------------------------------------------------- /tweaks/PageList/AddModalParam/AddModalParam.php: -------------------------------------------------------------------------------- 1 | 'Adds &modal=1 to all links in the pagelist when the pagelist is viewed in a modal window', 11 | ]; 12 | } 13 | 14 | public function init(): void 15 | { 16 | $this->loadJS(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tweaks/Modules/UpgradesRefresh/UpgradesRefresh.php: -------------------------------------------------------------------------------- 1 | 'Always refresh when visiting ProcessWireUpgrades', 14 | ]; 15 | } 16 | 17 | public function ready(): void 18 | { 19 | $this->loadJS(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tweaks/PageList/FullRowHover/FullRowHover.css: -------------------------------------------------------------------------------- 1 | html:not(.pListShowActions) 2 | #content 3 | .PageList 4 | .PageListItem:hover 5 | .PageListActions { 6 | display: inline-block; 7 | } 8 | html:not(.pListShowActions) 9 | #content 10 | .PageList 11 | .PageListItemOpen 12 | .PageListActions { 13 | display: none; 14 | } 15 | html:not(.pListShowActions) 16 | #content 17 | .PageList 18 | .PageListItemOpen:hover 19 | .PageListActions { 20 | display: inline-block; 21 | } 22 | -------------------------------------------------------------------------------- /tweaks/Inputfields/CheckAllCheckboxes/CheckAllCheckboxes.php: -------------------------------------------------------------------------------- 1 | 'Add checkbox to check all checkboxes in a field', 14 | ]; 15 | } 16 | 17 | public function ready(): void 18 | { 19 | $this->loadJS(); 20 | $this->loadCSS(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tweaks/PageEdit/PrevNextPage/PrevNextPage.css: -------------------------------------------------------------------------------- 1 | .aos-edit-prev, 2 | .aos-edit-next { 3 | padding: 0 0.3rem; 4 | position: relative; 5 | top: 1px; 6 | } 7 | 8 | .aos-edit-prev:not(:hover), 9 | .aos-edit-next:not(:hover) { 10 | color: #ccc; 11 | } 12 | 13 | .aos-edit-prev i, 14 | .aos-edit-next i { 15 | font-size: 17px !important; 16 | } 17 | 18 | html:not(.AdminThemeDefault) .aos-edit-prev i, 19 | html:not(.AdminThemeDefault) .aos-edit-next i { 20 | font-size: 27px !important; 21 | } 22 | 23 | .aos-edit-prev { 24 | margin-left: 0.6rem; 25 | } 26 | -------------------------------------------------------------------------------- /tweaks/PageList/ShowExtraActions/ShowExtraActions.php: -------------------------------------------------------------------------------- 1 | 'Shows extra page action items in page tree for SuperUsers', 13 | ]; 14 | } 15 | 16 | public function init(): void 17 | { 18 | if (wire()->config->ajax) return; 19 | wire()->addHookAfter( 20 | "ProcessPageList::execute", 21 | function () { 22 | $this->loadJS(); 23 | } 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tweaks/General/FakeFavicon/FakeFavicon.php: -------------------------------------------------------------------------------- 1 | 'Adds a fake favicon to the backend to prevent 404 in devtools.', 13 | ]; 14 | } 15 | 16 | public function init(): void 17 | { 18 | $this->wire->addHookAfter('AdminTheme::getExtraMarkup', $this, 'addFavicon'); 19 | } 20 | 21 | public function addFavicon(HookEvent $event) 22 | { 23 | $parts = $event->return; 24 | $parts['head'] .= ''; 25 | $event->return = $parts; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tweaks/Inputfields/AsmSearchBox/select2/js/select2-v4.0.2.patch: -------------------------------------------------------------------------------- 1 | diff -Naur old/select2-v4.0.2/dist/js/select2.full.js new/select2-v4.0.2/dist/js/select2.full.js 2 | --- old/select2-v4.0.2/dist/js/select2.full.js 2016-03-08 17:33:38.000000000 -0800 3 | +++ new/select2-v4.0.2/dist/js/select2.full.js 2016-04-26 18:10:26.000000000 -0700 4 | @@ -5122,11 +5122,13 @@ 5 | var self = this; 6 | 7 | this.$element.on('change.select2', function () { 8 | + if (self.dataAdapter != null) { 9 | self.dataAdapter.current(function (data) { 10 | self.trigger('selection:update', { 11 | data: data 12 | }); 13 | }); 14 | + } 15 | }); 16 | 17 | this._sync = Utils.bind(this._syncAttributes, this); 18 | -------------------------------------------------------------------------------- /tweaks/PageList/ShowExtraActions/ShowExtraActions.js: -------------------------------------------------------------------------------- 1 | /* Originally by tpr in the AdminOnSteroids module */ 2 | /* Ported to RockAdminTweaks by netcarver */ 3 | $(document).on("mouseover", ".PageListItem", function () { 4 | var $extrasToggle = $(this).find(".clickExtras"), 5 | $templateEditAction = $(this).find( 6 | ".PageListActionEdit ~ .PageListActionEdit" 7 | ); 8 | if ($extrasToggle.length) { 9 | $extrasToggle.trigger("click").remove(); 10 | if ($(this).find(".PageListActionExtras").length) { 11 | $(this).find(".PageListActionExtras").remove(); 12 | } 13 | // move template edit link to the end 14 | if ($templateEditAction.length) { 15 | $templateEditAction.parent().append($templateEditAction); 16 | } 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /tweak.txt: -------------------------------------------------------------------------------- 1 | 'Put your short tweak description here', 11 | // 'help' => 'Optional longer description - opens in a **modal** and supports [markdown](/).', 12 | // 'author' => 'Bernhard Baumrock', 13 | // 'authorUrl' => 'https://processwire.com/talk/profile/2137-bernhard/', 14 | // 'maintainer' => 'If different from author', 15 | // 'maintainerUrl' => 'If different from author', 16 | // 'infoLink' => 'External info link, eg forum thread', 17 | ]; 18 | } 19 | 20 | public function init(): void 21 | { 22 | } 23 | 24 | public function ready(): void 25 | { 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tweaks/Modules/CollapseInfo/CollapseInfo.php: -------------------------------------------------------------------------------- 1 | 'Collapse Module Info section by default', 17 | ]; 18 | } 19 | 20 | 21 | public function ready(): void 22 | { 23 | $this->wire->addHookAfter('InputfieldMarkup::render', function (HookEvent $event) { 24 | $field = $event->object; 25 | if ($field->id === 'ModuleInfo') { 26 | $field->collapsed = Inputfield::collapsedYes; 27 | } 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tweaks/Inputfields/CopyFieldNames/CopyFieldNames.php: -------------------------------------------------------------------------------- 1 | 'Copy field names on shift-click by SuperUsers', 13 | 'infoLink' => 'https://processwire.com/talk/topic/29071--', 14 | ]; 15 | } 16 | 17 | public function init(): void 18 | { 19 | // Add custom JS file to $config->scripts FilenameArray 20 | // This adds the custom JS fairly early in the FilenameArray which allows for stopping 21 | // event propagation so clicks on InputfieldHeader do not also expand/collapse InputfieldContent 22 | if (!$this->wire->user->isSuperuser()) return; 23 | wire()->addHookBefore('ProcessController::execute', $this, 'loadJS'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.github/workflows/releases.yml: -------------------------------------------------------------------------------- 1 | name: Releases 2 | on: 3 | push: 4 | branches: 5 | - main 6 | 7 | jobs: 8 | changelog: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v4 13 | - name: conventional Changelog Action 14 | id: changelog 15 | uses: TriPSs/conventional-changelog-action@v5.1.0 16 | with: 17 | preset: "conventionalcommits" 18 | github-token: ${{ secrets.github_token }} 19 | 20 | - name: create release 21 | uses: actions/create-release@v1 22 | if: ${{ steps.changelog.outputs.skipped == 'false' }} 23 | env: 24 | GITHUB_TOKEN: ${{ secrets.github_token }} 25 | with: 26 | tag_name: ${{ steps.changelog.outputs.tag }} 27 | release_name: ${{ steps.changelog.outputs.tag }} 28 | body: ${{ steps.changelog.outputs.clean_changelog }} 29 | -------------------------------------------------------------------------------- /tweaks/Inputfields/CopyFieldNames/CopyFieldNames.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | // Copy a string to the clipboard 3 | function copyToClipboard(string) { 4 | const $temp = $(''); 5 | $("body").append($temp); 6 | $temp[0].select(); 7 | document.execCommand("copy"); 8 | $temp.remove(); 9 | } 10 | 11 | // When InputfieldHeader is clicked 12 | $(document).on("click", ".InputfieldHeader", function (event) { 13 | let text = ""; 14 | if (!event.shiftKey) return; 15 | 16 | event.preventDefault(); 17 | event.stopImmediatePropagation(); 18 | text = $(this).attr("for"); 19 | if (!text) text = $(this).parent().attr("id"); 20 | text = text.replace(/^Inputfield_|wrap_Inputfield_|wrap_/, "").trim(); 21 | if (!text) return; 22 | 23 | copyToClipboard(text); 24 | $(this).effect("highlight", {}, 500); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /tweaks/General/EnableAllLanguages/EnableAllLanguages.php: -------------------------------------------------------------------------------- 1 | 'Enable all languages after a new page has been added.', 15 | ]; 16 | } 17 | 18 | public function init(): void 19 | { 20 | $this->wire->addHookBefore('Pages::added', $this, 'enableLanguages'); 21 | } 22 | 23 | /** 24 | * Enable all languages for all created pages 25 | * @param HookEvent $event 26 | * @return void 27 | * @throws WireException 28 | */ 29 | protected function enableLanguages(HookEvent $event): void 30 | { 31 | if (!wire()->languages) return; 32 | $p = $event->arguments(0); 33 | foreach (wire()->languages->findNonDefault() as $language) { 34 | $p->setLanguageStatus($language, true); 35 | } 36 | $p->save(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /docs/assets/readme.md: -------------------------------------------------------------------------------- 1 | # Assets 2 | 3 | Tweaks can load JS and CSS assets. As you might want to load assets based on some conditions we do not automatically load them. But it's only one line of code to do so and it will automatically take care of cache busting: 4 | 5 | ## JS 6 | 7 | ```php 8 | // the tweak CopyFieldNames.php will load 9 | // the js file CopyFieldNames.js 10 | $this->loadJS(); 11 | ``` 12 | 13 | The only thing you have to define is when to load the script, for example: 14 | 15 | ```php 16 | public function init(): void 17 | { 18 | if (!$this->wire->user->isSuperuser()) return; 19 | wire()->addHookBefore( 20 | 'ProcessController::execute', 21 | function () { 22 | $this->loadJS(); 23 | } 24 | ); 25 | } 26 | 27 | // or shorter: 28 | public function init(): void 29 | { 30 | if (!$this->wire->user->isSuperuser()) return; 31 | wire()->addHookBefore('ProcessController::execute', $this, 'loadJS'); 32 | } 33 | ``` 34 | 35 | ## CSS 36 | 37 | For CSS the principle is exactly the same, just use `loadCSS` instead of `loadJS`. 38 | -------------------------------------------------------------------------------- /tweaks/General/QuickAdd/QuickAdd.php: -------------------------------------------------------------------------------- 1 | 'Skip template selection on page add if only a single template is allowed.', 13 | ]; 14 | } 15 | 16 | public function init(): void 17 | { 18 | $this->wire->addHookBefore('ProcessPageAdd::buildForm', $this, 'skipAdd'); 19 | } 20 | 21 | public function skipAdd(HookEvent $event) 22 | { 23 | // this prevents the hook to run on ProcessUser 24 | if ($event->process != 'ProcessPageAdd') return; 25 | $templates = $event->process->getAllowedTemplates(); 26 | if (count($templates) !== 1) return; 27 | foreach ($templates as $k => $tpl) { 28 | $p = $this->wire->pages->newPage($tpl); 29 | $p->parent = $this->wire->input->get('parent_id', 'int'); 30 | $p->addStatus('unpublished'); 31 | $p->save(); 32 | $this->wire->session->redirect($p->editUrl()); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /docs/readme.md: -------------------------------------------------------------------------------- 1 | # RockAdminTweaks 2 | 3 | RockAdminTweaks is a module for ProcessWire that provides a collection of useful features and hacks, referred to as "tweaks", for the ProcessWire backend. These tweaks can be easily enabled or disabled via checkboxes in the module's configuration page. 4 | 5 | 6 | 7 | ### Features: 8 | - **Easy Customization**: Users can create their own tweaks by simply adding PHP, JS, or CSS files. 9 | - **Modular Design**: Each tweak is self-contained, making it easy to manage and configure. 10 | - **Dynamic Loading**: Tweaks are loaded dynamically based on the user's selections, ensuring that only the necessary resources are used. 11 | 12 | RockAdminTweaks is the successor to the popular ProcessWire module "AdminOnSteroids". While AdminOnSteroids provided a range of enhancements and customizations for the ProcessWire admin panel, RockAdminTweaks builds upon and extends these features with a more modular and dynamic approach. Users familiar with AdminOnSteroids will find RockAdminTweaks to be a familiar experience. 13 | -------------------------------------------------------------------------------- /tweaks/PageEdit/PrevNextPage/PrevNextPage.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", function () { 2 | var PrevNextLinks = ProcessWire.config.AOS_prevnextlinks; 3 | if (PrevNextLinks) { 4 | var targetElement = $("h1, li.title span, li.title").first(); 5 | if (targetElement.length) { 6 | var icon; 7 | if (PrevNextLinks.prev) { 8 | icon = "fa fa-angle-left"; 9 | targetElement.append( 10 | '' 18 | ); 19 | } 20 | if (PrevNextLinks.next) { 21 | icon = "fa fa-angle-right"; 22 | targetElement.append( 23 | '' 31 | ); 32 | } 33 | } 34 | } 35 | }); 36 | -------------------------------------------------------------------------------- /tweaks/Inputfields/AsmSearchBox/AsmSearchBox.php: -------------------------------------------------------------------------------- 1 | 'Add search box to ASM Select dropdowns', 17 | ]; 18 | } 19 | 20 | public function ready(): void 21 | { 22 | 23 | $this->wire('config')->scripts->add($this->pathToUrl(__DIR__ . '/select2/js/select2.min.js')); 24 | $this->wire('config')->styles->add($this->pathToUrl(__DIR__ . '/select2/css/select2.min.css')); 25 | 26 | $this->loadJS(); 27 | $this->loadCSS(); 28 | 29 | $this->addHookAfter('InputfieldAsmSelect::render', $this, 'addAsmSelectBox'); 30 | 31 | } 32 | 33 | public function addAsmSelectBox($event) 34 | { 35 | $field = $event->object; 36 | 37 | if ($field->attr('data-no-asm-searchbox') === '1') { 38 | return; 39 | } 40 | 41 | $id = $field->attr('id'); 42 | 43 | $script = ""; 44 | 45 | $event->return .= $script; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /tweaks/Inputfields/ColumnBreak/ColumnBreak.css: -------------------------------------------------------------------------------- 1 | .aos_col_left, 2 | .aos_col_right { 3 | width: 67%; 4 | float: left; 5 | clear: none !important; 6 | margin-top: 0 !important; 7 | 8 | >.InputfieldContent { 9 | background: transparent; 10 | } 11 | } 12 | 13 | .aos_col_right { 14 | width: 33%; 15 | margin-left: -1px !important; 16 | } 17 | 18 | /*hide aos_column_break field*/ 19 | #ProcessPageEditContent #wrap_Inputfield_aos_column_break { 20 | height: 0 !important; 21 | overflow: hidden !important; 22 | } 23 | 24 | .aos_no-inputfield-padding > .InputfieldContent { 25 | padding: 0; 26 | } 27 | 28 | /*remove line under wiretabs (uikit)*/ 29 | #PageEditTabs.WireTabs.uk-tab::before { 30 | display: none; 31 | } 32 | 33 | 34 | html .Inputfields { 35 | zoom: 1; 36 | } 37 | html .Inputfields:before, html .Inputfields:after { 38 | content: " "; 39 | display: block; 40 | height: 0; 41 | overflow: hidden; 42 | } 43 | html .Inputfields:after { 44 | clear: both; 45 | } 46 | html .gutter { 47 | cursor: ew-resize; 48 | float: left; 49 | min-height: 200px; 50 | position: relative; 51 | z-index: 300; 52 | } 53 | html .gutter:active:before { 54 | content: ""; 55 | position: fixed; 56 | left: 0; 57 | top: 0; 58 | bottom: 0; 59 | right: 0; 60 | background: transparent; 61 | } 62 | -------------------------------------------------------------------------------- /tweaks/Inputfields/CheckAllCheckboxes/CheckAllCheckboxes.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | 3 | var $checkAllCheckboxes = $('
  • '); 4 | function updateCheckCheckboxState($ul) { 5 | $checkAllCheckboxes.attr('data-checked-all', $ul.find('input:not(:checked)').length === 0 ? '1' : ''); 6 | } 7 | function checkCheckboxes(e, $ul) { 8 | if (e.which !== 1) return true; // fire on left click only 9 | var isAllChecked = $ul.find('input:not(:checked)').length > 0, 10 | inputSelector = isAllChecked ? 'input:not(:checked)' : 'input:checked'; 11 | // need to trigger change, eg. for showIf fields 12 | $ul.find(inputSelector).attr('checked', isAllChecked).trigger('change'); 13 | return isAllChecked; 14 | } 15 | $(document).on('change', 'ul[class*="InputfieldCheckboxes"] input', function () { 16 | updateCheckCheckboxState($(this).parents('ul').first()); 17 | }); 18 | $checkAllCheckboxes.on('click', function (e) { 19 | $(this).attr('data-checked-all', checkCheckboxes(e, $(this).parent()) > 0 ? '1' : ''); 20 | }); 21 | $(document).on('hover', '.InputfieldCheckboxes ul[class*="InputfieldCheckboxes"]', function () { 22 | updateCheckCheckboxState($(this)); 23 | $(this).append($checkAllCheckboxes); 24 | }); 25 | 26 | }); 27 | -------------------------------------------------------------------------------- /tweaks/General/RemoveVariations/RemoveVariations.php: -------------------------------------------------------------------------------- 1 | 'Remove all image variations instead of rebuilding them', 24 | 'infoLink' => 'https://processwire.com/talk/topic/31127--', 25 | ]; 26 | } 27 | 28 | public function init(): void 29 | { 30 | wire()->addHookBefore('Pageimage::rebuildVariations', $this, 'removeVariations'); 31 | } 32 | 33 | public function removeVariations(HookEvent $event) 34 | { 35 | /** @var Pageimage $pageimage */ 36 | $pageimage = $event->object; 37 | $event->replace = true; 38 | $pageimage->removeVariations(); 39 | // Return expected output to avoid errors 40 | $event->return = [ 41 | 'rebuilt' => [], 42 | 'skipped' => [], 43 | 'reasons' => [], 44 | 'errors' => [], 45 | ]; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tweaks/Inputfields/CheckAllCheckboxes/CheckAllCheckboxes.css: -------------------------------------------------------------------------------- 1 | #checkAllCheckboxes { 2 | display: inline-block; 3 | visibility: hidden; 4 | opacity: 0; 5 | position: absolute; 6 | bottom: 100%; 7 | left: 0; 8 | float: none; 9 | margin-left: -0.45rem !important; 10 | cursor: pointer; 11 | border: 3px solid white; 12 | width: 1.7rem; 13 | height: 1.7rem; 14 | border-radius: 100%; 15 | background: #E2E9EF; 16 | text-align: center; 17 | padding: 0 !important; 18 | user-select: none; 19 | backface-visibility: hidden; 20 | z-index: 3; 21 | } 22 | #checkAllCheckboxes i { 23 | pointer-events: none; 24 | position: relative; 25 | top: -2px; 26 | } 27 | #checkAllCheckboxes i::before { 28 | font-size: 0.75rem; 29 | color: #3EB998; 30 | text-shadow: 0 0 2px rgba(255, 255, 255, 0.7); 31 | } 32 | #checkAllCheckboxes:hover { 33 | background: #3EB998; 34 | } 35 | #checkAllCheckboxes:hover i::before { 36 | color: white; 37 | text-shadow: none; 38 | } 39 | #checkAllCheckboxes[data-checked-all="1"] i::before { 40 | content: "\f00d" !important; 41 | } 42 | 43 | ul[class*=InputfieldCheckboxes] { 44 | position: relative; 45 | } 46 | ul[class*=InputfieldCheckboxes]::before { 47 | content: ""; 48 | position: absolute; 49 | bottom: 100%; 50 | left: 0; 51 | right: 0; 52 | height: 1.4rem; 53 | } 54 | ul[class*=InputfieldCheckboxes]:hover #checkAllCheckboxes { 55 | opacity: 1; 56 | visibility: visible; 57 | } 58 | -------------------------------------------------------------------------------- /tweaks/PageEdit/EditFieldLinks/EditFieldLinks.js: -------------------------------------------------------------------------------- 1 | $(document).on('mousedown', '.Inputfield .aos_EditField', function (e) { 2 | var fieldID = $(this).attr('data-for-field'), 3 | // in repeaters field names are suffixed, eg. "excerpt_repeater1516" 4 | editFieldLink = $(this).parents('.Inputfield').eq(0).find('.aos_EditFieldLink[data-field-id="' + fieldID + '"]'); 5 | 6 | // right click 7 | if (e.which === 3) return false; 8 | 9 | if (editFieldLink.length) { 10 | 11 | // if middle mouse button pressed, open a new page 12 | if (e.which === 2 || e.button === 4) { 13 | window.open(editFieldLink.attr('href').replace('&modal=1', '')); 14 | } else { 15 | editFieldLink[0].click(); 16 | } 17 | 18 | return false; 19 | 20 | } 21 | }); 22 | 23 | // workaround: add edit links to ajax-loaded fields 24 | $('.Inputfield:not(.InputfieldPageListSelect)').on('reloaded', function () { 25 | var field = $(this), 26 | label = field.children('label'); 27 | 28 | if (!label.length) return; 29 | 30 | if (label.find('span').length === 0) { 31 | field.addClass('aos_hasTooltip'); 32 | var fieldName = label.parent().find('.InputfieldContent .aos_EditFieldLink').attr('data-field-name'); 33 | 34 | if (!fieldName) return; 35 | 36 | label.contents().eq(0).wrap(''); 37 | field.find('span.title').append('' + fieldName + ' '); 38 | } 39 | }); 40 | -------------------------------------------------------------------------------- /tweaks/Inputfields/PageListSelectUnselectRestore/PageListSelectUnselectRestore.css: -------------------------------------------------------------------------------- 1 | .aos_pagelist_unselect { 2 | margin-top: 1px !important; 3 | padding: 0 !important; 4 | text-align: center; 5 | border: none !important; 6 | transition-duration: 0.1s !important; 7 | max-width: 60px; 8 | line-height: 1 !important; 9 | } 10 | .aos_pagelist_unselect i { 11 | padding: 3px 5px !important; 12 | display: inline-block; 13 | } 14 | .aos_pagelist_unselect, .aos_pagelist_unselect:hover { 15 | padding: 0 !important; 16 | } 17 | .aos_pagelist_unselect.empty, .aos_pagelist_unselect.initial { 18 | pointer-events: none; 19 | opacity: 0.3; 20 | filter: saturate(0); 21 | border-color: inherit; 22 | } 23 | .aos_pagelist_unselect.clear { 24 | background-color: transparent !important; 25 | margin-left: -3px; 26 | margin-right: 5px; 27 | float: left; 28 | color: #8d939e !important; 29 | } 30 | .aos_pagelist_unselect.clear:hover { 31 | color: #8d939e !important; 32 | background-color: transparent !important; 33 | } 34 | .aos_pagelist_unselect.clear:hover i { 35 | transform: scale(1.2); 36 | transform-origin: center; 37 | } 38 | .aos_pagelist_unselect.clear:hover ~ .PageListRoot .PageListSelectName { 39 | text-decoration: line-through; 40 | } 41 | .aos_pagelist_unselect.clear ~ .PageListRoot { 42 | float: left; 43 | width: calc(100% - 54px); 44 | margin-bottom: 1rem; 45 | } 46 | .aos_pagelist_unselect.clear ~ .notes { 47 | width: 100%; 48 | clear: both; 49 | } 50 | .aos_pagelist_unselect.restore { 51 | position: relative; 52 | top: -3px; 53 | margin-right: 0; 54 | } 55 | -------------------------------------------------------------------------------- /tweaks/PageList/AddModalParam/AddModalParam.js: -------------------------------------------------------------------------------- 1 | // wait for document to be ready 2 | $(document).ready(() => { 3 | // detect if we are in a modal 4 | const isModal = document.body.classList.contains("modal"); 5 | // console.log("isModal", isModal); 6 | if (!isModal) return; 7 | 8 | // get the modal parameter of the current url and exit if it doesn't exist 9 | const params = new URLSearchParams(window.location.search); 10 | const modal = params.get("modal"); 11 | 12 | // on every ajax request update all pagelist links 13 | $(document).on("ajaxComplete", () => { 14 | const links = document.querySelectorAll(".PageListRoot a[href]"); 15 | 16 | links.forEach((link) => { 17 | // get href attribute 18 | const href = link.getAttribute("href"); 19 | 20 | // don't update # links 21 | if (href === "#") return; 22 | 23 | // don't update links that do not point to the backend 24 | // which means they do not start with ProcessWire.config.urls.admin 25 | if (!href.startsWith(ProcessWire.config.urls.admin)) return; 26 | 27 | try { 28 | // get the base path and search params 29 | const [path, search] = href.split("?"); 30 | const params = new URLSearchParams(search); 31 | 32 | // if it already has a modal parameter, exit 33 | if (params.get("modal")) return; 34 | 35 | // add the modal parameter 36 | params.set("modal", modal); 37 | 38 | // construct the new href 39 | const queryString = params.toString() ? "?" + params.toString() : ""; 40 | const newHref = path + queryString; 41 | 42 | // replace the href 43 | link.setAttribute("href", newHref); 44 | } catch (error) { 45 | console.error("failed to build url", href); 46 | } 47 | }); 48 | }); 49 | }); 50 | -------------------------------------------------------------------------------- /tweaks/Inputfields/ImageDownload/ImageDownload.php: -------------------------------------------------------------------------------- 1 | 'Adds a download icon to image fields.', 16 | 'help' => 'Optional longer description - opens in a **modal** and supports [markdown](/).', 17 | 'author' => 'Bernhard Baumrock', 18 | 'authorUrl' => 'https://processwire.com/talk/profile/2137-bernhard/', 19 | 'infoLink' => 'https://processwire.com/talk/topic/28089--', 20 | ]; 21 | } 22 | 23 | public function init(): void 24 | { 25 | wire()->addHookAfter( 26 | 'InputfieldImage::getImageThumbnailActions', 27 | function (HookEvent $event) { 28 | $image = $event->arguments(0); // Pageimage 29 | $class = $event->arguments(3); // class to use on all returned actions 30 | $a = $event->return; // array 31 | $icon = wireIconMarkup('download'); 32 | $a['download'] = "$icon"; 33 | $event->return = $a; 34 | } 35 | ); 36 | wire()->addHookAfter( 37 | 'InputfieldImage::getImageEditButtons', 38 | function (HookEvent $event) { 39 | $image = $event->arguments(0); // Pageimage 40 | $class = $event->arguments(3); // class(es) to use on all returned actions 41 | $buttons = $event->return; // array, indexed by action name 42 | $icon = wireIconMarkup('download'); 43 | $buttons['download'] = ""; 44 | $event->return = $buttons; 45 | } 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tweaks/PageList/TemplateLink/TemplateLink.php: -------------------------------------------------------------------------------- 1 | "Shows the template name and edit link in the page tree action list for SuperUsers", 16 | ]; 17 | } 18 | 19 | 20 | public function ready(): void 21 | { 22 | if (!$this->wire->user->isSuperuser()) { 23 | return; 24 | } 25 | $this->wire->addHookAfter('ProcessPageListActions::getActions', $this, 'addAction'); 26 | } 27 | 28 | 29 | public function addAction(HookEvent $event) 30 | { 31 | $page = $event->arguments('page'); 32 | $actions = $event->return; 33 | $template = $page->template; 34 | 35 | $templateEditUrl = $this->config->urls->httpAdmin . 'setup/template/edit?id=' . $template->id; 36 | 37 | $editTemplateAction = [ 38 | 'editTemplate' => [ 39 | // use "Edit" to enable built-in long-click feature 40 | 'cn' => 'Edit', 41 | 'name' => $template->name, 42 | 'url' => $templateEditUrl, 43 | ], 44 | ]; 45 | 46 | // put the template edit action before the Extras ( 47 | $key_extras = array_search('extras', array_keys($actions)); 48 | 49 | // home, trash, etc doesn't have 'extras', add the button to the end 50 | if (!$key_extras) { 51 | $key_extras = count($actions); 52 | } 53 | 54 | $actions = array_merge( 55 | array_slice($actions, 0, $key_extras, true), 56 | $editTemplateAction, 57 | array_slice($actions, $key_extras, null, true) 58 | ); 59 | 60 | $event->return = $actions; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /tweaks/PageList/NonSuperuserTrash/NonSuperuserTrash.php: -------------------------------------------------------------------------------- 1 | 'Add Trash action also for non-SuperUsers', 16 | 'author' => 'Roland Toth', 17 | 'authorUrl' => 'https://processwire.com/talk/profile/3156--', 18 | 'maintainer' => 'Adrian Jones', 19 | 'maintainerUrl' => 'https://processwire.com/talk/profile/985--', 20 | 'help' => 'Compared to the core option of ProcessPageList to show trash for non-superusers this tweak only adds the "trash" action to the pagelist actions buttons, but the trash page in the tree will not be accessible with this tweak. If you want to make the trash page also accessible you can use the core feature in ProcessPageList config settings.', 21 | ]; 22 | } 23 | 24 | 25 | public function ready(): void 26 | { 27 | if (!$this->wire->user->isSuperuser()) { 28 | $this->addHookAfter('ProcessPageListActions::getExtraActions', function (HookEvent $event) { 29 | $page = $event->arguments(0); 30 | $extras = $event->return; 31 | if ($page->trashable()) { 32 | $trash_icon = " "; 33 | $extras['trash'] = array( 34 | 'cn' => 'Trash aos-pagelist-confirm', 35 | 'name' => $trash_icon . $this->_('Trash'), 36 | 'url' => $this->wire('config')->urls->admin . "page/?action=trash&id=$page->id", 37 | 'ajax' => true, 38 | ); 39 | } 40 | $event->return = $extras; 41 | }); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [1.13.0](https://github.com/baumrock/RockAdminTweaks/compare/v1.12.0...v1.13.0) (2025-08-02) 2 | 3 | 4 | ### Features 5 | 6 | * add FakeFavicon tweak ([36a0be8](https://github.com/baumrock/RockAdminTweaks/commit/36a0be89d61fde997f3754d127c3d4b5b1cdb272)) 7 | 8 | 9 | ### Bug Fixes 10 | 11 | * adjust bottom setting for new admin theme [#18](https://github.com/baumrock/RockAdminTweaks/issues/18) ([b9b52e3](https://github.com/baumrock/RockAdminTweaks/commit/b9b52e3a8ae8e48dfb5c3cf596ced8132f24da1e)) 12 | 13 | ## [1.12.0](https://github.com/baumrock/RockAdminTweaks/compare/v1.11.0...v1.12.0) (2025-04-06) 14 | 15 | 16 | ### Features 17 | 18 | * new tweak to remove variations to force recreating them ([5389583](https://github.com/baumrock/RockAdminTweaks/commit/538958331545c8898403fb7bb8d32d4adb0c74ad)) 19 | 20 | ## [1.11.0](https://github.com/baumrock/RockAdminTweaks/compare/v1.10.0...v1.11.0) (2025-03-12) 21 | 22 | 23 | ### Features 24 | 25 | * add tweak to enable all languages ([f2a62c6](https://github.com/baumrock/RockAdminTweaks/commit/f2a62c61c4a76f9bb490a83aee43447bc512ccba)) 26 | 27 | ## [1.10.0](https://github.com/baumrock/RockAdminTweaks/compare/v1.9.3...v1.10.0) (2025-01-07) 28 | 29 | 30 | ### Features 31 | 32 | * add tweak to add modal param to pagelist links ([46871fe](https://github.com/baumrock/RockAdminTweaks/commit/46871fe5880aba630d6c5f5a073ee68066f6d3ef)) 33 | 34 | ## [1.9.3](https://github.com/baumrock/RockAdminTweaks/compare/v1.9.2...v1.9.3) (2024-07-22) 35 | 36 | 37 | ### Bug Fixes 38 | 39 | * add check for originalTitle before strlen() ([b8382ae](https://github.com/baumrock/RockAdminTweaks/commit/b8382ae271bbeb6d6f2181f66557d3842a9ec9d6)) 40 | * quickadd causing error when creating new users ([f794d6b](https://github.com/baumrock/RockAdminTweaks/commit/f794d6bd03a80ff0924c3d16f38dbcf91df4ac53)) 41 | * restore original version ([96a74d1](https://github.com/baumrock/RockAdminTweaks/commit/96a74d1b9876b1369a25034c5219975df077b6fe)) 42 | 43 | -------------------------------------------------------------------------------- /tweaks/Inputfields/PageListSelectUnselectRestore/PageListSelectUnselectRestore.js: -------------------------------------------------------------------------------- 1 | $(document).on('pageSelected', function (e, obj) { 2 | 3 | var clearButton = obj.a.parents('.InputfieldPageListSelect').first().find('button.clear'), 4 | restoreButton = obj.a.parents('.InputfieldPageListSelect').first().find('button.restore'); 5 | 6 | if (obj.id !== 0) { 7 | clearButton.removeClass('empty'); 8 | } else { 9 | clearButton.addClass('empty'); 10 | } 11 | 12 | restoreButton.removeClass('empty').removeClass('initial'); 13 | }); 14 | 15 | $(document).on('click', '.aos_pagelist_unselect', function () { 16 | 17 | var button = $(this), 18 | parentEl = button.parent(), 19 | input = button.parent().find('input'), 20 | //titleElem = button.parent().find('.PageListSelectName .label_title'); 21 | titleElem = button.parent().find('.PageListSelectName'); 22 | 23 | // try without .label_title (on pageSelected the span disappears) 24 | //if (!titleElem.length) { 25 | // titleElem = button.parent().find('.PageListSelectName'); 26 | //} 27 | 28 | if (button.hasClass('clear')) { 29 | // clear 30 | input.removeAttr('value'); 31 | titleElem.html(''); 32 | button.addClass('empty'); 33 | 34 | parentEl.find('button.restore[data-value-original!=""]').removeClass('empty'); 35 | parentEl.find('button.restore').removeClass('initial'); 36 | } else { 37 | // restore 38 | input.val(button.attr('data-value-original')); 39 | titleElem.html(button.attr('data-title-original')); 40 | button.addClass('empty'); 41 | parentEl.find('button.clear').removeClass('empty'); 42 | } 43 | 44 | // if pagelist is open, close it 45 | if (parentEl.find('.PageListItemOpen').length) { 46 | parentEl.find('a.PageListSelectActionToggle').trigger('click'); 47 | } 48 | 49 | // allow dependent fields to update 50 | input.trigger('change'); 51 | 52 | return false; 53 | }); 54 | -------------------------------------------------------------------------------- /tweaks/Inputfields/PageListSelectUnselectRestore/PageListSelectUnselectRestore.php: -------------------------------------------------------------------------------- 1 | 'Add unselect/restore buttons to PageListSelect', 17 | ]; 18 | } 19 | 20 | public function ready(): void 21 | { 22 | 23 | $this->loadJS(); 24 | $this->loadCSS(); 25 | 26 | $this->addHookAfter('InputfieldPageListSelect::render', $this, 'addPageListUnselectButtons'); 27 | } 28 | 29 | public function addPageListUnselectButtons($event) 30 | { 31 | $field = $event->object; 32 | 33 | $originalID = ''; 34 | $originalTitle = ($field->value && $this->pages->get($field->value)) ? $this->pages->get($field->value)->title : ''; 35 | 36 | if (isset($this->PageListTweaks) && in_array('pListIDs', $this->PageListTweaks) && $this->wire('user')->isSuperuser()) { 37 | $originalID = ($field->value && $this->pages->get($field->value)) ? $this->pages->get($field->value)->id : ''; 38 | } 39 | 40 | $restoreTitleTag = $originalTitle && strlen($originalTitle) ? 'title="' . \ProcessWire\__('Restore', __FILE__) . ' "' . $originalTitle . '""' : ''; 41 | 42 | $clearButton = ''; 43 | 44 | $restoreButton = $field->value ? '' : ''; 45 | 46 | $event->return = $restoreButton . $clearButton . $event->return; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tweaks/General/BypassTrash/BypassTrash.js: -------------------------------------------------------------------------------- 1 | // Delete + non-superuser Trash actions 2 | // console.log(ProcessWire.config.AOS_BypassTrash); 3 | $(document).on("mousedown", "a.aos-pagelist-confirm", function (e) { 4 | var str_cancel = ProcessWire.config.AOS_BypassTrash.str_cancel; 5 | var str_confirm = ProcessWire.config.AOS_BypassTrash.str_confirm; 6 | 7 | // console.log(str_cancel); 8 | // console.log(str_confirm); 9 | 10 | e.preventDefault(); 11 | if (e.which === 3 || e.which === 2) return false; 12 | 13 | var link = $(this), 14 | url = link.attr("href"), 15 | linkTextDefault; 16 | 17 | if (!link.attr("data-text-original")) { 18 | var currentText = $(this).get(0).childNodes[1] 19 | ? $(this).get(0).childNodes[1].nodeValue 20 | : $(this).html(); 21 | link.attr("data-text-original", currentText); 22 | if (link.hasClass("PageListActionDelete") || link.hasClass("PageDelete")) { 23 | link.attr("data-text-confirm", str_confirm); 24 | } 25 | } 26 | 27 | if (url.indexOf("&force=1") === -1) { 28 | var linkCancel; 29 | linkTextDefault = link.attr("data-text-original"); 30 | 31 | if (link.hasClass("cancel")) { 32 | linkCancel = link.next("a"); 33 | linkCancel 34 | .removeClass("cancel") 35 | .attr("href", link.attr("href").replace("&force=1", "")) 36 | .contents() 37 | .last()[0].textContent = linkTextDefault; 38 | link.replaceWith(linkCancel); 39 | return false; 40 | } 41 | 42 | linkTextDefault = link.attr("data-text-confirm") 43 | ? link.attr("data-text-confirm") 44 | : link.attr("data-text-original"); 45 | linkCancel = link.clone(true); 46 | linkCancel.addClass("cancel").contents().last()[0].textContent = " " + str_cancel; 47 | 48 | // replace text only (keep icon) 49 | link.contents().last()[0].textContent = linkTextDefault; 50 | link.attr("href", link.attr("href") + "&force=1"); 51 | link.before(linkCancel); 52 | } 53 | 54 | return false; 55 | }); 56 | -------------------------------------------------------------------------------- /tweaks/Inputfields/AsmSearchBox/AsmSearchBox.css: -------------------------------------------------------------------------------- 1 | .select2-selection.select2-selection--single, 2 | .select2.select2-container, 3 | span.select2-dropdown { 4 | width: auto !important; 5 | min-width: 300px !important; 6 | max-width: 640px; 7 | } 8 | 9 | .select2-results__option { 10 | white-space: nowrap; 11 | } 12 | 13 | .select2-dropdown--above { 14 | border-bottom: 1px solid #aaa !important; 15 | } 16 | 17 | .select2-container--default .select2-selection--single { 18 | border-radius: 2px !important; 19 | } 20 | 21 | .select2-search--dropdown { 22 | padding: 0 !important; 23 | } 24 | .select2-search--dropdown input { 25 | padding-top: 0.36em !important; 26 | padding-bottom: 0.36em !important; 27 | } 28 | 29 | .select2-container--default .select2-results__option[aria-disabled=true] { 30 | color: #b4b4b4 !important; 31 | } 32 | 33 | .select2-container--default .select2-search--dropdown .select2-search__field { 34 | border-left: none !important; 35 | border-right: none !important; 36 | } 37 | 38 | .select2-container--default .select2-results > .select2-results__options { 39 | max-height: 360px !important; 40 | } 41 | 42 | .select2-results__option { 43 | padding: 2px 6px !important; 44 | } 45 | 46 | ol.asmList + select + .select2-container { 47 | display: none !important; 48 | } 49 | 50 | .select2-results__option:empty { 51 | display: none; 52 | } 53 | 54 | .select2-container--default .select2-selection--single .select2-selection__arrow { 55 | right: 4px !important; 56 | } 57 | 58 | .select2-container .select2-selection--single .select2-selection__rendered { 59 | padding-right: 24px !important; 60 | } 61 | 62 | .AdminThemeUikit .select2-container .select2-selection--single { 63 | height: 32px; 64 | } 65 | .AdminThemeUikit .select2-selection__rendered { 66 | line-height: 30px; 67 | } 68 | .AdminThemeUikit .select2-container--default .select2-selection--single .select2-selection__arrow { 69 | height: 30px; 70 | right: 6px; 71 | } 72 | .AdminThemeUikit .select2-container--default .select2-selection--single .select2-selection__rendered { 73 | line-height: 30px; 74 | } 75 | .AdminThemeUikit .select2-container .select2-selection--single .select2-selection__rendered { 76 | padding-left: 10px; 77 | } 78 | -------------------------------------------------------------------------------- /tweaks/PageEdit/EditFieldLinks/EditFieldLinks.css: -------------------------------------------------------------------------------- 1 | .aos_hasTooltip .title, 2 | .InputfieldCheckbox .InputfieldContent > label { 3 | position: relative; 4 | } 5 | .aos_hasTooltip .title, 6 | .InputfieldCheckbox label { 7 | display: inline-block; 8 | } 9 | .aos_hasTooltip .title:hover .aos_EditField, 10 | .InputfieldCheckbox label:hover .aos_EditField { 11 | display: inline-block; 12 | visibility: visible; 13 | transform: scale(1); 14 | opacity: 1; 15 | transition: 0.07s all 1s; 16 | } 17 | .aos_hasTooltip .title .aos_EditField, 18 | .InputfieldCheckbox label .aos_EditField { 19 | font-style: normal; 20 | visibility: hidden; 21 | transform: scale(0); 22 | opacity: 0; 23 | position: absolute; 24 | left: 0; 25 | bottom: -10px; 26 | font-weight: normal !important; 27 | background: #1c2836; 28 | color: rgba(255, 255, 255, 0.84) !important; 29 | margin: 0 0 8px -4px; 30 | font-size: 13px; 31 | padding: 5px 10px 4px !important; 32 | line-height: 1.5; 33 | z-index: 110000; 34 | backface-visibility: hidden; 35 | transition: 0.2s opacity; 36 | white-space: nowrap; 37 | } 38 | .aos_hasTooltip .title .aos_EditField:hover, 39 | .InputfieldCheckbox label .aos_EditField:hover { 40 | transition-delay: 0s !important; 41 | background: #28394e !important; 42 | color: #fff !important; 43 | text-decoration: underline; 44 | } 45 | .aos_hasTooltip .title .aos_EditField:hover i, 46 | .InputfieldCheckbox label .aos_EditField:hover i { 47 | opacity: 1; 48 | } 49 | .aos_hasTooltip .title .aos_EditField:hover:before, 50 | .InputfieldCheckbox label .aos_EditField:hover:before { 51 | border-top-color: #28394e; 52 | } 53 | .aos_hasTooltip .title .aos_EditField i, 54 | .InputfieldCheckbox label .aos_EditField i { 55 | margin-left: 8px; 56 | font-size: 12px !important; 57 | opacity: 0.84; 58 | } 59 | .aos_hasTooltip .title .aos_EditField:before, 60 | .InputfieldCheckbox label .aos_EditField:before { 61 | content: ""; 62 | position: absolute; 63 | top: 100%; 64 | left: 10px; 65 | border: 6px solid transparent; 66 | border-top-color: #1c2836; 67 | } 68 | .aos_hasTooltip .title .aos_EditField:after, 69 | .InputfieldCheckbox label .aos_EditField:after { 70 | content: ""; 71 | height: 12px; 72 | background: transparent; 73 | width: 133%; 74 | display: block; 75 | position: absolute; 76 | top: 100%; 77 | left: 0; 78 | } 79 | .aos_hasTooltip .title .aos_EditField:hover, 80 | .InputfieldCheckbox label .aos_EditField:hover { 81 | cursor: pointer; 82 | } 83 | .aos_hasTooltip .InputfieldRepeaterItem:hover .InputfieldContent { 84 | overflow: visible !important; 85 | } 86 | -------------------------------------------------------------------------------- /classes/Tweak.php: -------------------------------------------------------------------------------- 1 | info = new WireData(); 46 | $this->info->setArray($this->info()); 47 | $this->key = $key; 48 | $this->id = wire()->sanitizer->pageNameUTF8($key); 49 | } 50 | 51 | public function info(): array 52 | { 53 | return []; 54 | } 55 | 56 | public function init(): void 57 | { 58 | } 59 | 60 | public function ready(): void 61 | { 62 | } 63 | 64 | 65 | public final function loadCSS(): void 66 | { 67 | $cssfile = substr($this->file, 0, -3) . "css"; 68 | $url = wire()->config->versionUrl($this->pathToUrl($cssfile)); 69 | wire()->config->styles->add($url); 70 | } 71 | 72 | public final function loadJS(): void 73 | { 74 | $jsfile = substr($this->file, 0, -3) . "js"; 75 | $url = wire()->config->versionUrl($this->pathToUrl($jsfile)); 76 | wire()->config->scripts->add($url); 77 | } 78 | 79 | /** 80 | * Convert path to url and optionally add cache busting string 81 | * @param mixed $path 82 | * @param bool $nocache 83 | * @return string 84 | */ 85 | public function pathToUrl($path, $nocache = false): string 86 | { 87 | $path = Paths::normalizeSeparators($path); 88 | $url = str_replace( 89 | wire()->config->paths->root, 90 | wire()->config->urls->root, 91 | $path 92 | ); 93 | if ($nocache) { 94 | try { 95 | return wire()->config->versionUrl($url); 96 | } catch (\Throwable $th) { 97 | $this->log($th->getMessage()); 98 | } 99 | } 100 | return $url; 101 | } 102 | 103 | public function __debugInfo() 104 | { 105 | return [ 106 | 'name' => $this->name, 107 | 'key' => $this->key, 108 | 'id' => $this->id, 109 | 'file' => $this->file, 110 | ]; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /tweaks/General/QuickWebAuthnLogin/QuickWebAuthnLogin.php: -------------------------------------------------------------------------------- 1 | 'Allow quick login as unique SuperUser, in debug mode, using just WebAuthn credentials', 29 | ]; 30 | } 31 | 32 | 33 | public function ready(): void 34 | { 35 | if ($this->wire->fields->get('tfa_type') === null) { 36 | return; // No 2FA set up 37 | } 38 | if (!$this->wire->config->debug) { 39 | return; // Not a debug mode site 40 | } 41 | 42 | $super_role_id = $this->wire->config->superUserRolePageID; 43 | $this->supers = $this->wire->users->find("roles=$super_role_id, tfa_type=TfaWebAuthn"); 44 | 45 | if (1 !== count($this->supers)) { 46 | return; // Not exactly 1 TfaWebAuthn superuser 47 | } 48 | 49 | $this->superuser = $this->supers->eq(0); 50 | 51 | if ('TfaWebAuthn' !== $this->superuser->hasTfa()) { 52 | return; // TfaWebAuthn Not fully configured for superuser 53 | } 54 | 55 | $this->wire->addHookAfter("ProcessLogin::loginFormProcessReady", $this, "fillLoginForm"); 56 | $this->wire->addHookAfter("Session::authenticate", $this, "overridePasswordAuthentication"); 57 | } 58 | 59 | 60 | protected function fillLoginForm(HookEvent $event) 61 | { 62 | $uname = $this->wire->input->post->login_name ?? ''; 63 | $upass = $this->wire->input->post->login_pass ?? ''; 64 | if ('' === $uname && '' === $upass) { 65 | $this->wire->input->post->login_name = $this->superuser->name; 66 | $this->wire->input->post->login_pass = 'dummy_password'; // Not empty so PW to processes it 67 | } 68 | } 69 | 70 | 71 | protected function overridePasswordAuthentication(HookEvent $event) 72 | { 73 | $user = $event->arguments(0); 74 | if ($user->id === $this->superuser->id && 'TfaWebAuthn' === $user->hasTfa()) { 75 | // Override earlier failed password authentication for this user 76 | // WebAuthn 2FA will kick in now, just as if the password was entered correctly. 77 | // So we only need to press our YubiKey button or use our face/fingerprint etc. 78 | $event->return = true; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /tweaks/Inputfields/ColumnBreak/ColumnBreak.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | 3 | if (window.Split && $('.aos_col_left ~ .aos_col_right').length) { 4 | 5 | var storageName = $('.aos_col_right').attr('data-splitter-storagekey'), 6 | defaultLeft = parseFloat($('.aos_col_left').attr('data-splitter-default')), 7 | defaultRight = parseFloat($('.aos_col_right').attr('data-splitter-default')), 8 | sizes = localStorage.getItem(storageName) || [defaultLeft, defaultRight]; 9 | 10 | var aos_splitter = Split(['.aos_col_left', '.aos_col_right'], { 11 | sizes: typeof sizes === 'string' ? JSON.parse(sizes) : sizes, 12 | gutterSize: 20, 13 | minSize: 250, 14 | onDragEnd: function () { 15 | localStorage.setItem(storageName, JSON.stringify(aos_splitter.getSizes())); 16 | setSplitterHeight(); 17 | } 18 | }); 19 | } 20 | 21 | function setSplitterHeight() { 22 | // set height to 0 before checking parent height 23 | !$('.gutter').length || $('.gutter').css('height', 0).css('height', $('.gutter').parent().outerHeight()); 24 | } 25 | 26 | $(window).on('load', function () { 27 | setTimeout(function () { 28 | setSplitterHeight(); 29 | }, 2000); 30 | }); 31 | 32 | // restore default splitter position on double-click on splitter 33 | $(document).on('dblclick', '.aos_col_left + .gutter', function (e) { 34 | if (!aos_splitter) return true; 35 | aos_splitter.setSizes([defaultLeft, defaultRight]); 36 | localStorage.removeItem(storageName); 37 | }); 38 | 39 | // recalculate splitter height on window resize 40 | $(window).on('resize', function () { 41 | setSplitterHeight(); 42 | }); 43 | 44 | 45 | // check for AdminColumns in tabs 46 | if ($('#ProcessPageEdit li[data-column-break]').length) { 47 | 48 | $(document).on('wiretabclick', function (e, elem) { 49 | 50 | var tabName = elem.attr('id').replace('Inputfield_', ''), 51 | tabSelector = '#Inputfield_' + tabName, 52 | tabColumnBreaks = $('#ProcessPageEdit li[data-column-break]').attr('data-column-break'); 53 | 54 | if ($(tabSelector).hasClass('aos-columns-ready')) return false; 55 | 56 | if (tabColumnBreaks) tabColumnBreaks = JSON.parse(tabColumnBreaks); 57 | 58 | if (tabColumnBreaks[tabName]) { 59 | 60 | if (!tabColumnBreaks[tabName][0]) return false; 61 | 62 | var breakField = $('#wrap_Inputfield_' + tabColumnBreaks[tabName][0]), 63 | colWidth = tabColumnBreaks[tabName][1] ? tabColumnBreaks[tabName][1] : 67; 64 | 65 | if (!breakField.length) return false; 66 | 67 | var aosColBreakIndex = breakField.index() + 1; 68 | 69 | $(tabSelector + ' > .Inputfields > li:lt(' + aosColBreakIndex + ')').wrapAll('
    • '); 70 | $(tabSelector + ' > .Inputfields > .aos_col_left ~ li').wrapAll('
      • '); 71 | 72 | $(tabSelector).addClass('aos-columns-ready'); 73 | } 74 | }); 75 | } 76 | }); 77 | -------------------------------------------------------------------------------- /tweaks/Inputfields/AsmSearchBox/AsmSearchBox.js: -------------------------------------------------------------------------------- 1 | function initAsmSelectBox(inputfield_id) { 2 | var $asmSelect = $('#wrap_' + inputfield_id + ' select.asmSelect'), 3 | placeholder; 4 | 5 | if (!$asmSelect.length) { 6 | window.requestAnimationFrame(function () { 7 | initAsmSelectBox(inputfield_id); 8 | }); 9 | return false; 10 | } 11 | 12 | // add data-asm-placeholder for existing placeholder 13 | var asmSelect2Config = {}, 14 | $placeholderOption = $asmSelect.find('option[selected]:not([value])'); 15 | 16 | if ($placeholderOption.length) { 17 | placeholder = $placeholderOption.text(); 18 | asmSelect2Config.placeholder = placeholder; 19 | $asmSelect.attr('data-asm-placeholder', placeholder); 20 | $placeholderOption.empty(); // placeholder in select2.js needs an empty option 21 | } 22 | 23 | $asmSelect.select2(asmSelect2Config); 24 | } 25 | 26 | $(document).ready(function () { 27 | 28 | var select2Config = {}/*, 29 | keepAsmSearchTerm = AsmTweaksSettings.indexOf('asmSearchBoxKeepTerm') !== -1;*/ 30 | 31 | $(document).on('change', '.asmSelect ~ select', function () { 32 | 33 | var src = event && (event.target || event.srcElement); 34 | 35 | // asmSelect remove icon click 36 | if (src && src.tagName === 'I') { 37 | var $asmSelect = $(this).parents('.asmContainer').first().find('.asmSelect'); 38 | $asmSelect.select2('destroy'); 39 | restoreAsmSelectBoxPlaceholder($asmSelect, select2Config); 40 | $asmSelect.select2(select2Config); 41 | } 42 | }); 43 | 44 | 45 | // save scroll position 46 | $(document).on('select2:selecting', '.asmSelect', function () { 47 | $(this).attr('data-scroll-position', $('.select2-results__options').scrollTop()); 48 | }); 49 | 50 | 51 | $(document).on('select2:select', '.asmSelect', function (event) { 52 | 53 | var $asmSelect = $(this), 54 | src = event.target || event.srcElement, 55 | inputSelector = '.select2-search__field', 56 | searchTermAttr = 'data-select2-search-term', 57 | searchTerm = $(inputSelector).val()/*, 58 | keepListOpen = AsmTweaksSettings.indexOf('asmSearchBoxKeepListOpen') !== -1*/; 59 | 60 | // select an item in select2 dropdown 61 | if (src.tagName === 'SELECT') { 62 | 63 | // save search term in parent's data attr 64 | if (keepAsmSearchTerm) { 65 | $asmSelect.parent().attr(searchTermAttr, searchTerm); 66 | } 67 | 68 | $asmSelect.select2('destroy'); 69 | restoreAsmSelectBoxPlaceholder($asmSelect, select2Config); 70 | $asmSelect.select2(select2Config); 71 | 72 | if (!keepListOpen) { 73 | return false; 74 | } 75 | 76 | $asmSelect.select2('open'); 77 | 78 | // restore previous search term 79 | if (keepAsmSearchTerm) { 80 | var $input = $(inputSelector); 81 | $input.val($asmSelect.parent().attr(searchTermAttr)); 82 | $input.trigger('keyup'); 83 | if ($input.val && $input.setSelectionRange) { 84 | var len = $input.value.length * 2; 85 | $input.setSelectionRange(len, len); 86 | } 87 | } 88 | 89 | // restore scroll position 90 | $(".select2-results__options").scrollTop($asmSelect.attr('data-scroll-position')); 91 | } 92 | }); 93 | }); 94 | -------------------------------------------------------------------------------- /tweaks/PageEdit/PrevNextPage/PrevNextPage.php: -------------------------------------------------------------------------------- 1 | "Add buttons/options to edit prev/next page", 15 | ]; 16 | } 17 | 18 | 19 | public function ready(): void 20 | { 21 | if ($this->wire()->config->ajax) { 22 | return; 23 | } 24 | 25 | $this->editedPage = false; 26 | $editedPageId = $this->wire('sanitizer')->int($this->wire('input')->get->id); 27 | $editedPage = $this->wire('pages')->get($editedPageId); 28 | 29 | if ($editedPage->id && !($editedPage instanceof RepeaterPage)) { 30 | $this->editedPage = $editedPage; 31 | } 32 | 33 | if ( 34 | in_array($this->wire('page')->process, ['ProcessPageEdit', 'ProcessUser', 'ProcessRole']) 35 | && $this->wire('input')->id 36 | && $this->editedPage 37 | ) { 38 | // sort precedence: template level - page level - "sort" 39 | $sortfield = 'sort'; 40 | $parent = $this->editedPage->parent(); 41 | 42 | if ($parent->id) { 43 | $sortfield = $parent->template->sortfield ?: $parent->sortfield; 44 | } 45 | 46 | $p404_id = $this->wire('config')->http404PageID; 47 | $baseSelector = "include=all, template!=admin, id!=$p404_id, parent=$parent"; 48 | $prevnextlinks = array(); 49 | $isFirst = false; 50 | $isLast = false; 51 | $numSiblings = $parent->numChildren(true); 52 | 53 | if ($numSiblings > 1) { 54 | $selector = $baseSelector . ', sort=' . $sortfield; 55 | 56 | if (strpos($sortfield, '-') === 0) { 57 | $sortfieldReversed = ltrim($sortfield, '-'); 58 | } else { 59 | $sortfieldReversed = '-' . $sortfield; 60 | } 61 | 62 | $next = $this->editedPage->next($selector); 63 | $prev = $this->editedPage->prev($selector); 64 | 65 | if (!$next->id) { 66 | $next = $this->editedPage->siblings($selector . ', limit=1')->first(); 67 | $isFirst = true; 68 | } 69 | 70 | if (!$prev->id) { 71 | $prev = $this->editedPage->siblings("$baseSelector, limit=1, sort=" . $sortfieldReversed)->first(); 72 | $isLast = true; 73 | } 74 | 75 | $edit_next_text = $isFirst ? ' ' . $this->_('Edit first:') : $this->_('Edit next:'); 76 | $edit_prev_text = $isLast ? ' ' . $this->_('Edit last:') : $this->_('Edit previous:'); 77 | 78 | if ($prev && $prev->id && $prev->editable()) { 79 | $prevnextlinks['prev'] = array( 80 | 'title' => $edit_prev_text . ' ' . ($prev->title ? $prev->title : $prev->name), 81 | 'url' => $prev->editUrl, 82 | ); 83 | } 84 | 85 | if ($next && $next->id && $next->editable()) { 86 | $prevnextlinks['next'] = array( 87 | 'title' => $edit_next_text . ' ' . ($next->title ? $next->title : $next->name), 88 | 'url' => $next->editUrl, 89 | ); 90 | } 91 | 92 | if (!empty($prevnextlinks)) { 93 | $this->wire('config')->js('AOS_prevnextlinks', $prevnextlinks); 94 | $this->loadJS(); 95 | $this->loadCSS(); 96 | } 97 | } 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /tweaks/PageEdit/EditFieldLinks/EditFieldLinks.php: -------------------------------------------------------------------------------- 1 | 'Field edit links in PageEdit (on hover)', 17 | ]; 18 | } 19 | 20 | public function ready(): void 21 | { 22 | 23 | if ($this->wire('user')->isSuperuser()) { 24 | 25 | $editedPageId = $this->wire('sanitizer')->int($this->wire('input')->get->id); 26 | $editedPage = $this->wire('pages')->get($editedPageId); 27 | 28 | if ($editedPage->id && !($editedPage instanceof RepeaterPage)) { 29 | $this->editedPage = $editedPage; 30 | } 31 | 32 | if ($this->editedPage) { 33 | 34 | $this->addHookAfter('Inputfield::render', $this, 'addFieldEditLinks'); 35 | $this->addHookAfter('Inputfield::renderValue', $this, 'addFieldEditLinks'); 36 | 37 | $this->loadJS(); 38 | $this->loadCSS(); 39 | 40 | } 41 | } 42 | 43 | } 44 | 45 | public function addFieldEditLinks($event) 46 | { 47 | $inputfield = $event->object; 48 | 49 | if ($inputfield->type === 'hidden') { 50 | return; 51 | } 52 | 53 | $markup = $event->return; 54 | 55 | if (strpos($markup, 'data-editurl')) { 56 | return; 57 | } 58 | 59 | if ($field = $inputfield->hasField) { 60 | 61 | if (!is_object($field)) { 62 | return; 63 | } 64 | 65 | if ($field->flags && $field->hasFlag(\ProcessWire\Field::flagSystem) && $field->name !== 'title') { 66 | return; 67 | } 68 | 69 | 70 | // add class to wrapper to be able to use :hover even if label is unavailable (eg. checkbox field) 71 | $inputfield->wrapAttr('class', $inputfield->wrapAttr('class') . ' aos_hasTooltip'); 72 | 73 | $editFieldUrl = $this->wire('config')->urls->admin . 'setup/field/edit?id=' . $field->id; 74 | 75 | $editFieldTooltip = '' . $field->name . ''; 76 | 77 | // need to allow HTML in label 78 | $inputfield->entityEncodeLabel = false; 79 | $inputfield->label = '' . $editFieldTooltip . $inputfield->label . ''; 80 | 81 | // add tooltip if there's no label (checkbox) 82 | if ($inputfield instanceof InputfieldCheckbox) { 83 | $markup = str_replace('', $editFieldTooltip . '', $markup); 84 | } 85 | 86 | // use hidden link to be able to use modal/panel 87 | // note: link is not added to the label tag because it won't be clickable 88 | 89 | $link = ''; 90 | 91 | // for multi-select page reference fields $link was added twice (#96) 92 | // for repeaters $markup contains all included fields' $links (#101) 93 | if (strpos($markup, 'aos_EditFieldLink') === false || $inputfield instanceof InputfieldRepeater) { 94 | $target = isset(self::$configData['FieldAndTemplateEditLinks']) ? self::$configData['FieldAndTemplateEditLinks'] : ''; 95 | $target = ($target === 'pw-panel') ? $target . ' pw-panel-reload' : $target; 96 | 97 | $link = 'Edit'; 98 | } 99 | 100 | $event->return = $markup . $link; 101 | 102 | } 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /tweaks/Inputfields/ColumnBreak/split.js/split.min.js: -------------------------------------------------------------------------------- 1 | /*! Split.js - v1.2.0 */ 2 | "use strict";(function(){var a=this,b=a.attachEvent&&!a[d],c=a.document,d="addEventListener",e="removeEventListener",f="getBoundingClientRect",g=.5,h=function(){for(var a,b=["","-webkit-","-moz-","-o-"],d=0;d=this.size-(this.bMin+k.snapOffset+this.bGutterSize)&&(b=this.size-(this.bMin+this.bGutterSize)),b-=g,y.call(this,b),k.onDrag&&k.onDrag())},x=function(){var b=a.getComputedStyle(this.parent),c=this.parent[n]-parseFloat(b[r])-parseFloat(b[s]);this.size=this.a[f]()[l]+this.b[f]()[l]+this.aGutterSize+this.bGutterSize,this.percentage=Math.min(this.size/c*100,100),this.start=this.a[f]()[p]},y=function(a){z(this.a,a/this.size*this.percentage,this.aGutterSize),z(this.b,this.percentage-a/this.size*this.percentage,this.bGutterSize)},z=function(a,b,c){for(var d=k.elementStyle(l,b,c),e=Object.keys(d),f=0;f0&&(F={a:i(j[m-1]),b:H,aMin:k.minSize[m-1],bMin:k.minSize[m],dragging:!1,parent:C,isFirst:I,isLast:J,direction:k.direction},F.aGutterSize=k.gutterSize,F.bGutterSize=k.gutterSize,I&&(F.aGutterSize=k.gutterSize/2),J&&(F.bGutterSize=k.gutterSize/2),"row-reverse"!==M&&"column-reverse"!==M||(G=F.a,F.a=F.b,F.b=G)),!b){if(m>0){var N=c.createElement("div");N.className=q,A(N,L),N[d]("mousedown",u.bind(F)),N[d]("touchstart",u.bind(F)),C.insertBefore(N,H),F.gutter=N}0!==m&&m!=j.length-1||(L=k.gutterSize/2)}if(z(H,K,L),m>0){var O=F.a[f]()[l],P=F.b[f]()[l];O0&&t.push(F)}return{setSizes:function(a){for(var b=0;b0){var c=t[b-1];z(c.a,a[b-1],c.aGutterSize),z(c.b,a[b],c.bGutterSize)}},getSizes:function(){for(var b=[],c=0;c "Add buttons/options, to Page list actions and page edit tab, to bypass trash for SuperUsers", 19 | ]; 20 | } 21 | 22 | 23 | public function ready(): void 24 | { 25 | if (!$this->wire->user->isSuperuser()) { 26 | return; 27 | } 28 | 29 | // Translatable strings 30 | $this->strings = new \StdClass(); 31 | $this->strings->cancel = $this->_("Cancel Deletion"); 32 | $this->strings->confirm = $this->_("Delete Permanently"); 33 | $this->strings->skip_trash = $this->_('Skip Trash?'); 34 | $this->strings->desc = $this->_('Check to permanently delete this page.'); 35 | $this->strings->deleted = $this->_('Deleted page: %s'); 36 | 37 | $this->addHookAfter('ProcessPageListActions::getExtraActions', $this, 'addDeleteButton'); 38 | $this->addHookAfter('ProcessPageListActions::processAction', $this, 'addDeleteButtonAction'); 39 | 40 | // add delete field to page edit Delete tab 41 | $this->addHookAfter('ProcessPageEdit::buildFormDelete', $this, 'addDeletePermanentlyField'); 42 | $this->addHookBefore('Pages::trash', $this, 'addDeletePermanentlyHook'); 43 | 44 | $this->wire->addHookBefore("ProcessPageList::execute", function() { 45 | $str_cancel = $this->strings->cancel; 46 | $str_confirm = $this->strings->confirm; 47 | $this->wire('config')->js('AOS_BypassTrash', compact('str_cancel', 'str_confirm')); 48 | $this->loadCSS(); 49 | $this->loadJS(); 50 | }); 51 | 52 | $this->editedPage = false; 53 | $editedPageId = $this->wire('sanitizer')->int($this->wire('input')->get->id); 54 | $editedPage = $this->wire('pages')->get($editedPageId); 55 | 56 | if ($editedPage->id && !($editedPage instanceof RepeaterPage)) { 57 | $this->editedPage = $editedPage; 58 | } 59 | } 60 | 61 | 62 | /** 63 | * Add Delete button to pagelist 64 | */ 65 | public function addDeleteButton(HookEvent $event) 66 | { 67 | $page = $event->arguments('page'); 68 | 69 | if (!$this->wire('user')->isSuperuser()) { 70 | return false; 71 | } 72 | 73 | // do not allow for pages having children 74 | if ($page->numChildren > 0) { 75 | return false; 76 | } 77 | 78 | // not trashable and not in Trash 79 | if (!$page->trashable() && !$page->isTrash()) { 80 | return false; 81 | } 82 | 83 | $actions = array(); 84 | $adminUrl = $this->wire('config')->urls->admin . 'page/'; 85 | $icon = ''; 86 | $actions['delete'] = array( 87 | 'cn' => 'Delete aos-pagelist-confirm', 88 | 'name' => $icon . 'Delete', 89 | 'url' => $adminUrl . '?action=delete&id=' . $page->id, 90 | 'ajax' => true, 91 | ); 92 | 93 | $event->return += $actions; 94 | } 95 | 96 | 97 | /** 98 | * Process action for addDeleteButton. 99 | * 100 | * @return bool 101 | */ 102 | public function addDeleteButtonAction(HookEvent $event) 103 | { 104 | $page = $event->arguments(0); 105 | $action = $event->arguments(1); 106 | // do not allow for pages having children 107 | if ($page->numChildren > 0) { 108 | return false; 109 | } 110 | 111 | if ($action == 'delete') { 112 | $page->delete(); 113 | $event->return = array( 114 | 'action' => $action, 115 | 'success' => true, 116 | 'page' => $page->id, 117 | 'updateItem' => $page->id, 118 | 'message' => 'Page deleted.', 119 | 'remove' => true, 120 | 'refreshChildren' => false, 121 | ); 122 | } 123 | } 124 | 125 | 126 | public function addDeletePermanentlyField(HookEvent $event) 127 | { 128 | if ($this->editedPage && !$this->editedPage->trashable()) { 129 | return false; 130 | } 131 | 132 | $form = $event->return; 133 | 134 | $trashConfirmField = $form->get('delete_page'); 135 | if (!$trashConfirmField) { 136 | return false; 137 | } 138 | 139 | $f = $this->wire('modules')->get('InputfieldCheckbox'); 140 | $f->attr('id+name', 'delete_permanently'); 141 | $f->checkboxLabel = $this->strings->confirm; 142 | $f->label = $this->strings->skip_trash; 143 | $f->description = $this->strings->desc; 144 | $f->value = '1'; 145 | 146 | $trashConfirmField->columnWidth = 50; 147 | $f->columnWidth = 50; 148 | 149 | $f->collapsed = Inputfield::collapsedNever; 150 | $trashConfirmField->collapsed = Inputfield::collapsedNever; 151 | 152 | // add fieldset (Reno top spacing bug) 153 | if ($this->adminTheme === 'AdminThemeReno') { 154 | $fset = $this->wire('modules')->get('InputfieldFieldset'); 155 | $fset->add($trashConfirmField); 156 | $fset->add($f); 157 | $form->remove($trashConfirmField); 158 | $form->insertBefore($fset, $form->get('submit_delete')); 159 | } else { 160 | $form->insertAfter($f, $trashConfirmField); 161 | } 162 | } 163 | 164 | 165 | // delete page instead trashing if delete_permanently was checked 166 | public function addDeletePermanentlyHook(HookEvent $event) 167 | { 168 | if (isset($this->wire('input')->post->delete_permanently)) { 169 | $p = $event->arguments[0]; 170 | $session = $this->wire('session'); 171 | $afterDeleteRedirect = $this->wire('config')->urls->admin . "page/?open={$p->parent->id}"; 172 | if ($p->deleteable()) { 173 | $session->message(sprintf($this->strings->deleted, $p->url)); // Page deleted message 174 | $this->wire('pages')->delete($p, true); 175 | $session->redirect($afterDeleteRedirect); 176 | } 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /tweaks/Inputfields/ColumnBreak/ColumnBreak.php: -------------------------------------------------------------------------------- 1 | 'Add aos_column_break field to create admin columns (compatible with AOS version)', 17 | ]; 18 | } 19 | 20 | public function ready(): void 21 | { 22 | // use skipLabel and collapsed to avoid visiblity if tweak is uninstalled (no need to remove from templates) 23 | if (!$this->wire()->fields->get('aos_column_break')) { 24 | 25 | $field = new \ProcessWire\Field(); 26 | $field->type = $this->wire('modules')->get('FieldtypeText'); 27 | $field->name = 'aos_column_break'; 28 | $field->label = ''; 29 | $field->skipLabel = true; 30 | $field->collapsed = \ProcessWire\Inputfield::collapsedYesLocked; 31 | $field->tags = '-aos'; 32 | $field->save(); 33 | 34 | $this->message(\ProcessWire\__('Installed field "aos_column_break".', __FILE__)); 35 | } 36 | 37 | $this->wire('config')->scripts->add($this->pathToUrl(__DIR__ . '/split.js/split.min.js')); 38 | 39 | $editedPageId = $this->wire('sanitizer')->int($this->wire('input')->get->id); 40 | $editedPage = $this->wire('pages')->get($editedPageId); 41 | 42 | if ($editedPage->id && !($editedPage instanceof RepeaterPage)) { 43 | $this->editedPage = $editedPage; 44 | } 45 | 46 | $this->addHookAfter('ProcessPageEdit::buildFormContent', $this, 'setupAdminColumns'); 47 | 48 | $this->loadCSS(); 49 | $this->loadJS(); 50 | } 51 | 52 | public function setupAdminColumns($event) 53 | { 54 | $form = $event->return; 55 | $fields = $form->children(); 56 | $colBreakField = $fields->get('aos_column_break'); 57 | $colWidths = array(67, 33); 58 | $tabOpenFields = $fields->find('hasFieldtype=FieldtypeFieldsetTabOpen'); 59 | 60 | if ($tabOpenFields->count()) { 61 | $this->setupAdminColumnsTabs($tabOpenFields, $form); 62 | } 63 | 64 | if (!$colBreakField) { 65 | return false; 66 | } 67 | 68 | // stop if colBreakField is inside a tab 69 | $tabSeen = false; 70 | 71 | foreach ($fields as $field) { 72 | 73 | if ($field->hasFieldtype == 'FieldtypeFieldsetTabOpen') { 74 | $tabSeen = true; 75 | } 76 | 77 | if ($field->name == $colBreakField->name) { 78 | 79 | if ($tabSeen) { 80 | // there was a TabOpen field first, remove colBreakField and stop 81 | $form->remove($colBreakField); 82 | 83 | return false; 84 | 85 | } else { 86 | // colBreakField is not inside a tab 87 | break; 88 | } 89 | } 90 | } 91 | 92 | if ($colBreakField->columnWidth) { 93 | $colWidths = array($colBreakField->columnWidth, 100 - $colBreakField->columnWidth); 94 | } 95 | 96 | $fsetLeft = $this->wire('modules')->get('InputfieldFieldset'); 97 | $fsetLeft->attr('class', $fsetLeft->attr('class') . ' aos_col_left aos_no-inputfield-padding'); 98 | $fsetLeft->set('themeBorder', 'none'); 99 | $fsetLeft->set('themeOffset', false); 100 | $fsetLeft->wrapAttr('style', 'width: ' . $colWidths[0] . '%'); 101 | $fsetLeft->wrapAttr('data-splitter-default', $colWidths[0]); 102 | 103 | $fsetRight = $this->wire('modules')->get('InputfieldFieldset'); 104 | $fsetRight->set('themeBorder', 'none'); 105 | $fsetRight->set('themeOffset', false); 106 | $fsetRight->attr('class', $fsetRight->attr('class') . ' aos_col_right aos_no-inputfield-padding'); 107 | $fsetRight->wrapAttr('style', 'width: ' . $colWidths[1] . '%'); 108 | $fsetRight->wrapAttr('data-splitter-default', $colWidths[1]); 109 | 110 | // add template name and user id for Split.js 111 | $fsetRight->wrapAttr('data-splitter-storagekey', 112 | 'splitter_' . $this->editedPage->template->name . '_' . $this->wire('user')->id); 113 | 114 | $this->wire('modules')->get('FieldtypeFieldsetClose'); 115 | $fsetLeftEnd = new \ProcessWire\InputfieldFieldsetClose; 116 | $fsetRightEnd = new \ProcessWire\InputfieldFieldsetClose; 117 | 118 | $fsetLeftEnd->name = 'aos_col_left' . \ProcessWire\FieldtypeFieldsetOpen::fieldsetCloseIdentifier; 119 | $fsetRightEnd->name = 'aos_col_right' . \ProcessWire\FieldtypeFieldsetOpen::fieldsetCloseIdentifier; 120 | 121 | $fset = $fsetLeft; 122 | $rightItems = false; 123 | 124 | foreach ($fields as $f) { 125 | 126 | // stop on first Tab field 127 | if ($f->hasFieldtype == 'FieldtypeFieldsetTabOpen') { 128 | break; 129 | } 130 | 131 | // if colBreakField reached, remove it and start adding fields to the right column 132 | if (!$rightItems && $f == $colBreakField) { 133 | $form->remove($colBreakField); 134 | $fset = $fsetRight; 135 | $rightItems = true; 136 | continue; 137 | } 138 | 139 | $fset->add($form->get($f->name)); 140 | $form->remove($form->get($f->name)); 141 | } 142 | 143 | $form->add($fsetLeft); 144 | $form->add($fsetLeftEnd); 145 | 146 | $form->add($fsetRight); 147 | $form->add($fsetRightEnd); 148 | } 149 | 150 | public function setupAdminColumnsTabs($fields, $form) 151 | { 152 | $dataColumnBreaks = array(); 153 | 154 | foreach ($fields as $f) { 155 | 156 | // add data-attributes fo JS 157 | $notes = $f->notes; 158 | 159 | if (empty($notes)) { 160 | // try default notes (PW bug with overrides?) 161 | $notes = $this->fields->get($f->name)->notes; 162 | } 163 | 164 | if (!empty($notes)) { 165 | $notes = trim($notes); 166 | 167 | if (strpos($notes, 'colbreak_') !== 0) { 168 | return; 169 | } 170 | 171 | $notes = str_replace('colbreak_', '', $notes); 172 | 173 | if (strpos($notes, ':') !== false) { 174 | $notes = array_map('trim', explode(':', $notes)); 175 | } else { 176 | $notes = array($notes, 67); 177 | } 178 | $dataColumnBreaks[$f->name] = $notes; 179 | } 180 | } 181 | 182 | if (!empty($dataColumnBreaks)) { 183 | $form->wrapAttr('data-column-break', json_encode($dataColumnBreaks)); 184 | } 185 | } 186 | 187 | } 188 | -------------------------------------------------------------------------------- /RockAdminTweaks.module.php: -------------------------------------------------------------------------------- 1 | tweaks = new WireArray(); 28 | $this->wire->classLoader->addNamespace("RockAdminTweaks", __DIR__ . "/classes"); 29 | $this->tweakPathTemplates = $this->wire->config->paths->templates . $this->className . "/"; 30 | $this->tweakPathModules = __DIR__ . "/tweaks/"; 31 | $this->loadTweakArray(); 32 | $this->loadEnabledTweaks(); 33 | } 34 | 35 | public function ready(): void 36 | { 37 | foreach ($this->tweaks as $tweak) $tweak->ready(); 38 | } 39 | 40 | private function loadEnabledTweaks(): void 41 | { 42 | $this->enabledTweaks = $this->wire->modules->getConfig($this, 'enabledTweaks') ?: []; 43 | foreach ($this->enabledTweaks as $key) { 44 | $tweak = $this->loadTweak($key); 45 | if (!$tweak) continue; 46 | $this->tweaks->add($tweak); 47 | $tweak->init(); 48 | } 49 | } 50 | 51 | private function loadTweak($key) 52 | { 53 | if (!array_key_exists($key, $this->tweakArray)) return; 54 | $file = $this->tweakArray[$key]; 55 | if (!is_file($file)) return; 56 | require_once $file; 57 | try { 58 | $parts = explode(":", $key); 59 | $tweakName = $parts[1]; 60 | $class = "\\RockAdminTweaks\\$tweakName"; 61 | $tweak = new $class($key); 62 | $tweak->file = $file; 63 | $tweak->name = $tweakName; 64 | return $tweak; 65 | } catch (\Throwable $th) { 66 | $this->error($th->getMessage()); 67 | } 68 | } 69 | 70 | private function loadTweakArray(): void 71 | { 72 | $arr = []; 73 | foreach ( 74 | [ 75 | $this->tweakPathModules, 76 | $this->tweakPathTemplates, 77 | ] as $dir 78 | ) { 79 | $files = $this->wire->files->find($dir, [ 80 | 'extensions' => ['php'], 81 | ]); 82 | foreach ($files as $file) { 83 | $name = substr(basename($file), 0, -4); 84 | $folder = basename(dirname(dirname($file))); 85 | $arr["$folder:$name"] = $file; 86 | } 87 | } 88 | ksort($arr); 89 | $this->tweakArray = $arr; 90 | } 91 | 92 | /* ##### module methods ##### */ 93 | 94 | /** 95 | * Config inputfields 96 | * @param InputfieldWrapper $inputfields 97 | */ 98 | public function getModuleConfigInputfields($inputfields) 99 | { 100 | $this->moduleConfigAdd($inputfields); 101 | $this->showEnabledTweaks($inputfields); 102 | $this->moduleConfigTweaks($inputfields); 103 | return $inputfields; 104 | } 105 | 106 | public function isEnabled($key): bool 107 | { 108 | return in_array($key, $this->enabledTweaks); 109 | } 110 | 111 | private function moduleConfigAdd(&$inputfields): void 112 | { 113 | $path = $this->tweakPathTemplates; 114 | 115 | $fs = new InputfieldFieldset(); 116 | $fs->label = 'Create a new Tweak'; 117 | $fs->icon = 'plus'; 118 | $fs->collapsed = Inputfield::collapsedYes; 119 | $fs->notes = "The tweak will be created in $path"; 120 | if (!is_writable($path)) $fs->notes .= "\nWARNING: Folder is not writable or does not exist!"; 121 | $inputfields->add($fs); 122 | 123 | if ($this->wire->config->debug) { 124 | $fs->add([ 125 | 'type' => 'text', 126 | 'name' => 'tgroup', 127 | 'label' => 'Group / Folder', 128 | 'columnWidth' => 50, 129 | ]); 130 | $fs->add([ 131 | 'type' => 'text', 132 | 'name' => 'tname', 133 | 'label' => 'Name', 134 | 'columnWidth' => 50, 135 | ]); 136 | } else { 137 | $fs->add([ 138 | 'type' => 'markup', 139 | 'value' => 'This is only allowed if $config->debug = true;', 140 | ]); 141 | } 142 | 143 | // create tweak 144 | $tgroup = ucfirst((string)$this->wire->input->post->tgroup); 145 | $tname = ucfirst((string)$this->wire->input->post->tname); 146 | if ($tgroup && $tname) { 147 | $path = $this->tweakPathTemplates . "$tgroup/$tname"; 148 | $newFile = "$path/$tname.php"; 149 | if (is_file($newFile)) { 150 | $this->error("$newFile already exists"); 151 | } else { 152 | $this->wire->files->mkdir($path, true); 153 | $content = $this->wire->files->fileGetContents(__DIR__ . "/tweak.txt"); 154 | $content = str_replace('{name}', $tname, $content); 155 | $this->wire->files->filePutContents($newFile, $content); 156 | $this->message("Created tweak at $newFile"); 157 | } 158 | } 159 | } 160 | 161 | private function moduleConfigTweaks(&$inputfields): void 162 | { 163 | // save enabled tweaks to cache 164 | if ($this->wire->input->post->submit_save_module) { 165 | $enabledTweaks = $this->wire->input->post->tweaks; 166 | $this->wire->modules->saveConfig($this, ['enabledTweaks' => $enabledTweaks]); 167 | } 168 | 169 | $fs = new InputfieldFieldset(); 170 | $fs->name = 'tweaks'; 171 | $fs->label = 'Tweaks'; 172 | $fs->icon = 'magic'; 173 | $fs->prependMarkup = ''; 174 | $inputfields->add($fs); 175 | 176 | $oldFolder = false; 177 | foreach ($this->tweakArray as $key => $path) { 178 | $parts = explode(":", $key); 179 | $folder = $parts[0]; 180 | $tweakName = $parts[1]; 181 | 182 | // create new folder-field 183 | if ($oldFolder !== $folder) { 184 | $f = new InputfieldCheckboxes(); 185 | $f->name = 'tweaks'; 186 | $f->label = $folder; 187 | $f->icon = 'folder-open-o'; 188 | $f->entityEncodeText = false; 189 | $fs->add($f); 190 | } 191 | 192 | // load tweak from file 193 | $tweak = $this->loadTweak($key); 194 | $info = $tweak->info; 195 | $desc = $info->description; 196 | if ($info->help) { 197 | $help = wire()->sanitizer->entitiesMarkdown($info->help, true); 198 | $by = $info->author ? "by {$info->author}" : ''; 199 | $desc .= "id} uk-toggle title='Full description' uk-tooltip>" 200 | . "" 201 | . "" 202 | . ""; 210 | } 211 | if ($info->author) { 212 | $desc .= "" 213 | . "" 214 | . ""; 215 | } 216 | if ($info->maintainer) { 217 | $desc .= "" 218 | . "" 219 | . ""; 220 | } 221 | if ($info->infoLink) { 222 | $desc .= "" 223 | . '' 224 | . ''; 225 | } 226 | 227 | // debug 228 | // bd($tweak); 229 | 230 | // add option as checkbox 231 | $f->addOption($key, "$tweakName - $desc", [ 232 | 'checked' => $this->isEnabled($key) ? 'checked' : '', 233 | ]); 234 | 235 | $oldFolder = $folder; 236 | } 237 | } 238 | 239 | private function showEnabledTweaks($inputfields): void 240 | { 241 | $lines = []; 242 | $lines[] = "rockmigrations()->setModuleConfig('RockAdminTweaks', ["; 243 | $lines[] = " 'enabledTweaks' => ["; 244 | foreach ($this->enabledTweaks as $tweak) { 245 | $lines[] = " '$tweak',"; 246 | } 247 | $lines[] = " ],"; 248 | $lines[] = "]);"; 249 | $markup = "
        " . implode("\n", $lines) . "
        "; 250 | $inputfields->add([ 251 | 'type' => 'markup', 252 | 'label' => 'RockMigrations Code', 253 | 'value' => $markup, 254 | 'collapsed' => Inputfield::collapsedYes, 255 | 'icon' => 'code', 256 | 'description' => 'If you have multiple environments you can use RockMigrations to enable/disable tweaks identically and automatically across all environments:', 257 | ]); 258 | } 259 | } 260 | -------------------------------------------------------------------------------- /tweaks/Inputfields/AsmSearchBox/select2/css/select2.min.css: -------------------------------------------------------------------------------- 1 | .select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;height:1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important;white-space:nowrap !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right;margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb} 2 | -------------------------------------------------------------------------------- /tweaks/Inputfields/AsmSearchBox/select2/js/select2.min.js: -------------------------------------------------------------------------------- 1 | !function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof module&&module.exports?module.exports=function(t,n){return void 0===n&&(n="undefined"!=typeof window?require("jquery"):require("jquery")(t)),e(n),n}:e(jQuery)}(function(e){var t=function(){if(e&&e.fn&&e.fn.select2&&e.fn.select2.amd)var t=e.fn.select2.amd;var t;return function(){if(!t||!t.requirejs){t?n=t:t={};var e,n,r;!function(t){function i(e,t){return w.call(e,t)}function o(e,t){var n,r,i,o,s,a,l,c,u,d,p,h,f=t&&t.split("/"),g=_.map,m=g&&g["*"]||{};if(e){for(e=e.split("/"),s=e.length-1,_.nodeIdCompat&&A.test(e[s])&&(e[s]=e[s].replace(A,"")),"."===e[0].charAt(0)&&f&&(h=f.slice(0,f.length-1),e=h.concat(e)),u=0;u0&&(e.splice(u-1,2),u-=2)}e=e.join("/")}if((f||m)&&g){for(n=e.split("/"),u=n.length;u>0;u-=1){if(r=n.slice(0,u).join("/"),f)for(d=f.length;d>0;d-=1)if(i=g[f.slice(0,d).join("/")],i&&(i=i[r])){o=i,a=u;break}if(o)break;!l&&m&&m[r]&&(l=m[r],c=u)}!o&&l&&(o=l,a=c),o&&(n.splice(0,a,o),e=n.join("/"))}return e}function s(e,n){return function(){var r=b.call(arguments,0);return"string"!=typeof r[0]&&1===r.length&&r.push(null),f.apply(t,r.concat([e,n]))}}function a(e){return function(t){return o(t,e)}}function l(e){return function(t){v[e]=t}}function c(e){if(i(y,e)){var n=y[e];delete y[e],$[e]=!0,h.apply(t,n)}if(!i(v,e)&&!i($,e))throw new Error("No "+e);return v[e]}function u(e){var t,n=e?e.indexOf("!"):-1;return n>-1&&(t=e.substring(0,n),e=e.substring(n+1,e.length)),[t,e]}function d(e){return e?u(e):[]}function p(e){return function(){return _&&_.config&&_.config[e]||{}}}var h,f,g,m,v={},y={},_={},$={},w=Object.prototype.hasOwnProperty,b=[].slice,A=/\.js$/;g=function(e,t){var n,r=u(e),i=r[0],s=t[1];return e=r[1],i&&(i=o(i,s),n=c(i)),i?e=n&&n.normalize?n.normalize(e,a(s)):o(e,s):(e=o(e,s),r=u(e),i=r[0],e=r[1],i&&(n=c(i))),{f:i?i+"!"+e:e,n:e,pr:i,p:n}},m={require:function(e){return s(e)},exports:function(e){var t=v[e];return"undefined"!=typeof t?t:v[e]={}},module:function(e){return{id:e,uri:"",exports:v[e],config:p(e)}}},h=function(e,n,r,o){var a,u,p,h,f,_,w,b=[],A=typeof r;if(o=o||e,_=d(o),"undefined"===A||"function"===A){for(n=!n.length&&r.length?["require","exports","module"]:n,f=0;f0&&(t.call(arguments,e.prototype.constructor),i=n.prototype.constructor),i.apply(this,arguments)}function i(){this.constructor=r}var o=t(n),s=t(e);n.displayName=e.displayName,r.prototype=new i;for(var a=0;an;n++)e[n].apply(this,t)},n.Observable=r,n.generateChars=function(e){for(var t="",n=0;e>n;n++){var r=Math.floor(36*Math.random());t+=r.toString(36)}return t},n.bind=function(e,t){return function(){e.apply(t,arguments)}},n._convertData=function(e){for(var t in e){var n=t.split("-"),r=e;if(1!==n.length){for(var i=0;i":">",'"':""","'":"'","/":"/"};return"string"!=typeof e?e:String(e).replace(/[&<>"'\/\\]/g,function(e){return t[e]})},n.appendMany=function(t,n){if("1.7"===e.fn.jquery.substr(0,3)){var r=e();e.map(n,function(e){r=r.add(e)}),n=r}t.append(n)},n.__cache={};var i=0;return n.GetUniqueElementId=function(e){var t=e.getAttribute("data-select2-id");return null==t&&(e.id?(t=e.id,e.setAttribute("data-select2-id",t)):(e.setAttribute("data-select2-id",++i),t=i.toString())),t},n.StoreData=function(e,t,r){var i=n.GetUniqueElementId(e);n.__cache[i]||(n.__cache[i]={}),n.__cache[i][t]=r},n.GetData=function(t,r){var i=n.GetUniqueElementId(t);return r?n.__cache[i]&&null!=n.__cache[i][r]?n.__cache[i][r]:e(t).data(r):n.__cache[i]},n.RemoveData=function(e){var t=n.GetUniqueElementId(e);null!=n.__cache[t]&&delete n.__cache[t]},n}),t.define("select2/results",["jquery","./utils"],function(e,t){function n(e,t,r){this.$element=e,this.data=r,this.options=t,n.__super__.constructor.call(this)}return t.Extend(n,t.Observable),n.prototype.render=function(){var t=e('
          ');return this.options.get("multiple")&&t.attr("aria-multiselectable","true"),this.$results=t,t},n.prototype.clear=function(){this.$results.empty()},n.prototype.displayMessage=function(t){var n=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var r=e('
        • '),i=this.options.get("translations").get(t.message);r.append(n(i(t.args))),r[0].className+=" select2-results__message",this.$results.append(r)},n.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},n.prototype.append=function(e){this.hideLoading();var t=[];if(null==e.results||0===e.results.length)return void(0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"}));e.results=this.sort(e.results);for(var n=0;n0?t.first().trigger("mouseenter"):e.first().trigger("mouseenter"),this.ensureHighlightVisible()},n.prototype.setClasses=function(){var n=this;this.data.current(function(r){var i=e.map(r,function(e){return e.id.toString()}),o=n.$results.find(".select2-results__option[aria-selected]");o.each(function(){var n=e(this),r=t.GetData(this,"data"),o=""+r.id;null!=r.element&&r.element.selected||null==r.element&&e.inArray(o,i)>-1?n.attr("aria-selected","true"):n.attr("aria-selected","false")})})},n.prototype.showLoading=function(e){this.hideLoading();var t=this.options.get("translations").get("searching"),n={disabled:!0,loading:!0,text:t(e)},r=this.option(n);r.className+=" loading-results",this.$results.prepend(r)},n.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},n.prototype.option=function(n){var r=document.createElement("li");r.className="select2-results__option";var i={role:"treeitem","aria-selected":"false"};n.disabled&&(delete i["aria-selected"],i["aria-disabled"]="true"),null==n.id&&delete i["aria-selected"],null!=n._resultId&&(r.id=n._resultId),n.title&&(r.title=n.title),n.children&&(i.role="group",i["aria-label"]=n.text,delete i["aria-selected"]);for(var o in i){var s=i[o];r.setAttribute(o,s)}if(n.children){var a=e(r),l=document.createElement("strong");l.className="select2-results__group";e(l);this.template(n,l);for(var c=[],u=0;u
        ",{"class":"select2-results__options select2-results__options--nested"});h.append(c),a.append(l),a.append(h)}else this.template(n,r);return t.StoreData(r,"data",n),r},n.prototype.bind=function(n){var r=this,i=n.id+"-results";this.$results.attr("id",i),n.on("results:all",function(e){r.clear(),r.append(e.data),n.isOpen()&&(r.setClasses(),r.highlightFirstItem())}),n.on("results:append",function(e){r.append(e.data),n.isOpen()&&r.setClasses()}),n.on("query",function(e){r.hideMessages(),r.showLoading(e)}),n.on("select",function(){n.isOpen()&&(r.setClasses(),r.highlightFirstItem())}),n.on("unselect",function(){n.isOpen()&&(r.setClasses(),r.highlightFirstItem())}),n.on("open",function(){r.$results.attr("aria-expanded","true"),r.$results.attr("aria-hidden","false"),r.setClasses(),r.ensureHighlightVisible()}),n.on("close",function(){r.$results.attr("aria-expanded","false"),r.$results.attr("aria-hidden","true"),r.$results.removeAttr("aria-activedescendant")}),n.on("results:toggle",function(){var e=r.getHighlightedResults();0!==e.length&&e.trigger("mouseup")}),n.on("results:select",function(){var e=r.getHighlightedResults();if(0!==e.length){var n=t.GetData(e[0],"data");"true"==e.attr("aria-selected")?r.trigger("close",{}):r.trigger("select",{data:n})}}),n.on("results:previous",function(){var e=r.getHighlightedResults(),t=r.$results.find("[aria-selected]"),n=t.index(e);if(!(0>=n)){var i=n-1;0===e.length&&(i=0);var o=t.eq(i);o.trigger("mouseenter");var s=r.$results.offset().top,a=o.offset().top,l=r.$results.scrollTop()+(a-s);0===i?r.$results.scrollTop(0):0>a-s&&r.$results.scrollTop(l)}}),n.on("results:next",function(){var e=r.getHighlightedResults(),t=r.$results.find("[aria-selected]"),n=t.index(e),i=n+1;if(!(i>=t.length)){var o=t.eq(i);o.trigger("mouseenter");var s=r.$results.offset().top+r.$results.outerHeight(!1),a=o.offset().top+o.outerHeight(!1),l=r.$results.scrollTop()+a-s;0===i?r.$results.scrollTop(0):a>s&&r.$results.scrollTop(l)}}),n.on("results:focus",function(e){e.element.addClass("select2-results__option--highlighted")}),n.on("results:message",function(e){r.displayMessage(e)}),e.fn.mousewheel&&this.$results.on("mousewheel",function(e){var t=r.$results.scrollTop(),n=r.$results.get(0).scrollHeight-t+e.deltaY,i=e.deltaY>0&&t-e.deltaY<=0,o=e.deltaY<0&&n<=r.$results.height();i?(r.$results.scrollTop(0),e.preventDefault(),e.stopPropagation()):o&&(r.$results.scrollTop(r.$results.get(0).scrollHeight-r.$results.height()),e.preventDefault(),e.stopPropagation())}),this.$results.on("mouseup",".select2-results__option[aria-selected]",function(n){var i=e(this),o=t.GetData(this,"data");return"true"===i.attr("aria-selected")?void(r.options.get("multiple")?r.trigger("unselect",{originalEvent:n,data:o}):r.trigger("close",{})):void r.trigger("select",{originalEvent:n,data:o})}),this.$results.on("mouseenter",".select2-results__option[aria-selected]",function(){var n=t.GetData(this,"data");r.getHighlightedResults().removeClass("select2-results__option--highlighted"),r.trigger("results:focus",{data:n,element:e(this)})})},n.prototype.getHighlightedResults=function(){var e=this.$results.find(".select2-results__option--highlighted");return e},n.prototype.destroy=function(){this.$results.remove()},n.prototype.ensureHighlightVisible=function(){var e=this.getHighlightedResults();if(0!==e.length){var t=this.$results.find("[aria-selected]"),n=t.index(e),r=this.$results.offset().top,i=e.offset().top,o=this.$results.scrollTop()+(i-r),s=i-r;o-=2*e.outerHeight(!1),2>=n?this.$results.scrollTop(0):(s>this.$results.outerHeight()||0>s)&&this.$results.scrollTop(o)}},n.prototype.template=function(t,n){var r=this.options.get("templateResult"),i=this.options.get("escapeMarkup"),o=r(t,n);null==o?n.style.display="none":"string"==typeof o?n.innerHTML=i(o):e(n).append(o)},n}),t.define("select2/keys",[],function(){var e={BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46};return e}),t.define("select2/selection/base",["jquery","../utils","../keys"],function(e,t,n){function r(e,t){this.$element=e,this.options=t,r.__super__.constructor.call(this)}return t.Extend(r,t.Observable),r.prototype.render=function(){var n=e('');return this._tabindex=0,null!=t.GetData(this.$element[0],"old-tabindex")?this._tabindex=t.GetData(this.$element[0],"old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),n.attr("title",this.$element.attr("title")),n.attr("tabindex",this._tabindex),this.$selection=n,n},r.prototype.bind=function(e){var t=this,r=(e.id+"-container",e.id+"-results");this.container=e,this.$selection.on("focus",function(e){t.trigger("focus",e)}),this.$selection.on("blur",function(e){t._handleBlur(e)}),this.$selection.on("keydown",function(e){t.trigger("keypress",e),e.which===n.SPACE&&e.preventDefault()}),e.on("results:focus",function(e){t.$selection.attr("aria-activedescendant",e.data._resultId)}),e.on("selection:update",function(e){t.update(e.data)}),e.on("open",function(){t.$selection.attr("aria-expanded","true"),t.$selection.attr("aria-owns",r),t._attachCloseHandler(e)}),e.on("close",function(){t.$selection.attr("aria-expanded","false"),t.$selection.removeAttr("aria-activedescendant"),t.$selection.removeAttr("aria-owns"),t.$selection.focus(),window.setTimeout(function(){t.$selection.focus()},0),t._detachCloseHandler(e)}),e.on("enable",function(){t.$selection.attr("tabindex",t._tabindex)}),e.on("disable",function(){t.$selection.attr("tabindex","-1")})},r.prototype._handleBlur=function(t){var n=this;window.setTimeout(function(){document.activeElement==n.$selection[0]||e.contains(n.$selection[0],document.activeElement)||n.trigger("blur",t)},1)},r.prototype._attachCloseHandler=function(n){e(document.body).on("mousedown.select2."+n.id,function(n){var r=e(n.target),i=r.closest(".select2"),o=e(".select2.select2-container--open");o.each(function(){e(this);if(this!=i[0]){var n=t.GetData(this,"element");n.select2("close")}})})},r.prototype._detachCloseHandler=function(t){e(document.body).off("mousedown.select2."+t.id)},r.prototype.position=function(e,t){var n=t.find(".selection");n.append(e)},r.prototype.destroy=function(){this._detachCloseHandler(this.container)},r.prototype.update=function(){throw new Error("The `update` method must be defined in child classes.")},r}),t.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(e,t,n){function r(){r.__super__.constructor.apply(this,arguments)}return n.Extend(r,t),r.prototype.render=function(){var e=r.__super__.render.call(this);return e.addClass("select2-selection--single"),e.html(''),e},r.prototype.bind=function(e){var t=this;r.__super__.bind.apply(this,arguments);var n=e.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",n).attr("role","textbox").attr("aria-readonly","true"),this.$selection.attr("aria-labelledby",n),this.$selection.on("mousedown",function(e){1===e.which&&t.trigger("toggle",{originalEvent:e})}),this.$selection.on("focus",function(){}),this.$selection.on("blur",function(){}),e.on("focus",function(){e.isOpen()||t.$selection.focus()})},r.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},r.prototype.display=function(e,t){var n=this.options.get("templateSelection"),r=this.options.get("escapeMarkup");return r(n(e,t))},r.prototype.selectionContainer=function(){return e("")},r.prototype.update=function(e){if(0===e.length)return void this.clear();var t=e[0],n=this.$selection.find(".select2-selection__rendered"),r=this.display(t,n);n.empty().append(r),n.attr("title",t.title||t.text)},r}),t.define("select2/selection/multiple",["jquery","./base","../utils"],function(e,t,n){function r(){r.__super__.constructor.apply(this,arguments)}return n.Extend(r,t),r.prototype.render=function(){var e=r.__super__.render.call(this);return e.addClass("select2-selection--multiple"),e.html('
          '),e},r.prototype.bind=function(){var t=this;r.__super__.bind.apply(this,arguments),this.$selection.on("click",function(e){t.trigger("toggle",{originalEvent:e})}),this.$selection.on("click",".select2-selection__choice__remove",function(r){if(!t.options.get("disabled")){var i=e(this),o=i.parent(),s=n.GetData(o[0],"data");t.trigger("unselect",{originalEvent:r,data:s})}})},r.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},r.prototype.display=function(e,t){var n=this.options.get("templateSelection"),r=this.options.get("escapeMarkup");return r(n(e,t))},r.prototype.selectionContainer=function(){var t=e('
        • ×
        • ');return t},r.prototype.update=function(e){if(this.clear(),0!==e.length){for(var t=[],r=0;r1;if(r||n)return e.call(this,t);this.clear();var i=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(i)},e}),t.define("select2/selection/allowClear",["jquery","../keys","../utils"],function(e,t,n){function r(){}return r.prototype.bind=function(e,t,n){var r=this;e.call(this,t,n),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",function(e){r._handleClear(e)}),t.on("keypress",function(e){r._handleKeyboardClear(e,t)})},r.prototype._handleClear=function(e,t){if(!this.options.get("disabled")){var r=this.$selection.find(".select2-selection__clear");if(0!==r.length){t.stopPropagation();var i=n.GetData(r[0],"data"),o=this.$element.val();this.$element.val(this.placeholder.id);var s={data:i};if(this.trigger("clear",s),s.prevented)return void this.$element.val(o);for(var a=0;a0||0===r.length)){var i=e('×');n.StoreData(i[0],"data",r),this.$selection.find(".select2-selection__rendered").prepend(i)}},r}),t.define("select2/selection/search",["jquery","../utils","../keys"],function(e,t,n){function r(e,t,n){e.call(this,t,n)}return r.prototype.render=function(t){var n=e('');this.$searchContainer=n,this.$search=n.find("input");var r=t.call(this);return this._transferTabIndex(),r},r.prototype.bind=function(e,r,i){var o=this;e.call(this,r,i),r.on("open",function(){o.$search.trigger("focus")}),r.on("close",function(){o.$search.val(""),o.$search.removeAttr("aria-activedescendant"),o.$search.trigger("focus")}),r.on("enable",function(){o.$search.prop("disabled",!1),o._transferTabIndex()}),r.on("disable",function(){o.$search.prop("disabled",!0)}),r.on("focus",function(){o.$search.trigger("focus")}),r.on("results:focus",function(e){o.$search.attr("aria-activedescendant",e.id)}),this.$selection.on("focusin",".select2-search--inline",function(e){o.trigger("focus",e)}),this.$selection.on("focusout",".select2-search--inline",function(e){o._handleBlur(e)}),this.$selection.on("keydown",".select2-search--inline",function(e){e.stopPropagation(),o.trigger("keypress",e),o._keyUpPrevented=e.isDefaultPrevented();var r=e.which;if(r===n.BACKSPACE&&""===o.$search.val()){var i=o.$searchContainer.prev(".select2-selection__choice");if(i.length>0){var s=t.GetData(i[0],"data");o.searchRemoveChoice(s),e.preventDefault()}}});var s=document.documentMode,a=s&&11>=s;this.$selection.on("input.searchcheck",".select2-search--inline",function(){return a?void o.$selection.off("input.search input.searchcheck"):void o.$selection.off("keyup.search")}),this.$selection.on("keyup.search input.search",".select2-search--inline",function(e){if(a&&"input"===e.type)return void o.$selection.off("input.search input.searchcheck");var t=e.which;t!=n.SHIFT&&t!=n.CTRL&&t!=n.ALT&&t!=n.TAB&&o.handleSearch(e)})},r.prototype._transferTabIndex=function(){this.$search.attr("tabindex",this.$selection.attr("tabindex")),this.$selection.attr("tabindex","-1")},r.prototype.createPlaceholder=function(e,t){this.$search.attr("placeholder",t.text)},r.prototype.update=function(e,t){var n=this.$search[0]==document.activeElement;if(this.$search.attr("placeholder",""),e.call(this,t),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch(),n){var r=this.$element.find("[data-select2-tag]").length;r?this.$element.focus():this.$search.focus()}},r.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var e=this.$search.val();this.trigger("query",{term:e})}this._keyUpPrevented=!1},r.prototype.searchRemoveChoice=function(e,t){this.trigger("unselect",{data:t}),this.$search.val(t.text),this.handleSearch()},r.prototype.resizeSearch=function(){this.$search.css("width","25px");var e="";if(""!==this.$search.attr("placeholder"))e=this.$selection.find(".select2-selection__rendered").innerWidth();else{var t=this.$search.val().length+1;e=.75*t+"em"}this.$search.css("width",e)},r}),t.define("select2/selection/eventRelay",["jquery"],function(e){function t(){}return t.prototype.bind=function(t,n,r){var i=this,o=["open","opening","close","closing","select","selecting","unselect","unselecting","clear","clearing"],s=["opening","closing","selecting","unselecting","clearing"];t.call(this,n,r),n.on("*",function(t,n){if(-1!==e.inArray(t,o)){n=n||{};var r=e.Event("select2:"+t,{params:n});i.$element.trigger(r),-1!==e.inArray(t,s)&&(n.prevented=r.isDefaultPrevented())}})},t}),t.define("select2/translation",["jquery","require"],function(e,t){function n(e){this.dict=e||{}}return n.prototype.all=function(){return this.dict},n.prototype.get=function(e){return this.dict[e]},n.prototype.extend=function(t){this.dict=e.extend({},t.all(),this.dict)},n._cache={},n.loadPath=function(e){if(!(e in n._cache)){var r=t(e);n._cache[e]=r}return new n(n._cache[e])},n}),t.define("select2/diacritics",[],function(){var e={"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ", 2 | "Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"};return e}),t.define("select2/data/base",["../utils"],function(e){function t(){t.__super__.constructor.call(this)}return e.Extend(t,e.Observable),t.prototype.current=function(){throw new Error("The `current` method must be defined in child classes.")},t.prototype.query=function(){throw new Error("The `query` method must be defined in child classes.")},t.prototype.bind=function(){},t.prototype.destroy=function(){},t.prototype.generateResultId=function(t,n){var r=t.id+"-result-";return r+=e.generateChars(4),r+=null!=n.id?"-"+n.id.toString():"-"+e.generateChars(4)},t}),t.define("select2/data/select",["./base","../utils","jquery"],function(e,t,n){function r(e,t){this.$element=e,this.options=t,r.__super__.constructor.call(this)}return t.Extend(r,e),r.prototype.current=function(e){var t=[],r=this;this.$element.find(":selected").each(function(){var e=n(this),i=r.item(e);t.push(i)}),e(t)},r.prototype.select=function(e){var t=this;if(e.selected=!0,n(e.element).is("option"))return e.element.selected=!0,void this.$element.trigger("change");if(this.$element.prop("multiple"))this.current(function(r){var i=[];e=[e],e.push.apply(e,r);for(var o=0;o=0){var u=o.filter(r(c)),d=this.item(u),p=n.extend(!0,{},c,d),h=this.option(p);u.replaceWith(h)}else{var f=this.option(c);if(c.children){var g=this.convertToOptions(c.children);t.appendMany(f,g)}a.push(f)}}return a},r}),t.define("select2/data/ajax",["./array","../utils","jquery"],function(e,t,n){function r(e,t){this.ajaxOptions=this._applyDefaults(t.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),r.__super__.constructor.call(this,e,t)}return t.Extend(r,e),r.prototype._applyDefaults=function(e){var t={data:function(e){return n.extend({},e,{q:e.term})},transport:function(e,t,r){var i=n.ajax(e);return i.then(t),i.fail(r),i}};return n.extend({},t,e,!0)},r.prototype.processResults=function(e){return e},r.prototype.query=function(e,t){function r(){var r=o.transport(o,function(r){var o=i.processResults(r,e);i.options.get("debug")&&window.console&&console.error&&(o&&o.results&&n.isArray(o.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),t(o)},function(){"status"in r&&(0===r.status||"0"===r.status)||i.trigger("results:message",{message:"errorLoading"})});i._request=r}var i=this;null!=this._request&&(n.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var o=n.extend({type:"GET"},this.ajaxOptions);"function"==typeof o.url&&(o.url=o.url.call(this.$element,e)),"function"==typeof o.data&&(o.data=o.data.call(this.$element,e)),this.ajaxOptions.delay&&null!=e.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(r,this.ajaxOptions.delay)):r()},r}),t.define("select2/data/tags",["jquery"],function(e){function t(t,n,r){var i=r.get("tags"),o=r.get("createTag");void 0!==o&&(this.createTag=o);var s=r.get("insertTag");if(void 0!==s&&(this.insertTag=s),t.call(this,n,r),e.isArray(i))for(var a=0;a0&&t.term.length>this.maximumInputLength?void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:t.term,params:t}}):void e.call(this,t,n)},e}),t.define("select2/data/maximumSelectionLength",[],function(){function e(e,t,n){this.maximumSelectionLength=n.get("maximumSelectionLength"),e.call(this,t,n)}return e.prototype.query=function(e,t,n){var r=this;this.current(function(i){var o=null!=i?i.length:0;return r.maximumSelectionLength>0&&o>=r.maximumSelectionLength?void r.trigger("results:message",{message:"maximumSelected",args:{maximum:r.maximumSelectionLength}}):void e.call(r,t,n)})},e}),t.define("select2/dropdown",["jquery","./utils"],function(e,t){function n(e,t){this.$element=e,this.options=t,n.__super__.constructor.call(this)}return t.Extend(n,t.Observable),n.prototype.render=function(){var t=e('');return t.attr("dir",this.options.get("dir")),this.$dropdown=t,t},n.prototype.bind=function(){},n.prototype.position=function(){},n.prototype.destroy=function(){this.$dropdown.remove()},n}),t.define("select2/dropdown/search",["jquery","../utils"],function(e){function t(){}return t.prototype.render=function(t){var n=t.call(this),r=e('');return this.$searchContainer=r,this.$search=r.find("input"),n.prepend(r),n},t.prototype.bind=function(t,n,r){var i=this;t.call(this,n,r),this.$search.on("keydown",function(e){i.trigger("keypress",e),i._keyUpPrevented=e.isDefaultPrevented()}),this.$search.on("input",function(){e(this).off("keyup")}),this.$search.on("keyup input",function(e){i.handleSearch(e)}),n.on("open",function(){i.$search.attr("tabindex",0),i.$search.focus(),window.setTimeout(function(){i.$search.focus()},0)}),n.on("close",function(){i.$search.attr("tabindex",-1),i.$search.val(""),i.$search.blur()}),n.on("focus",function(){n.isOpen()||i.$search.focus()}),n.on("results:all",function(e){if(null==e.query.term||""===e.query.term){var t=i.showSearch(e);t?i.$searchContainer.removeClass("select2-search--hide"):i.$searchContainer.addClass("select2-search--hide")}})},t.prototype.handleSearch=function(){if(!this._keyUpPrevented){var e=this.$search.val();this.trigger("query",{term:e})}this._keyUpPrevented=!1},t.prototype.showSearch=function(){return!0},t}),t.define("select2/dropdown/hidePlaceholder",[],function(){function e(e,t,n,r){this.placeholder=this.normalizePlaceholder(n.get("placeholder")),e.call(this,t,n,r)}return e.prototype.append=function(e,t){t.results=this.removePlaceholder(t.results),e.call(this,t)},e.prototype.normalizePlaceholder=function(e,t){return"string"==typeof t&&(t={id:"",text:t}),t},e.prototype.removePlaceholder=function(e,t){for(var n=t.slice(0),r=t.length-1;r>=0;r--){var i=t[r];this.placeholder.id===i.id&&n.splice(r,1)}return n},e}),t.define("select2/dropdown/infiniteScroll",["jquery"],function(e){function t(e,t,n,r){this.lastParams={},e.call(this,t,n,r),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return t.prototype.append=function(e,t){this.$loadingMore.remove(),this.loading=!1,e.call(this,t),this.showLoadingMore(t)&&this.$results.append(this.$loadingMore)},t.prototype.bind=function(t,n,r){var i=this;t.call(this,n,r),n.on("query",function(e){i.lastParams=e,i.loading=!0}),n.on("query:append",function(e){i.lastParams=e,i.loading=!0}),this.$results.on("scroll",function(){var t=e.contains(document.documentElement,i.$loadingMore[0]);if(!i.loading&&t){var n=i.$results.offset().top+i.$results.outerHeight(!1),r=i.$loadingMore.offset().top+i.$loadingMore.outerHeight(!1);n+50>=r&&i.loadMore()}})},t.prototype.loadMore=function(){this.loading=!0;var t=e.extend({},{page:1},this.lastParams);t.page++,this.trigger("query:append",t)},t.prototype.showLoadingMore=function(e,t){return t.pagination&&t.pagination.more},t.prototype.createLoadingMore=function(){var t=e('
        • '),n=this.options.get("translations").get("loadingMore");return t.html(n(this.lastParams)),t},t}),t.define("select2/dropdown/attachBody",["jquery","../utils"],function(e,t){function n(t,n,r){this.$dropdownParent=r.get("dropdownParent")||e(document.body),t.call(this,n,r)}return n.prototype.bind=function(e,t,n){var r=this,i=!1;e.call(this,t,n),t.on("open",function(){r._showDropdown(),r._attachPositioningHandler(t),i||(i=!0,t.on("results:all",function(){r._positionDropdown(),r._resizeDropdown()}),t.on("results:append",function(){r._positionDropdown(),r._resizeDropdown()}))}),t.on("close",function(){r._hideDropdown(),r._detachPositioningHandler(t)}),this.$dropdownContainer.on("mousedown",function(e){e.stopPropagation()})},n.prototype.destroy=function(e){e.call(this),this.$dropdownContainer.remove()},n.prototype.position=function(e,t,n){t.attr("class",n.attr("class")),t.removeClass("select2"),t.addClass("select2-container--open"),t.css({position:"absolute",top:-999999}),this.$container=n},n.prototype.render=function(t){var n=e(""),r=t.call(this);return n.append(r),this.$dropdownContainer=n,n},n.prototype._hideDropdown=function(){this.$dropdownContainer.detach()},n.prototype._attachPositioningHandler=function(n,r){var i=this,o="scroll.select2."+r.id,s="resize.select2."+r.id,a="orientationchange.select2."+r.id,l=this.$container.parents().filter(t.hasScroll);l.each(function(){t.StoreData(this,"select2-scroll-position",{x:e(this).scrollLeft(),y:e(this).scrollTop()})}),l.on(o,function(){var n=t.GetData(this,"select2-scroll-position");e(this).scrollTop(n.y)}),e(window).on(o+" "+s+" "+a,function(){i._positionDropdown(),i._resizeDropdown()})},n.prototype._detachPositioningHandler=function(n,r){var i="scroll.select2."+r.id,o="resize.select2."+r.id,s="orientationchange.select2."+r.id,a=this.$container.parents().filter(t.hasScroll);a.off(i),e(window).off(i+" "+o+" "+s)},n.prototype._positionDropdown=function(){var t=e(window),n=this.$dropdown.hasClass("select2-dropdown--above"),r=this.$dropdown.hasClass("select2-dropdown--below"),i=null,o=this.$container.offset();o.bottom=o.top+this.$container.outerHeight(!1);var s={height:this.$container.outerHeight(!1)};s.top=o.top,s.bottom=o.top+s.height;var a={height:this.$dropdown.outerHeight(!1)},l={top:t.scrollTop(),bottom:t.scrollTop()+t.height()},c=l.topo.bottom+a.height,d={left:o.left,top:s.bottom},p=this.$dropdownParent;"static"===p.css("position")&&(p=p.offsetParent());var h=p.offset();d.top-=h.top,d.left-=h.left,n||r||(i="below"),u||!c||n?!c&&u&&n&&(i="below"):i="above",("above"==i||n&&"below"!==i)&&(d.top=s.top-h.top-a.height),null!=i&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+i),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+i)),this.$dropdownContainer.css(d)},n.prototype._resizeDropdown=function(){var e={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(e.minWidth=e.width,e.position="relative",e.width="auto"),this.$dropdown.css(e)},n.prototype._showDropdown=function(){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},n}),t.define("select2/dropdown/minimumResultsForSearch",[],function(){function e(t){for(var n=0,r=0;r0&&(d.dataAdapter=c.Decorate(d.dataAdapter,v)),d.maximumInputLength>0&&(d.dataAdapter=c.Decorate(d.dataAdapter,y)),d.maximumSelectionLength>0&&(d.dataAdapter=c.Decorate(d.dataAdapter,_)),d.tags&&(d.dataAdapter=c.Decorate(d.dataAdapter,g)),null==d.tokenSeparators&&null==d.tokenizer||(d.dataAdapter=c.Decorate(d.dataAdapter,m)),null!=d.query){var C=t(d.amdBase+"compat/query");d.dataAdapter=c.Decorate(d.dataAdapter,C)}if(null!=d.initSelection){var O=t(d.amdBase+"compat/initSelection");d.dataAdapter=c.Decorate(d.dataAdapter,O)}}if(null==d.resultsAdapter&&(d.resultsAdapter=n,null!=d.ajax&&(d.resultsAdapter=c.Decorate(d.resultsAdapter,A)),null!=d.placeholder&&(d.resultsAdapter=c.Decorate(d.resultsAdapter,b)),d.selectOnClose&&(d.resultsAdapter=c.Decorate(d.resultsAdapter,S))),null==d.dropdownAdapter){if(d.multiple)d.dropdownAdapter=$;else{var T=c.Decorate($,w);d.dropdownAdapter=T}if(0!==d.minimumResultsForSearch&&(d.dropdownAdapter=c.Decorate(d.dropdownAdapter,D)),d.closeOnSelect&&(d.dropdownAdapter=c.Decorate(d.dropdownAdapter,E)),null!=d.dropdownCssClass||null!=d.dropdownCss||null!=d.adaptDropdownCssClass){var q=t(d.amdBase+"compat/dropdownCss");d.dropdownAdapter=c.Decorate(d.dropdownAdapter,q)}d.dropdownAdapter=c.Decorate(d.dropdownAdapter,x)}if(null==d.selectionAdapter){if(d.multiple?d.selectionAdapter=i:d.selectionAdapter=r,null!=d.placeholder&&(d.selectionAdapter=c.Decorate(d.selectionAdapter,o)),d.allowClear&&(d.selectionAdapter=c.Decorate(d.selectionAdapter,s)),d.multiple&&(d.selectionAdapter=c.Decorate(d.selectionAdapter,a)),null!=d.containerCssClass||null!=d.containerCss||null!=d.adaptContainerCssClass){var L=t(d.amdBase+"compat/containerCss");d.selectionAdapter=c.Decorate(d.selectionAdapter,L)}d.selectionAdapter=c.Decorate(d.selectionAdapter,l)}if("string"==typeof d.language)if(d.language.indexOf("-")>0){var j=d.language.split("-"),P=j[0];d.language=[d.language,P]}else d.language=[d.language];if(e.isArray(d.language)){var I=new u;d.language.push("en");for(var k=d.language,R=0;R0){for(var o=e.extend(!0,{},i),s=i.children.length-1;s>=0;s--){var a=i.children[s],l=n(r,a);null==l&&o.children.splice(s,1)}return o.children.length>0?o:n(r,o)}var c=t(i.text).toUpperCase(),u=t(r.term).toUpperCase();return c.indexOf(u)>-1?i:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:c.escapeMarkup,language:C,matcher:n,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(e){return e},templateResult:function(e){return e.text},templateSelection:function(e){return e.text},theme:"default",width:"resolve"}},O.prototype.set=function(t,n){var r=e.camelCase(t),i={};i[r]=n;var o=c._convertData(i);e.extend(!0,this.defaults,o)};var T=new O;return T}),t.define("select2/options",["require","jquery","./defaults","./utils"],function(e,t,n,r){function i(t,i){if(this.options=t,null!=i&&this.fromElement(i),this.options=n.apply(this.options),i&&i.is("input")){var o=e(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=r.Decorate(this.options.dataAdapter,o)}}return i.prototype.fromElement=function(e){var n=["select2"];null==this.options.multiple&&(this.options.multiple=e.prop("multiple")),null==this.options.disabled&&(this.options.disabled=e.prop("disabled")),null==this.options.language&&(e.prop("lang")?this.options.language=e.prop("lang").toLowerCase():e.closest("[lang]").prop("lang")&&(this.options.language=e.closest("[lang]").prop("lang"))),null==this.options.dir&&(e.prop("dir")?this.options.dir=e.prop("dir"):e.closest("[dir]").prop("dir")?this.options.dir=e.closest("[dir]").prop("dir"):this.options.dir="ltr"),e.prop("disabled",this.options.disabled),e.prop("multiple",this.options.multiple),r.GetData(e[0],"select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),r.StoreData(e[0],"data",r.GetData(e[0],"select2Tags")),r.StoreData(e[0],"tags",!0)),r.GetData(e[0],"ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),e.attr("ajax--url",r.GetData(e[0],"ajaxUrl")),r.StoreData(e[0],"ajax-Url",r.GetData(e[0],"ajaxUrl")));var i={};i=t.fn.jquery&&"1."==t.fn.jquery.substr(0,2)&&e[0].dataset?t.extend(!0,{},e[0].dataset,r.GetData(e[0])):r.GetData(e[0]);var o=t.extend(!0,{},i);o=r._convertData(o);for(var s in o)t.inArray(s,n)>-1||(t.isPlainObject(this.options[s])?t.extend(this.options[s],o[s]):this.options[s]=o[s]);return this},i.prototype.get=function(e){return this.options[e]},i.prototype.set=function(e,t){this.options[e]=t},i}),t.define("select2/core",["jquery","./options","./utils","./keys"],function(e,t,n,r){var i=function(e,r){null!=n.GetData(e[0],"select2")&&n.GetData(e[0],"select2").destroy(),this.$element=e,this.id=this._generateId(e),r=r||{},this.options=new t(r,e),i.__super__.constructor.call(this);var o=e.attr("tabindex")||0;n.StoreData(e[0],"old-tabindex",o),e.attr("tabindex","-1");var s=this.options.get("dataAdapter");this.dataAdapter=new s(e,this.options);var a=this.render();this._placeContainer(a);var l=this.options.get("selectionAdapter");this.selection=new l(e,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,a);var c=this.options.get("dropdownAdapter");this.dropdown=new c(e,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,a);var u=this.options.get("resultsAdapter");this.results=new u(e,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var d=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(e){d.trigger("selection:update",{data:e})}),e.addClass("select2-hidden-accessible"),e.attr("aria-hidden","true"),this._syncAttributes(),n.StoreData(e[0],"select2",this),e.data("select2",this)};return n.Extend(i,n.Observable),i.prototype._generateId=function(e){var t="";return t=null!=e.attr("id")?e.attr("id"):null!=e.attr("name")?e.attr("name")+"-"+n.generateChars(2):n.generateChars(4),t=t.replace(/(:|\.|\[|\]|,)/g,""),t="select2-"+t},i.prototype._placeContainer=function(e){e.insertAfter(this.$element);var t=this._resolveWidth(this.$element,this.options.get("width"));null!=t&&e.css("width",t)},i.prototype._resolveWidth=function(e,t){var n=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==t){var r=this._resolveWidth(e,"style");return null!=r?r:this._resolveWidth(e,"element")}if("element"==t){var i=e.outerWidth(!1);return 0>=i?"auto":i+"px"}if("style"==t){var o=e.attr("style");if("string"!=typeof o)return null;for(var s=o.split(";"),a=0,l=s.length;l>a;a+=1){var c=s[a].replace(/\s/g,""),u=c.match(n);if(null!==u&&u.length>=1)return u[1]}return null}return t},i.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},i.prototype._registerDomEvents=function(){var t=this;this.$element.on("change.select2",function(){null!=t.dataAdapter&&t.dataAdapter.current(function(e){t.trigger("selection:update",{data:e})})}),this.$element.on("focus.select2",function(e){t.trigger("focus",e)}),this._syncA=n.bind(this._syncAttributes,this),this._syncS=n.bind(this._syncSubtree,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._syncA);var r=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=r?(this._observer=new r(function(n){e.each(n,t._syncA),e.each(n,t._syncS)}),this._observer.observe(this.$element[0],{attributes:!0,childList:!0,subtree:!1})):this.$element[0].addEventListener&&(this.$element[0].addEventListener("DOMAttrModified",t._syncA,!1),this.$element[0].addEventListener("DOMNodeInserted",t._syncS,!1),this.$element[0].addEventListener("DOMNodeRemoved",t._syncS,!1))},i.prototype._registerDataEvents=function(){var e=this;this.dataAdapter.on("*",function(t,n){e.trigger(t,n)})},i.prototype._registerSelectionEvents=function(){var t=this,n=["toggle","focus"];this.selection.on("toggle",function(){t.toggleDropdown()}),this.selection.on("focus",function(e){t.focus(e)}),this.selection.on("*",function(r,i){-1===e.inArray(r,n)&&t.trigger(r,i)})},i.prototype._registerDropdownEvents=function(){var e=this;this.dropdown.on("*",function(t,n){e.trigger(t,n)})},i.prototype._registerResultsEvents=function(){var e=this;this.results.on("*",function(t,n){e.trigger(t,n)})},i.prototype._registerEvents=function(){var e=this;this.on("open",function(){e.$container.addClass("select2-container--open")}),this.on("close",function(){e.$container.removeClass("select2-container--open")}),this.on("enable",function(){e.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){e.$container.addClass("select2-container--disabled")}),this.on("blur",function(){e.$container.removeClass("select2-container--focus")}),this.on("query",function(t){e.isOpen()||e.trigger("open",{}),this.dataAdapter.query(t,function(n){e.trigger("results:all",{data:n,query:t})})}),this.on("query:append",function(t){this.dataAdapter.query(t,function(n){e.trigger("results:append",{data:n,query:t})})}),this.on("keypress",function(t){var n=t.which;e.isOpen()?n===r.ESC||n===r.TAB||n===r.UP&&t.altKey?(e.close(),t.preventDefault()):n===r.ENTER?(e.trigger("results:select",{}),t.preventDefault()):n===r.SPACE&&t.ctrlKey?(e.trigger("results:toggle",{}),t.preventDefault()):n===r.UP?(e.trigger("results:previous",{}),t.preventDefault()):n===r.DOWN&&(e.trigger("results:next",{}),t.preventDefault()):(n===r.ENTER||n===r.SPACE||n===r.DOWN&&t.altKey)&&(e.open(),t.preventDefault())})},i.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable",{})):this.trigger("enable",{})},i.prototype._syncSubtree=function(e,t){var n=!1,r=this;if(!e||!e.target||"OPTION"===e.target.nodeName||"OPTGROUP"===e.target.nodeName){if(t)if(t.addedNodes&&t.addedNodes.length>0)for(var i=0;i0&&(n=!0);else n=!0;n&&this.dataAdapter.current(function(e){r.trigger("selection:update",{data:e})})}},i.prototype.trigger=function(e,t){var n=i.__super__.trigger,r={open:"opening",close:"closing",select:"selecting",unselect:"unselecting",clear:"clearing"};if(void 0===t&&(t={}),e in r){var o=r[e],s={prevented:!1,name:e,args:t};if(n.call(this,o,s),s.prevented)return void(t.prevented=!0)}n.call(this,e,t)},i.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},i.prototype.open=function(){this.isOpen()||this.trigger("query",{})},i.prototype.close=function(){this.isOpen()&&this.trigger("close",{})},i.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},i.prototype.hasFocus=function(){return this.$container.hasClass("select2-container--focus")},i.prototype.focus=function(){this.hasFocus()||(this.$container.addClass("select2-container--focus"),this.trigger("focus",{}))},i.prototype.enable=function(e){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),null!=e&&0!==e.length||(e=[!0]);var t=!e[0];this.$element.prop("disabled",t)},i.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.'); 3 | var e=[];return this.dataAdapter.current(function(t){e=t}),e},i.prototype.val=function(t){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==t||0===t.length)return this.$element.val();var n=t[0];e.isArray(n)&&(n=e.map(n,function(e){return e.toString()})),this.$element.val(n).trigger("change")},i.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._syncA),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&(this.$element[0].removeEventListener("DOMAttrModified",this._syncA,!1),this.$element[0].removeEventListener("DOMNodeInserted",this._syncS,!1),this.$element[0].removeEventListener("DOMNodeRemoved",this._syncS,!1)),this._syncA=null,this._syncS=null,this.$element.off(".select2"),this.$element.attr("tabindex",n.GetData(this.$element[0],"old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),n.RemoveData(this.$element[0]),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null},i.prototype.render=function(){var t=e('');return t.attr("dir",this.options.get("dir")),this.$container=t,this.$container.addClass("select2-container--"+this.options.get("theme")),n.StoreData(t[0],"element",this.$element),t},i}),t.define("jquery-mousewheel",["jquery"],function(e){return e}),t.define("jquery.select2",["jquery","jquery-mousewheel","./select2/core","./select2/defaults","./select2/utils"],function(e,t,n,r,i){if(null==e.fn.select2){var o=["open","close","destroy"];e.fn.select2=function(t){if(t=t||{},"object"==typeof t)return this.each(function(){var r=e.extend(!0,{},t);new n(e(this),r)}),this;if("string"==typeof t){var r,s=Array.prototype.slice.call(arguments,1);return this.each(function(){var e=i.GetData(this,"select2");null==e&&window.console&&console.error&&console.error("The select2('"+t+"') method was called on an element that is not using Select2."),r=e[t].apply(e,s)}),e.inArray(t,o)>-1?this:r}throw new Error("Invalid arguments for Select2: "+t)}}return null==e.fn.select2.defaults&&(e.fn.select2.defaults=r),n}),{define:t.define,require:t.require}}(),n=t.require("jquery.select2");return e.fn.select2.amd=t,n}); --------------------------------------------------------------------------------